isNumberLiteralBase checks if a substring (starting at stringStartOffset) in the given C-string is a valid JavaScript/TypeScript number literal (which supports the most common cases in many languages). It supports: - Decimal literal, including fractional parts and exponent. - Hexadecimal (0x or 0X), binary (0b or 0B), octal (0o or 0O) literals. - BigInt literal with trailing "n", but onl
| 273 | If no valid number literal is found at the offset, the function returns 0. |
| 274 | */ |
| 275 | inline size_t isNumberLiteralBase( const char* stringSearch, int stringStartOffset, |
| 276 | PatternMatcher::Range* matchList, size_t stringLength, |
| 277 | bool underscoreSeparatorSupported, bool supportsOctal, |
| 278 | bool supportsBinary, bool supportsBigInt ) { |
| 279 | if ( stringStartOffset < 0 || (size_t)stringStartOffset >= stringLength ) |
| 280 | return 0; |
| 281 | |
| 282 | int pos = stringStartOffset; |
| 283 | const int start = pos; // Keep original start index |
| 284 | |
| 285 | bool isSigned = false; |
| 286 | bool hasDecimalPoint = false; |
| 287 | bool hasExponent = false; |
| 288 | bool consumedSomethingAfterSign = |
| 289 | false; // Track if any part of number (digit, dot) is consumed after sign |
| 290 | |
| 291 | // 1. Check for optional leading sign (+ or -) |
| 292 | if ( stringSearch[pos] == '+' || stringSearch[pos] == '-' ) { |
| 293 | isSigned = true; |
| 294 | pos++; |
| 295 | if ( pos >= (int)stringLength ) |
| 296 | return 0; // Sign alone is invalid |
| 297 | } |
| 298 | |
| 299 | // Store the position after the potential sign |
| 300 | int afterSignPos = pos; |
| 301 | |
| 302 | // Cannot have underscore immediately after sign |
| 303 | if ( pos < (int)stringLength && stringSearch[pos] == '_' ) { |
| 304 | return 0; |
| 305 | } |
| 306 | |
| 307 | // 2. Handle different literal types based on the character AFTER the sign (if any) |
| 308 | if ( stringSearch[afterSignPos] == '0' ) { |
| 309 | // Potential 0, 0x, 0b, 0o, 0.123, 0e5, 0123 (decimal) |
| 310 | if ( isSigned && ( pos + 1 < (int)stringLength && |
| 311 | ( stringSearch[pos + 1] == 'x' || stringSearch[pos + 1] == 'X' || |
| 312 | stringSearch[pos + 1] == 'b' || stringSearch[pos + 1] == 'B' || |
| 313 | stringSearch[pos + 1] == 'o' || stringSearch[pos + 1] == 'O' ) ) ) { |
| 314 | // Signed non-decimal (e.g., +0x1) is invalid in JS/TS |
| 315 | return 0; |
| 316 | } |
| 317 | |
| 318 | pos++; // Consume '0' |
| 319 | consumedSomethingAfterSign = true; |
| 320 | |
| 321 | if ( pos < (int)stringLength ) { |
| 322 | char next = stringSearch[pos]; |
| 323 | int base = 0; // 0 indicates potential decimal or just '0' |
| 324 | |
| 325 | if ( next == 'x' || next == 'X' ) |
| 326 | base = 16; |
| 327 | else if ( next == 'b' || next == 'B' ) { |
| 328 | base = 2; |
| 329 | if ( !supportsBinary ) |
| 330 | return 0; |
| 331 | } else if ( next == 'o' || next == 'O' ) { |
| 332 | base = 8; |
no test coverage detected