1namespace ts { 2 export type ErrorCallback = (message: DiagnosticMessage, length: number) => void; 3 4 /* @internal */ 5 export function tokenIsIdentifierOrKeyword(token: SyntaxKind): boolean { 6 return token >= SyntaxKind.Identifier; 7 } 8 9 /* @internal */ 10 export function tokenIsIdentifierOrKeywordOrGreaterThan(token: SyntaxKind): boolean { 11 return token === SyntaxKind.GreaterThanToken || tokenIsIdentifierOrKeyword(token); 12 } 13 14 export interface Scanner { 15 getStartPos(): number; 16 getToken(): SyntaxKind; 17 getTextPos(): number; 18 getTokenPos(): number; 19 getTokenText(): string; 20 getTokenValue(): string; 21 hasUnicodeEscape(): boolean; 22 hasExtendedUnicodeEscape(): boolean; 23 hasPrecedingLineBreak(): boolean; 24 /* @internal */ 25 hasPrecedingJSDocComment(): boolean; 26 isIdentifier(): boolean; 27 isReservedWord(): boolean; 28 isUnterminated(): boolean; 29 /* @internal */ 30 getNumericLiteralFlags(): TokenFlags; 31 /* @internal */ 32 getCommentDirectives(): CommentDirective[] | undefined; 33 /* @internal */ 34 getTokenFlags(): TokenFlags; 35 reScanGreaterToken(): SyntaxKind; 36 reScanSlashToken(): SyntaxKind; 37 reScanAsteriskEqualsToken(): SyntaxKind; 38 reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind; 39 reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind; 40 scanJsxIdentifier(): SyntaxKind; 41 scanJsxAttributeValue(): SyntaxKind; 42 reScanJsxAttributeValue(): SyntaxKind; 43 reScanJsxToken(): JsxTokenSyntaxKind; 44 reScanLessThanToken(): SyntaxKind; 45 reScanQuestionToken(): SyntaxKind; 46 reScanInvalidIdentifier(): SyntaxKind; 47 scanJsxToken(): JsxTokenSyntaxKind; 48 scanJsDocToken(): JSDocSyntaxKind; 49 scan(): SyntaxKind; 50 51 getText(): string; 52 /* @internal */ 53 clearCommentDirectives(): void; 54 // Sets the text for the scanner to scan. An optional subrange starting point and length 55 // can be provided to have the scanner only scan a portion of the text. 56 setText(text: string | undefined, start?: number, length?: number): void; 57 setOnError(onError: ErrorCallback | undefined): void; 58 setScriptTarget(scriptTarget: ScriptTarget): void; 59 setLanguageVariant(variant: LanguageVariant): void; 60 setTextPos(textPos: number): void; 61 /* @internal */ 62 setInJSDocType(inType: boolean): void; 63 // Invokes the provided callback then unconditionally restores the scanner to the state it 64 // was in immediately prior to invoking the callback. The result of invoking the callback 65 // is returned from this function. 66 lookAhead<T>(callback: () => T): T; 67 68 // Invokes the callback with the scanner set to scan the specified range. When the callback 69 // returns, the scanner is restored to the state it was in before scanRange was called. 70 scanRange<T>(start: number, length: number, callback: () => T): T; 71 72 // Invokes the provided callback. If the callback returns something falsy, then it restores 73 // the scanner to the state it was in immediately prior to invoking the callback. If the 74 // callback returns something truthy, then the scanner state is not rolled back. The result 75 // of invoking the callback is returned from this function. 76 tryScan<T>(callback: () => T): T; 77 } 78 79 const textToKeywordObj: MapLike<KeywordSyntaxKind> = { 80 abstract: SyntaxKind.AbstractKeyword, 81 any: SyntaxKind.AnyKeyword, 82 as: SyntaxKind.AsKeyword, 83 asserts: SyntaxKind.AssertsKeyword, 84 bigint: SyntaxKind.BigIntKeyword, 85 boolean: SyntaxKind.BooleanKeyword, 86 break: SyntaxKind.BreakKeyword, 87 case: SyntaxKind.CaseKeyword, 88 catch: SyntaxKind.CatchKeyword, 89 class: SyntaxKind.ClassKeyword, 90 struct: SyntaxKind.StructKeyword, 91 continue: SyntaxKind.ContinueKeyword, 92 const: SyntaxKind.ConstKeyword, 93 ["" + "constructor"]: SyntaxKind.ConstructorKeyword, 94 debugger: SyntaxKind.DebuggerKeyword, 95 declare: SyntaxKind.DeclareKeyword, 96 default: SyntaxKind.DefaultKeyword, 97 delete: SyntaxKind.DeleteKeyword, 98 do: SyntaxKind.DoKeyword, 99 else: SyntaxKind.ElseKeyword, 100 enum: SyntaxKind.EnumKeyword, 101 export: SyntaxKind.ExportKeyword, 102 extends: SyntaxKind.ExtendsKeyword, 103 false: SyntaxKind.FalseKeyword, 104 finally: SyntaxKind.FinallyKeyword, 105 for: SyntaxKind.ForKeyword, 106 from: SyntaxKind.FromKeyword, 107 function: SyntaxKind.FunctionKeyword, 108 get: SyntaxKind.GetKeyword, 109 if: SyntaxKind.IfKeyword, 110 implements: SyntaxKind.ImplementsKeyword, 111 import: SyntaxKind.ImportKeyword, 112 in: SyntaxKind.InKeyword, 113 infer: SyntaxKind.InferKeyword, 114 instanceof: SyntaxKind.InstanceOfKeyword, 115 interface: SyntaxKind.InterfaceKeyword, 116 intrinsic: SyntaxKind.IntrinsicKeyword, 117 is: SyntaxKind.IsKeyword, 118 keyof: SyntaxKind.KeyOfKeyword, 119 let: SyntaxKind.LetKeyword, 120 module: SyntaxKind.ModuleKeyword, 121 namespace: SyntaxKind.NamespaceKeyword, 122 never: SyntaxKind.NeverKeyword, 123 new: SyntaxKind.NewKeyword, 124 null: SyntaxKind.NullKeyword, 125 number: SyntaxKind.NumberKeyword, 126 object: SyntaxKind.ObjectKeyword, 127 package: SyntaxKind.PackageKeyword, 128 private: SyntaxKind.PrivateKeyword, 129 protected: SyntaxKind.ProtectedKeyword, 130 public: SyntaxKind.PublicKeyword, 131 readonly: SyntaxKind.ReadonlyKeyword, 132 require: SyntaxKind.RequireKeyword, 133 global: SyntaxKind.GlobalKeyword, 134 return: SyntaxKind.ReturnKeyword, 135 set: SyntaxKind.SetKeyword, 136 static: SyntaxKind.StaticKeyword, 137 string: SyntaxKind.StringKeyword, 138 super: SyntaxKind.SuperKeyword, 139 switch: SyntaxKind.SwitchKeyword, 140 symbol: SyntaxKind.SymbolKeyword, 141 this: SyntaxKind.ThisKeyword, 142 throw: SyntaxKind.ThrowKeyword, 143 true: SyntaxKind.TrueKeyword, 144 try: SyntaxKind.TryKeyword, 145 type: SyntaxKind.TypeKeyword, 146 typeof: SyntaxKind.TypeOfKeyword, 147 undefined: SyntaxKind.UndefinedKeyword, 148 unique: SyntaxKind.UniqueKeyword, 149 unknown: SyntaxKind.UnknownKeyword, 150 var: SyntaxKind.VarKeyword, 151 void: SyntaxKind.VoidKeyword, 152 while: SyntaxKind.WhileKeyword, 153 with: SyntaxKind.WithKeyword, 154 yield: SyntaxKind.YieldKeyword, 155 async: SyntaxKind.AsyncKeyword, 156 await: SyntaxKind.AwaitKeyword, 157 of: SyntaxKind.OfKeyword, 158 }; 159 160 const textToKeyword = new Map(getEntries(textToKeywordObj)); 161 162 const textToToken = new Map(getEntries({ 163 ...textToKeywordObj, 164 "{": SyntaxKind.OpenBraceToken, 165 "}": SyntaxKind.CloseBraceToken, 166 "(": SyntaxKind.OpenParenToken, 167 ")": SyntaxKind.CloseParenToken, 168 "[": SyntaxKind.OpenBracketToken, 169 "]": SyntaxKind.CloseBracketToken, 170 ".": SyntaxKind.DotToken, 171 "...": SyntaxKind.DotDotDotToken, 172 ";": SyntaxKind.SemicolonToken, 173 ",": SyntaxKind.CommaToken, 174 "<": SyntaxKind.LessThanToken, 175 ">": SyntaxKind.GreaterThanToken, 176 "<=": SyntaxKind.LessThanEqualsToken, 177 ">=": SyntaxKind.GreaterThanEqualsToken, 178 "==": SyntaxKind.EqualsEqualsToken, 179 "!=": SyntaxKind.ExclamationEqualsToken, 180 "===": SyntaxKind.EqualsEqualsEqualsToken, 181 "!==": SyntaxKind.ExclamationEqualsEqualsToken, 182 "=>": SyntaxKind.EqualsGreaterThanToken, 183 "+": SyntaxKind.PlusToken, 184 "-": SyntaxKind.MinusToken, 185 "**": SyntaxKind.AsteriskAsteriskToken, 186 "*": SyntaxKind.AsteriskToken, 187 "/": SyntaxKind.SlashToken, 188 "%": SyntaxKind.PercentToken, 189 "++": SyntaxKind.PlusPlusToken, 190 "--": SyntaxKind.MinusMinusToken, 191 "<<": SyntaxKind.LessThanLessThanToken, 192 "</": SyntaxKind.LessThanSlashToken, 193 ">>": SyntaxKind.GreaterThanGreaterThanToken, 194 ">>>": SyntaxKind.GreaterThanGreaterThanGreaterThanToken, 195 "&": SyntaxKind.AmpersandToken, 196 "|": SyntaxKind.BarToken, 197 "^": SyntaxKind.CaretToken, 198 "!": SyntaxKind.ExclamationToken, 199 "~": SyntaxKind.TildeToken, 200 "&&": SyntaxKind.AmpersandAmpersandToken, 201 "||": SyntaxKind.BarBarToken, 202 "?": SyntaxKind.QuestionToken, 203 "??": SyntaxKind.QuestionQuestionToken, 204 "?.": SyntaxKind.QuestionDotToken, 205 ":": SyntaxKind.ColonToken, 206 "=": SyntaxKind.EqualsToken, 207 "+=": SyntaxKind.PlusEqualsToken, 208 "-=": SyntaxKind.MinusEqualsToken, 209 "*=": SyntaxKind.AsteriskEqualsToken, 210 "**=": SyntaxKind.AsteriskAsteriskEqualsToken, 211 "/=": SyntaxKind.SlashEqualsToken, 212 "%=": SyntaxKind.PercentEqualsToken, 213 "<<=": SyntaxKind.LessThanLessThanEqualsToken, 214 ">>=": SyntaxKind.GreaterThanGreaterThanEqualsToken, 215 ">>>=": SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken, 216 "&=": SyntaxKind.AmpersandEqualsToken, 217 "|=": SyntaxKind.BarEqualsToken, 218 "^=": SyntaxKind.CaretEqualsToken, 219 "||=": SyntaxKind.BarBarEqualsToken, 220 "&&=": SyntaxKind.AmpersandAmpersandEqualsToken, 221 "??=": SyntaxKind.QuestionQuestionEqualsToken, 222 "@": SyntaxKind.AtToken, 223 "`": SyntaxKind.BacktickToken 224 })); 225 226 /* 227 As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers 228 IdentifierStart :: 229 Can contain Unicode 3.0.0 categories: 230 Uppercase letter (Lu), 231 Lowercase letter (Ll), 232 Titlecase letter (Lt), 233 Modifier letter (Lm), 234 Other letter (Lo), or 235 Letter number (Nl). 236 IdentifierPart :: = 237 Can contain IdentifierStart + Unicode 3.0.0 categories: 238 Non-spacing mark (Mn), 239 Combining spacing mark (Mc), 240 Decimal number (Nd), or 241 Connector punctuation (Pc). 242 243 Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at: 244 http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt 245 */ 246 const unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, ]; 247 const unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, ]; 248 249 /* 250 As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers 251 IdentifierStart :: 252 Can contain Unicode 6.2 categories: 253 Uppercase letter (Lu), 254 Lowercase letter (Ll), 255 Titlecase letter (Lt), 256 Modifier letter (Lm), 257 Other letter (Lo), or 258 Letter number (Nl). 259 IdentifierPart :: 260 Can contain IdentifierStart + Unicode 6.2 categories: 261 Non-spacing mark (Mn), 262 Combining spacing mark (Mc), 263 Decimal number (Nd), 264 Connector punctuation (Pc), 265 <ZWNJ>, or 266 <ZWJ>. 267 268 Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at: 269 http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt 270 */ 271 const unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, ]; 272 const unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, ]; 273 274 /** 275 * Generated by scripts/regenerate-unicode-identifier-parts.js on node v12.4.0 with unicode 12.1 276 * based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords 277 * unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and 278 * unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start 279 */ 280 const unicodeESNextIdentifierStart = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2208, 2228, 2230, 2237, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69376, 69404, 69415, 69415, 69424, 69445, 69600, 69622, 69635, 69687, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70751, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71680, 71723, 71840, 71903, 71935, 71935, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 123136, 123180, 123191, 123197, 123214, 123214, 123584, 123627, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101]; 281 const unicodeESNextIdentifierPart = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2208, 2228, 2230, 2237, 2259, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3328, 3331, 3333, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7673, 7675, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43047, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69376, 69404, 69415, 69415, 69424, 69456, 69600, 69622, 69632, 69702, 69734, 69743, 69759, 69818, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69958, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70096, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70206, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70751, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71680, 71738, 71840, 71913, 71935, 71935, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123584, 123641, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101, 917760, 917999]; 282 283 /** 284 * Test for whether a single line comment's text contains a directive. 285 */ 286 const commentDirectiveRegExSingleLine = /^\s*\/\/\/?\s*@(ts-expect-error|ts-ignore)/; 287 288 /** 289 * Test for whether a multi-line comment's last line contains a directive. 290 */ 291 const commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@(ts-expect-error|ts-ignore)/; 292 293 function lookupInUnicodeMap(code: number, map: readonly number[]): boolean { 294 // Bail out quickly if it couldn't possibly be in the map. 295 if (code < map[0]) { 296 return false; 297 } 298 299 // Perform binary search in one of the Unicode range maps 300 let lo = 0; 301 let hi: number = map.length; 302 let mid: number; 303 304 while (lo + 1 < hi) { 305 mid = lo + (hi - lo) / 2; 306 // mid has to be even to catch a range's beginning 307 mid -= mid % 2; 308 if (map[mid] <= code && code <= map[mid + 1]) { 309 return true; 310 } 311 312 if (code < map[mid]) { 313 hi = mid; 314 } 315 else { 316 lo = mid + 2; 317 } 318 } 319 320 return false; 321 } 322 323 /* @internal */ export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget | undefined) { 324 return languageVersion! >= ScriptTarget.ES2015 ? 325 lookupInUnicodeMap(code, unicodeESNextIdentifierStart) : 326 languageVersion === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) : 327 lookupInUnicodeMap(code, unicodeES3IdentifierStart); 328 } 329 330 function isUnicodeIdentifierPart(code: number, languageVersion: ScriptTarget | undefined) { 331 return languageVersion! >= ScriptTarget.ES2015 ? 332 lookupInUnicodeMap(code, unicodeESNextIdentifierPart) : 333 languageVersion === ScriptTarget.ES5 ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) : 334 lookupInUnicodeMap(code, unicodeES3IdentifierPart); 335 } 336 337 function makeReverseMap(source: ESMap<string, number>): string[] { 338 const result: string[] = []; 339 source.forEach((value, name) => { 340 result[value] = name; 341 }); 342 return result; 343 } 344 345 const tokenStrings = makeReverseMap(textToToken); 346 export function tokenToString(t: SyntaxKind): string | undefined { 347 return tokenStrings[t]; 348 } 349 350 /* @internal */ 351 export function stringToToken(s: string): SyntaxKind | undefined { 352 return textToToken.get(s); 353 } 354 355 /* @internal */ 356 export function computeLineStarts(text: string): number[] { 357 const result: number[] = new Array(); 358 let pos = 0; 359 let lineStart = 0; 360 while (pos < text.length) { 361 const ch = text.charCodeAt(pos); 362 pos++; 363 switch (ch) { 364 case CharacterCodes.carriageReturn: 365 if (text.charCodeAt(pos) === CharacterCodes.lineFeed) { 366 pos++; 367 } 368 // falls through 369 case CharacterCodes.lineFeed: 370 result.push(lineStart); 371 lineStart = pos; 372 break; 373 default: 374 if (ch > CharacterCodes.maxAsciiCharacter && isLineBreak(ch)) { 375 result.push(lineStart); 376 lineStart = pos; 377 } 378 break; 379 } 380 } 381 result.push(lineStart); 382 return result; 383 } 384 385 export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number): number; 386 /* @internal */ 387 export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number; // eslint-disable-line @typescript-eslint/unified-signatures 388 export function getPositionOfLineAndCharacter(sourceFile: SourceFileLike, line: number, character: number, allowEdits?: true): number { 389 return sourceFile.getPositionOfLineAndCharacter ? 390 sourceFile.getPositionOfLineAndCharacter(line, character, allowEdits) : 391 computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text, allowEdits); 392 } 393 394 /* @internal */ 395 export function computePositionOfLineAndCharacter(lineStarts: readonly number[], line: number, character: number, debugText?: string, allowEdits?: true): number { 396 if (line < 0 || line >= lineStarts.length) { 397 if (allowEdits) { 398 // Clamp line to nearest allowable value 399 line = line < 0 ? 0 : line >= lineStarts.length ? lineStarts.length - 1 : line; 400 } 401 else { 402 Debug.fail(`Bad line number. Line: ${line}, lineStarts.length: ${lineStarts.length} , line map is correct? ${debugText !== undefined ? arraysEqual(lineStarts, computeLineStarts(debugText)) : "unknown"}`); 403 } 404 } 405 406 const res = lineStarts[line] + character; 407 if (allowEdits) { 408 // Clamp to nearest allowable values to allow the underlying to be edited without crashing (accuracy is lost, instead) 409 // TODO: Somehow track edits between file as it was during the creation of sourcemap we have and the current file and 410 // apply them to the computed position to improve accuracy 411 return res > lineStarts[line + 1] ? lineStarts[line + 1] : typeof debugText === "string" && res > debugText.length ? debugText.length : res; 412 } 413 if (line < lineStarts.length - 1) { 414 Debug.assert(res < lineStarts[line + 1]); 415 } 416 else if (debugText !== undefined) { 417 Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline 418 } 419 return res; 420 } 421 422 /* @internal */ 423 export function getLineStarts(sourceFile: SourceFileLike): readonly number[] { 424 return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text)); 425 } 426 427 /* @internal */ 428 export function computeLineAndCharacterOfPosition(lineStarts: readonly number[], position: number): LineAndCharacter { 429 const lineNumber = computeLineOfPosition(lineStarts, position); 430 return { 431 line: lineNumber, 432 character: position - lineStarts[lineNumber] 433 }; 434 } 435 436 /** 437 * @internal 438 * We assume the first line starts at position 0 and 'position' is non-negative. 439 */ 440 export function computeLineOfPosition(lineStarts: readonly number[], position: number, lowerBound?: number) { 441 let lineNumber = binarySearch(lineStarts, position, identity, compareValues, lowerBound); 442 if (lineNumber < 0) { 443 // If the actual position was not found, 444 // the binary search returns the 2's-complement of the next line start 445 // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20 446 // then the search will return -2. 447 // 448 // We want the index of the previous line start, so we subtract 1. 449 // Review 2's-complement if this is confusing. 450 lineNumber = ~lineNumber - 1; 451 Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); 452 } 453 return lineNumber; 454 } 455 456 /** @internal */ 457 export function getLinesBetweenPositions(sourceFile: SourceFileLike, pos1: number, pos2: number) { 458 if (pos1 === pos2) return 0; 459 const lineStarts = getLineStarts(sourceFile); 460 const lower = Math.min(pos1, pos2); 461 const isNegative = lower === pos2; 462 const upper = isNegative ? pos1 : pos2; 463 const lowerLine = computeLineOfPosition(lineStarts, lower); 464 const upperLine = computeLineOfPosition(lineStarts, upper, lowerLine); 465 return isNegative ? lowerLine - upperLine : upperLine - lowerLine; 466 } 467 468 export function getLineAndCharacterOfPosition(sourceFile: SourceFileLike, position: number): LineAndCharacter { 469 return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); 470 } 471 472 export function isWhiteSpaceLike(ch: number): boolean { 473 return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); 474 } 475 476 /** Does not include line breaks. For that, see isWhiteSpaceLike. */ 477 export function isWhiteSpaceSingleLine(ch: number): boolean { 478 // Note: nextLine is in the Zs space, and should be considered to be a whitespace. 479 // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript. 480 return ch === CharacterCodes.space || 481 ch === CharacterCodes.tab || 482 ch === CharacterCodes.verticalTab || 483 ch === CharacterCodes.formFeed || 484 ch === CharacterCodes.nonBreakingSpace || 485 ch === CharacterCodes.nextLine || 486 ch === CharacterCodes.ogham || 487 ch >= CharacterCodes.enQuad && ch <= CharacterCodes.zeroWidthSpace || 488 ch === CharacterCodes.narrowNoBreakSpace || 489 ch === CharacterCodes.mathematicalSpace || 490 ch === CharacterCodes.ideographicSpace || 491 ch === CharacterCodes.byteOrderMark; 492 } 493 494 export function isLineBreak(ch: number): boolean { 495 // ES5 7.3: 496 // The ECMAScript line terminator characters are listed in Table 3. 497 // Table 3: Line Terminator Characters 498 // Code Unit Value Name Formal Name 499 // \u000A Line Feed <LF> 500 // \u000D Carriage Return <CR> 501 // \u2028 Line separator <LS> 502 // \u2029 Paragraph separator <PS> 503 // Only the characters in Table 3 are treated as line terminators. Other new line or line 504 // breaking characters are treated as white space but not as line terminators. 505 506 return ch === CharacterCodes.lineFeed || 507 ch === CharacterCodes.carriageReturn || 508 ch === CharacterCodes.lineSeparator || 509 ch === CharacterCodes.paragraphSeparator; 510 } 511 512 function isDigit(ch: number): boolean { 513 return ch >= CharacterCodes._0 && ch <= CharacterCodes._9; 514 } 515 516 function isHexDigit(ch: number): boolean { 517 return isDigit(ch) || ch >= CharacterCodes.A && ch <= CharacterCodes.F || ch >= CharacterCodes.a && ch <= CharacterCodes.f; 518 } 519 520 function isCodePoint(code: number): boolean { 521 return code <= 0x10FFFF; 522 } 523 524 /* @internal */ 525 export function isOctalDigit(ch: number): boolean { 526 return ch >= CharacterCodes._0 && ch <= CharacterCodes._7; 527 } 528 529 export function couldStartTrivia(text: string, pos: number): boolean { 530 // Keep in sync with skipTrivia 531 const ch = text.charCodeAt(pos); 532 switch (ch) { 533 case CharacterCodes.carriageReturn: 534 case CharacterCodes.lineFeed: 535 case CharacterCodes.tab: 536 case CharacterCodes.verticalTab: 537 case CharacterCodes.formFeed: 538 case CharacterCodes.space: 539 case CharacterCodes.slash: 540 // starts of normal trivia 541 // falls through 542 case CharacterCodes.lessThan: 543 case CharacterCodes.bar: 544 case CharacterCodes.equals: 545 case CharacterCodes.greaterThan: 546 // Starts of conflict marker trivia 547 return true; 548 case CharacterCodes.hash: 549 // Only if its the beginning can we have #! trivia 550 return pos === 0; 551 default: 552 return ch > CharacterCodes.maxAsciiCharacter; 553 } 554 } 555 556 /* @internal */ 557 export function skipTrivia(text: string, pos: number, stopAfterLineBreak?: boolean, stopAtComments = false): number { 558 if (positionIsSynthesized(pos)) { 559 return pos; 560 } 561 562 // Keep in sync with couldStartTrivia 563 while (true) { 564 const ch = text.charCodeAt(pos); 565 switch (ch) { 566 case CharacterCodes.carriageReturn: 567 if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { 568 pos++; 569 } 570 // falls through 571 case CharacterCodes.lineFeed: 572 pos++; 573 if (stopAfterLineBreak) { 574 return pos; 575 } 576 continue; 577 case CharacterCodes.tab: 578 case CharacterCodes.verticalTab: 579 case CharacterCodes.formFeed: 580 case CharacterCodes.space: 581 pos++; 582 continue; 583 case CharacterCodes.slash: 584 if (stopAtComments) { 585 break; 586 } 587 if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { 588 pos += 2; 589 while (pos < text.length) { 590 if (isLineBreak(text.charCodeAt(pos))) { 591 break; 592 } 593 pos++; 594 } 595 continue; 596 } 597 if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { 598 pos += 2; 599 while (pos < text.length) { 600 if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { 601 pos += 2; 602 break; 603 } 604 pos++; 605 } 606 continue; 607 } 608 break; 609 610 case CharacterCodes.lessThan: 611 case CharacterCodes.bar: 612 case CharacterCodes.equals: 613 case CharacterCodes.greaterThan: 614 if (isConflictMarkerTrivia(text, pos)) { 615 pos = scanConflictMarkerTrivia(text, pos); 616 continue; 617 } 618 break; 619 620 case CharacterCodes.hash: 621 if (pos === 0 && isShebangTrivia(text, pos)) { 622 pos = scanShebangTrivia(text, pos); 623 continue; 624 } 625 break; 626 627 default: 628 if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { 629 pos++; 630 continue; 631 } 632 break; 633 } 634 return pos; 635 } 636 } 637 638 // All conflict markers consist of the same character repeated seven times. If it is 639 // a <<<<<<< or >>>>>>> marker then it is also followed by a space. 640 const mergeConflictMarkerLength = "<<<<<<<".length; 641 642 function isConflictMarkerTrivia(text: string, pos: number) { 643 Debug.assert(pos >= 0); 644 645 // Conflict markers must be at the start of a line. 646 if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) { 647 const ch = text.charCodeAt(pos); 648 649 if ((pos + mergeConflictMarkerLength) < text.length) { 650 for (let i = 0; i < mergeConflictMarkerLength; i++) { 651 if (text.charCodeAt(pos + i) !== ch) { 652 return false; 653 } 654 } 655 656 return ch === CharacterCodes.equals || 657 text.charCodeAt(pos + mergeConflictMarkerLength) === CharacterCodes.space; 658 } 659 } 660 661 return false; 662 } 663 664 function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: DiagnosticMessage, pos?: number, len?: number) => void) { 665 if (error) { 666 error(Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength); 667 } 668 669 const ch = text.charCodeAt(pos); 670 const len = text.length; 671 672 if (ch === CharacterCodes.lessThan || ch === CharacterCodes.greaterThan) { 673 while (pos < len && !isLineBreak(text.charCodeAt(pos))) { 674 pos++; 675 } 676 } 677 else { 678 Debug.assert(ch === CharacterCodes.bar || ch === CharacterCodes.equals); 679 // Consume everything from the start of a ||||||| or ======= marker to the start 680 // of the next ======= or >>>>>>> marker. 681 while (pos < len) { 682 const currentChar = text.charCodeAt(pos); 683 if ((currentChar === CharacterCodes.equals || currentChar === CharacterCodes.greaterThan) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) { 684 break; 685 } 686 687 pos++; 688 } 689 } 690 691 return pos; 692 } 693 694 const shebangTriviaRegex = /^#!.*/; 695 696 /*@internal*/ 697 export function isShebangTrivia(text: string, pos: number) { 698 // Shebangs check must only be done at the start of the file 699 Debug.assert(pos === 0); 700 return shebangTriviaRegex.test(text); 701 } 702 703 /*@internal*/ 704 export function scanShebangTrivia(text: string, pos: number) { 705 const shebang = shebangTriviaRegex.exec(text)![0]; 706 pos = pos + shebang.length; 707 return pos; 708 } 709 710 /** 711 * Invokes a callback for each comment range following the provided position. 712 * 713 * Single-line comment ranges include the leading double-slash characters but not the ending 714 * line break. Multi-line comment ranges include the leading slash-asterisk and trailing 715 * asterisk-slash characters. 716 * 717 * @param reduce If true, accumulates the result of calling the callback in a fashion similar 718 * to reduceLeft. If false, iteration stops when the callback returns a truthy value. 719 * @param text The source text to scan. 720 * @param pos The position at which to start scanning. 721 * @param trailing If false, whitespace is skipped until the first line break and comments 722 * between that location and the next token are returned. If true, comments occurring 723 * between the given position and the next line break are returned. 724 * @param cb The callback to execute as each comment range is encountered. 725 * @param state A state value to pass to each iteration of the callback. 726 * @param initial An initial value to pass when accumulating results (when "reduce" is true). 727 * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy 728 * return value of the callback. 729 */ 730 function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U | undefined) => U, state: T, initial?: U): U | undefined { 731 let pendingPos!: number; 732 let pendingEnd!: number; 733 let pendingKind!: CommentKind; 734 let pendingHasTrailingNewLine!: boolean; 735 let hasPendingCommentRange = false; 736 let collecting = trailing; 737 let accumulator = initial; 738 if (pos === 0) { 739 collecting = true; 740 const shebang = getShebang(text); 741 if (shebang) { 742 pos = shebang.length; 743 } 744 } 745 scan: while (pos >= 0 && pos < text.length) { 746 const ch = text.charCodeAt(pos); 747 switch (ch) { 748 case CharacterCodes.carriageReturn: 749 if (text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { 750 pos++; 751 } 752 // falls through 753 case CharacterCodes.lineFeed: 754 pos++; 755 if (trailing) { 756 break scan; 757 } 758 759 collecting = true; 760 if (hasPendingCommentRange) { 761 pendingHasTrailingNewLine = true; 762 } 763 764 continue; 765 case CharacterCodes.tab: 766 case CharacterCodes.verticalTab: 767 case CharacterCodes.formFeed: 768 case CharacterCodes.space: 769 pos++; 770 continue; 771 case CharacterCodes.slash: 772 const nextChar = text.charCodeAt(pos + 1); 773 let hasTrailingNewLine = false; 774 if (nextChar === CharacterCodes.slash || nextChar === CharacterCodes.asterisk) { 775 const kind = nextChar === CharacterCodes.slash ? SyntaxKind.SingleLineCommentTrivia : SyntaxKind.MultiLineCommentTrivia; 776 const startPos = pos; 777 pos += 2; 778 if (nextChar === CharacterCodes.slash) { 779 while (pos < text.length) { 780 if (isLineBreak(text.charCodeAt(pos))) { 781 hasTrailingNewLine = true; 782 break; 783 } 784 pos++; 785 } 786 } 787 else { 788 while (pos < text.length) { 789 if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { 790 pos += 2; 791 break; 792 } 793 pos++; 794 } 795 } 796 797 if (collecting) { 798 if (hasPendingCommentRange) { 799 accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator); 800 if (!reduce && accumulator) { 801 // If we are not reducing and we have a truthy result, return it. 802 return accumulator; 803 } 804 } 805 806 pendingPos = startPos; 807 pendingEnd = pos; 808 pendingKind = kind; 809 pendingHasTrailingNewLine = hasTrailingNewLine; 810 hasPendingCommentRange = true; 811 } 812 813 continue; 814 } 815 break scan; 816 default: 817 if (ch > CharacterCodes.maxAsciiCharacter && (isWhiteSpaceLike(ch))) { 818 if (hasPendingCommentRange && isLineBreak(ch)) { 819 pendingHasTrailingNewLine = true; 820 } 821 pos++; 822 continue; 823 } 824 break scan; 825 } 826 } 827 828 if (hasPendingCommentRange) { 829 accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator); 830 } 831 832 return accumulator; 833 } 834 835 export function forEachLeadingCommentRange<U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; 836 export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; 837 export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { 838 return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); 839 } 840 841 export function forEachTrailingCommentRange<U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; 842 export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; 843 export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { 844 return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); 845 } 846 847 export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { 848 return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial); 849 } 850 851 export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { 852 return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial); 853 } 854 855 function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) { 856 if (!comments) { 857 comments = []; 858 } 859 860 comments.push({ kind, pos, end, hasTrailingNewLine }); 861 return comments; 862 } 863 864 export function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined { 865 return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); 866 } 867 868 export function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined { 869 return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); 870 } 871 872 /** Optionally, get the shebang */ 873 export function getShebang(text: string): string | undefined { 874 const match = shebangTriviaRegex.exec(text); 875 if (match) { 876 return match[0]; 877 } 878 } 879 880 export function isIdentifierStart(ch: number, languageVersion: ScriptTarget | undefined): boolean { 881 return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z || 882 ch === CharacterCodes.$ || ch === CharacterCodes._ || 883 ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierStart(ch, languageVersion); 884 } 885 886 export function isIdentifierPart(ch: number, languageVersion: ScriptTarget | undefined, identifierVariant?: LanguageVariant): boolean { 887 return ch >= CharacterCodes.A && ch <= CharacterCodes.Z || ch >= CharacterCodes.a && ch <= CharacterCodes.z || 888 ch >= CharacterCodes._0 && ch <= CharacterCodes._9 || ch === CharacterCodes.$ || ch === CharacterCodes._ || 889 // "-" and ":" are valid in JSX Identifiers 890 (identifierVariant === LanguageVariant.JSX ? (ch === CharacterCodes.minus || ch === CharacterCodes.colon) : false) || 891 ch > CharacterCodes.maxAsciiCharacter && isUnicodeIdentifierPart(ch, languageVersion); 892 } 893 894 /* @internal */ 895 export function isIdentifierText(name: string, languageVersion: ScriptTarget | undefined, identifierVariant?: LanguageVariant): boolean { 896 let ch = codePointAt(name, 0); 897 if (!isIdentifierStart(ch, languageVersion)) { 898 return false; 899 } 900 901 for (let i = charSize(ch); i < name.length; i += charSize(ch)) { 902 if (!isIdentifierPart(ch = codePointAt(name, i), languageVersion, identifierVariant)) { 903 return false; 904 } 905 } 906 907 return true; 908 } 909 910 // Creates a scanner over a (possibly unspecified) range of a piece of text. 911 export function createScanner(languageVersion: ScriptTarget, 912 skipTrivia: boolean, 913 languageVariant = LanguageVariant.Standard, 914 textInitial?: string, 915 onError?: ErrorCallback, 916 start?: number, 917 length?: number): Scanner { 918 919 let text = textInitial!; 920 921 // Current position (end position of text of current token) 922 let pos: number; 923 924 925 // end of text 926 let end: number; 927 928 // Start position of whitespace before current token 929 let startPos: number; 930 931 // Start position of text of current token 932 let tokenPos: number; 933 934 let token: SyntaxKind; 935 let tokenValue!: string; 936 let tokenFlags: TokenFlags; 937 938 let commentDirectives: CommentDirective[] | undefined; 939 let inJSDocType = 0; 940 941 setText(text, start, length); 942 943 const scanner: Scanner = { 944 getStartPos: () => startPos, 945 getTextPos: () => pos, 946 getToken: () => token, 947 getTokenPos: () => tokenPos, 948 getTokenText: () => text.substring(tokenPos, pos), 949 getTokenValue: () => tokenValue, 950 hasUnicodeEscape: () => (tokenFlags & TokenFlags.UnicodeEscape) !== 0, 951 hasExtendedUnicodeEscape: () => (tokenFlags & TokenFlags.ExtendedUnicodeEscape) !== 0, 952 hasPrecedingLineBreak: () => (tokenFlags & TokenFlags.PrecedingLineBreak) !== 0, 953 hasPrecedingJSDocComment: () => (tokenFlags & TokenFlags.PrecedingJSDocComment) !== 0, 954 isIdentifier: () => token === SyntaxKind.Identifier || token > SyntaxKind.LastReservedWord, 955 isReservedWord: () => token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord, 956 isUnterminated: () => (tokenFlags & TokenFlags.Unterminated) !== 0, 957 getCommentDirectives: () => commentDirectives, 958 getNumericLiteralFlags: () => tokenFlags & TokenFlags.NumericLiteralFlags, 959 getTokenFlags: () => tokenFlags, 960 reScanGreaterToken, 961 reScanAsteriskEqualsToken, 962 reScanSlashToken, 963 reScanTemplateToken, 964 reScanTemplateHeadOrNoSubstitutionTemplate, 965 scanJsxIdentifier, 966 scanJsxAttributeValue, 967 reScanJsxAttributeValue, 968 reScanJsxToken, 969 reScanLessThanToken, 970 reScanQuestionToken, 971 reScanInvalidIdentifier, 972 scanJsxToken, 973 scanJsDocToken, 974 scan, 975 getText, 976 clearCommentDirectives, 977 setText, 978 setScriptTarget, 979 setLanguageVariant, 980 setOnError, 981 setTextPos, 982 setInJSDocType, 983 tryScan, 984 lookAhead, 985 scanRange, 986 }; 987 988 if (Debug.isDebugging) { 989 Object.defineProperty(scanner, "__debugShowCurrentPositionInText", { 990 get: () => { 991 const text = scanner.getText(); 992 return text.slice(0, scanner.getStartPos()) + "║" + text.slice(scanner.getStartPos()); 993 }, 994 }); 995 } 996 997 return scanner; 998 999 function error(message: DiagnosticMessage): void; 1000 function error(message: DiagnosticMessage, errPos: number, length: number): void; 1001 function error(message: DiagnosticMessage, errPos: number = pos, length?: number): void { 1002 if (onError) { 1003 const oldPos = pos; 1004 pos = errPos; 1005 onError(message, length || 0); 1006 pos = oldPos; 1007 } 1008 } 1009 1010 function scanNumberFragment(): string { 1011 let start = pos; 1012 let allowSeparator = false; 1013 let isPreviousTokenSeparator = false; 1014 let result = ""; 1015 while (true) { 1016 const ch = text.charCodeAt(pos); 1017 if (ch === CharacterCodes._) { 1018 tokenFlags |= TokenFlags.ContainsSeparator; 1019 if (allowSeparator) { 1020 allowSeparator = false; 1021 isPreviousTokenSeparator = true; 1022 result += text.substring(start, pos); 1023 } 1024 else if (isPreviousTokenSeparator) { 1025 error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); 1026 } 1027 else { 1028 error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); 1029 } 1030 pos++; 1031 start = pos; 1032 continue; 1033 } 1034 if (isDigit(ch)) { 1035 allowSeparator = true; 1036 isPreviousTokenSeparator = false; 1037 pos++; 1038 continue; 1039 } 1040 break; 1041 } 1042 if (text.charCodeAt(pos - 1) === CharacterCodes._) { 1043 error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); 1044 } 1045 return result + text.substring(start, pos); 1046 } 1047 1048 function scanNumber(): { type: SyntaxKind, value: string } { 1049 const start = pos; 1050 const mainFragment = scanNumberFragment(); 1051 let decimalFragment: string | undefined; 1052 let scientificFragment: string | undefined; 1053 if (text.charCodeAt(pos) === CharacterCodes.dot) { 1054 pos++; 1055 decimalFragment = scanNumberFragment(); 1056 } 1057 let end = pos; 1058 if (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e) { 1059 pos++; 1060 tokenFlags |= TokenFlags.Scientific; 1061 if (text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) pos++; 1062 const preNumericPart = pos; 1063 const finalFragment = scanNumberFragment(); 1064 if (!finalFragment) { 1065 error(Diagnostics.Digit_expected); 1066 } 1067 else { 1068 scientificFragment = text.substring(end, preNumericPart) + finalFragment; 1069 end = pos; 1070 } 1071 } 1072 let result: string; 1073 if (tokenFlags & TokenFlags.ContainsSeparator) { 1074 result = mainFragment; 1075 if (decimalFragment) { 1076 result += "." + decimalFragment; 1077 } 1078 if (scientificFragment) { 1079 result += scientificFragment; 1080 } 1081 } 1082 else { 1083 result = text.substring(start, end); // No need to use all the fragments; no _ removal needed 1084 } 1085 1086 if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) { 1087 checkForIdentifierStartAfterNumericLiteral(start, decimalFragment === undefined && !!(tokenFlags & TokenFlags.Scientific)); 1088 return { 1089 type: SyntaxKind.NumericLiteral, 1090 value: "" + +result // if value is not an integer, it can be safely coerced to a number 1091 }; 1092 } 1093 else { 1094 tokenValue = result; 1095 const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint 1096 checkForIdentifierStartAfterNumericLiteral(start); 1097 return { type, value: tokenValue }; 1098 } 1099 } 1100 1101 function checkForIdentifierStartAfterNumericLiteral(numericStart: number, isScientific?: boolean) { 1102 if (!isIdentifierStart(codePointAt(text, pos), languageVersion)) { 1103 return; 1104 } 1105 1106 const identifierStart = pos; 1107 const { length } = scanIdentifierParts(); 1108 1109 if (length === 1 && text[identifierStart] === "n") { 1110 if (isScientific) { 1111 error(Diagnostics.A_bigint_literal_cannot_use_exponential_notation, numericStart, identifierStart - numericStart + 1); 1112 } 1113 else { 1114 error(Diagnostics.A_bigint_literal_must_be_an_integer, numericStart, identifierStart - numericStart + 1); 1115 } 1116 } 1117 else { 1118 error(Diagnostics.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal, identifierStart, length); 1119 pos = identifierStart; 1120 } 1121 } 1122 1123 function scanOctalDigits(): number { 1124 const start = pos; 1125 while (isOctalDigit(text.charCodeAt(pos))) { 1126 pos++; 1127 } 1128 return +(text.substring(start, pos)); 1129 } 1130 1131 /** 1132 * Scans the given number of hexadecimal digits in the text, 1133 * returning -1 if the given number is unavailable. 1134 */ 1135 function scanExactNumberOfHexDigits(count: number, canHaveSeparators: boolean): number { 1136 const valueString = scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators); 1137 return valueString ? parseInt(valueString, 16) : -1; 1138 } 1139 1140 /** 1141 * Scans as many hexadecimal digits as are available in the text, 1142 * returning "" if the given number of digits was unavailable. 1143 */ 1144 function scanMinimumNumberOfHexDigits(count: number, canHaveSeparators: boolean): string { 1145 return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators); 1146 } 1147 1148 function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean, canHaveSeparators: boolean): string { 1149 let valueChars: number[] = []; 1150 let allowSeparator = false; 1151 let isPreviousTokenSeparator = false; 1152 while (valueChars.length < minCount || scanAsManyAsPossible) { 1153 let ch = text.charCodeAt(pos); 1154 if (canHaveSeparators && ch === CharacterCodes._) { 1155 tokenFlags |= TokenFlags.ContainsSeparator; 1156 if (allowSeparator) { 1157 allowSeparator = false; 1158 isPreviousTokenSeparator = true; 1159 } 1160 else if (isPreviousTokenSeparator) { 1161 error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); 1162 } 1163 else { 1164 error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); 1165 } 1166 pos++; 1167 continue; 1168 } 1169 allowSeparator = canHaveSeparators; 1170 if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) { 1171 ch += CharacterCodes.a - CharacterCodes.A; // standardize hex literals to lowercase 1172 } 1173 else if (!((ch >= CharacterCodes._0 && ch <= CharacterCodes._9) || 1174 (ch >= CharacterCodes.a && ch <= CharacterCodes.f) 1175 )) { 1176 break; 1177 } 1178 valueChars.push(ch); 1179 pos++; 1180 isPreviousTokenSeparator = false; 1181 } 1182 if (valueChars.length < minCount) { 1183 valueChars = []; 1184 } 1185 if (text.charCodeAt(pos - 1) === CharacterCodes._) { 1186 error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); 1187 } 1188 return String.fromCharCode(...valueChars); 1189 } 1190 1191 function scanString(jsxAttributeString = false): string { 1192 const quote = text.charCodeAt(pos); 1193 pos++; 1194 let result = ""; 1195 let start = pos; 1196 while (true) { 1197 if (pos >= end) { 1198 result += text.substring(start, pos); 1199 tokenFlags |= TokenFlags.Unterminated; 1200 error(Diagnostics.Unterminated_string_literal); 1201 break; 1202 } 1203 const ch = text.charCodeAt(pos); 1204 if (ch === quote) { 1205 result += text.substring(start, pos); 1206 pos++; 1207 break; 1208 } 1209 if (ch === CharacterCodes.backslash && !jsxAttributeString) { 1210 result += text.substring(start, pos); 1211 result += scanEscapeSequence(); 1212 start = pos; 1213 continue; 1214 } 1215 if (isLineBreak(ch) && !jsxAttributeString) { 1216 result += text.substring(start, pos); 1217 tokenFlags |= TokenFlags.Unterminated; 1218 error(Diagnostics.Unterminated_string_literal); 1219 break; 1220 } 1221 pos++; 1222 } 1223 return result; 1224 } 1225 1226 /** 1227 * Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or 1228 * a literal component of a TemplateExpression. 1229 */ 1230 function scanTemplateAndSetTokenValue(isTaggedTemplate: boolean): SyntaxKind { 1231 const startedWithBacktick = text.charCodeAt(pos) === CharacterCodes.backtick; 1232 1233 pos++; 1234 let start = pos; 1235 let contents = ""; 1236 let resultingToken: SyntaxKind; 1237 1238 while (true) { 1239 if (pos >= end) { 1240 contents += text.substring(start, pos); 1241 tokenFlags |= TokenFlags.Unterminated; 1242 error(Diagnostics.Unterminated_template_literal); 1243 resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail; 1244 break; 1245 } 1246 1247 const currChar = text.charCodeAt(pos); 1248 1249 // '`' 1250 if (currChar === CharacterCodes.backtick) { 1251 contents += text.substring(start, pos); 1252 pos++; 1253 resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail; 1254 break; 1255 } 1256 1257 // '${' 1258 if (currChar === CharacterCodes.$ && pos + 1 < end && text.charCodeAt(pos + 1) === CharacterCodes.openBrace) { 1259 contents += text.substring(start, pos); 1260 pos += 2; 1261 resultingToken = startedWithBacktick ? SyntaxKind.TemplateHead : SyntaxKind.TemplateMiddle; 1262 break; 1263 } 1264 1265 // Escape character 1266 if (currChar === CharacterCodes.backslash) { 1267 contents += text.substring(start, pos); 1268 contents += scanEscapeSequence(isTaggedTemplate); 1269 start = pos; 1270 continue; 1271 } 1272 1273 // Speculated ECMAScript 6 Spec 11.8.6.1: 1274 // <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values 1275 if (currChar === CharacterCodes.carriageReturn) { 1276 contents += text.substring(start, pos); 1277 pos++; 1278 1279 if (pos < end && text.charCodeAt(pos) === CharacterCodes.lineFeed) { 1280 pos++; 1281 } 1282 1283 contents += "\n"; 1284 start = pos; 1285 continue; 1286 } 1287 1288 pos++; 1289 } 1290 1291 Debug.assert(resultingToken !== undefined); 1292 1293 tokenValue = contents; 1294 return resultingToken; 1295 } 1296 1297 function scanEscapeSequence(isTaggedTemplate?: boolean): string { 1298 const start = pos; 1299 pos++; 1300 if (pos >= end) { 1301 error(Diagnostics.Unexpected_end_of_text); 1302 return ""; 1303 } 1304 const ch = text.charCodeAt(pos); 1305 pos++; 1306 switch (ch) { 1307 case CharacterCodes._0: 1308 // '\01' 1309 if (isTaggedTemplate && pos < end && isDigit(text.charCodeAt(pos))) { 1310 pos++; 1311 tokenFlags |= TokenFlags.ContainsInvalidEscape; 1312 return text.substring(start, pos); 1313 } 1314 return "\0"; 1315 case CharacterCodes.b: 1316 return "\b"; 1317 case CharacterCodes.t: 1318 return "\t"; 1319 case CharacterCodes.n: 1320 return "\n"; 1321 case CharacterCodes.v: 1322 return "\v"; 1323 case CharacterCodes.f: 1324 return "\f"; 1325 case CharacterCodes.r: 1326 return "\r"; 1327 case CharacterCodes.singleQuote: 1328 return "\'"; 1329 case CharacterCodes.doubleQuote: 1330 return "\""; 1331 case CharacterCodes.u: 1332 if (isTaggedTemplate) { 1333 // '\u' or '\u0' or '\u00' or '\u000' 1334 for (let escapePos = pos; escapePos < pos + 4; escapePos++) { 1335 if (escapePos < end && !isHexDigit(text.charCodeAt(escapePos)) && text.charCodeAt(escapePos) !== CharacterCodes.openBrace) { 1336 pos = escapePos; 1337 tokenFlags |= TokenFlags.ContainsInvalidEscape; 1338 return text.substring(start, pos); 1339 } 1340 } 1341 } 1342 // '\u{DDDDDDDD}' 1343 if (pos < end && text.charCodeAt(pos) === CharacterCodes.openBrace) { 1344 pos++; 1345 1346 // '\u{' 1347 if (isTaggedTemplate && !isHexDigit(text.charCodeAt(pos))) { 1348 tokenFlags |= TokenFlags.ContainsInvalidEscape; 1349 return text.substring(start, pos); 1350 } 1351 1352 if (isTaggedTemplate) { 1353 const savePos = pos; 1354 const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false); 1355 const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1; 1356 1357 // '\u{Not Code Point' or '\u{CodePoint' 1358 if (!isCodePoint(escapedValue) || text.charCodeAt(pos) !== CharacterCodes.closeBrace) { 1359 tokenFlags |= TokenFlags.ContainsInvalidEscape; 1360 return text.substring(start, pos); 1361 } 1362 else { 1363 pos = savePos; 1364 } 1365 } 1366 tokenFlags |= TokenFlags.ExtendedUnicodeEscape; 1367 return scanExtendedUnicodeEscape(); 1368 } 1369 1370 tokenFlags |= TokenFlags.UnicodeEscape; 1371 // '\uDDDD' 1372 return scanHexadecimalEscape(/*numDigits*/ 4); 1373 1374 case CharacterCodes.x: 1375 if (isTaggedTemplate) { 1376 if (!isHexDigit(text.charCodeAt(pos))) { 1377 tokenFlags |= TokenFlags.ContainsInvalidEscape; 1378 return text.substring(start, pos); 1379 } 1380 else if (!isHexDigit(text.charCodeAt(pos + 1))) { 1381 pos++; 1382 tokenFlags |= TokenFlags.ContainsInvalidEscape; 1383 return text.substring(start, pos); 1384 } 1385 } 1386 // '\xDD' 1387 return scanHexadecimalEscape(/*numDigits*/ 2); 1388 1389 // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence), 1390 // the line terminator is interpreted to be "the empty code unit sequence". 1391 case CharacterCodes.carriageReturn: 1392 if (pos < end && text.charCodeAt(pos) === CharacterCodes.lineFeed) { 1393 pos++; 1394 } 1395 // falls through 1396 case CharacterCodes.lineFeed: 1397 case CharacterCodes.lineSeparator: 1398 case CharacterCodes.paragraphSeparator: 1399 return ""; 1400 default: 1401 return String.fromCharCode(ch); 1402 } 1403 } 1404 1405 function scanHexadecimalEscape(numDigits: number): string { 1406 const escapedValue = scanExactNumberOfHexDigits(numDigits, /*canHaveSeparators*/ false); 1407 1408 if (escapedValue >= 0) { 1409 return String.fromCharCode(escapedValue); 1410 } 1411 else { 1412 error(Diagnostics.Hexadecimal_digit_expected); 1413 return ""; 1414 } 1415 } 1416 1417 function scanExtendedUnicodeEscape(): string { 1418 const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false); 1419 const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1; 1420 let isInvalidExtendedEscape = false; 1421 1422 // Validate the value of the digit 1423 if (escapedValue < 0) { 1424 error(Diagnostics.Hexadecimal_digit_expected); 1425 isInvalidExtendedEscape = true; 1426 } 1427 else if (escapedValue > 0x10FFFF) { 1428 error(Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive); 1429 isInvalidExtendedEscape = true; 1430 } 1431 1432 if (pos >= end) { 1433 error(Diagnostics.Unexpected_end_of_text); 1434 isInvalidExtendedEscape = true; 1435 } 1436 else if (text.charCodeAt(pos) === CharacterCodes.closeBrace) { 1437 // Only swallow the following character up if it's a '}'. 1438 pos++; 1439 } 1440 else { 1441 error(Diagnostics.Unterminated_Unicode_escape_sequence); 1442 isInvalidExtendedEscape = true; 1443 } 1444 1445 if (isInvalidExtendedEscape) { 1446 return ""; 1447 } 1448 1449 return utf16EncodeAsString(escapedValue); 1450 } 1451 1452 // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX' 1453 // and return code point value if valid Unicode escape is found. Otherwise return -1. 1454 function peekUnicodeEscape(): number { 1455 if (pos + 5 < end && text.charCodeAt(pos + 1) === CharacterCodes.u) { 1456 const start = pos; 1457 pos += 2; 1458 const value = scanExactNumberOfHexDigits(4, /*canHaveSeparators*/ false); 1459 pos = start; 1460 return value; 1461 } 1462 return -1; 1463 } 1464 1465 1466 function peekExtendedUnicodeEscape(): number { 1467 if (languageVersion >= ScriptTarget.ES2015 && codePointAt(text, pos + 1) === CharacterCodes.u && codePointAt(text, pos + 2) === CharacterCodes.openBrace) { 1468 const start = pos; 1469 pos += 3; 1470 const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false); 1471 const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1; 1472 pos = start; 1473 return escapedValue; 1474 } 1475 return -1; 1476 } 1477 1478 function scanIdentifierParts(): string { 1479 let result = ""; 1480 let start = pos; 1481 while (pos < end) { 1482 let ch = codePointAt(text, pos); 1483 if (isIdentifierPart(ch, languageVersion)) { 1484 pos += charSize(ch); 1485 } 1486 else if (ch === CharacterCodes.backslash) { 1487 ch = peekExtendedUnicodeEscape(); 1488 if (ch >= 0 && isIdentifierPart(ch, languageVersion)) { 1489 pos += 3; 1490 tokenFlags |= TokenFlags.ExtendedUnicodeEscape; 1491 result += scanExtendedUnicodeEscape(); 1492 start = pos; 1493 continue; 1494 } 1495 ch = peekUnicodeEscape(); 1496 if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) { 1497 break; 1498 } 1499 tokenFlags |= TokenFlags.UnicodeEscape; 1500 result += text.substring(start, pos); 1501 result += utf16EncodeAsString(ch); 1502 // Valid Unicode escape is always six characters 1503 pos += 6; 1504 start = pos; 1505 } 1506 else { 1507 break; 1508 } 1509 } 1510 result += text.substring(start, pos); 1511 return result; 1512 } 1513 1514 function getIdentifierToken(): SyntaxKind.Identifier | KeywordSyntaxKind { 1515 // Reserved words are between 2 and 12 characters long and start with a lowercase letter 1516 const len = tokenValue.length; 1517 if (len >= 2 && len <= 12) { 1518 const ch = tokenValue.charCodeAt(0); 1519 if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) { 1520 const keyword = textToKeyword.get(tokenValue); 1521 if (keyword !== undefined) { 1522 return token = keyword; 1523 } 1524 } 1525 } 1526 return token = SyntaxKind.Identifier; 1527 } 1528 1529 function scanBinaryOrOctalDigits(base: 2 | 8): string { 1530 let value = ""; 1531 // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b. 1532 // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O. 1533 let separatorAllowed = false; 1534 let isPreviousTokenSeparator = false; 1535 while (true) { 1536 const ch = text.charCodeAt(pos); 1537 // Numeric separators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator 1538 if (ch === CharacterCodes._) { 1539 tokenFlags |= TokenFlags.ContainsSeparator; 1540 if (separatorAllowed) { 1541 separatorAllowed = false; 1542 isPreviousTokenSeparator = true; 1543 } 1544 else if (isPreviousTokenSeparator) { 1545 error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1); 1546 } 1547 else { 1548 error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1); 1549 } 1550 pos++; 1551 continue; 1552 } 1553 separatorAllowed = true; 1554 if (!isDigit(ch) || ch - CharacterCodes._0 >= base) { 1555 break; 1556 } 1557 value += text[pos]; 1558 pos++; 1559 isPreviousTokenSeparator = false; 1560 } 1561 if (text.charCodeAt(pos - 1) === CharacterCodes._) { 1562 // Literal ends with underscore - not allowed 1563 error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1); 1564 } 1565 return value; 1566 } 1567 1568 function checkBigIntSuffix(): SyntaxKind { 1569 if (text.charCodeAt(pos) === CharacterCodes.n) { 1570 tokenValue += "n"; 1571 // Use base 10 instead of base 2 or base 8 for shorter literals 1572 if (tokenFlags & TokenFlags.BinaryOrOctalSpecifier) { 1573 tokenValue = parsePseudoBigInt(tokenValue) + "n"; 1574 } 1575 pos++; 1576 return SyntaxKind.BigIntLiteral; 1577 } 1578 else { // not a bigint, so can convert to number in simplified form 1579 // Number() may not support 0b or 0o, so use parseInt() instead 1580 const numericValue = tokenFlags & TokenFlags.BinarySpecifier 1581 ? parseInt(tokenValue.slice(2), 2) // skip "0b" 1582 : tokenFlags & TokenFlags.OctalSpecifier 1583 ? parseInt(tokenValue.slice(2), 8) // skip "0o" 1584 : +tokenValue; 1585 tokenValue = "" + numericValue; 1586 return SyntaxKind.NumericLiteral; 1587 } 1588 } 1589 1590 function scan(): SyntaxKind { 1591 startPos = pos; 1592 tokenFlags = TokenFlags.None; 1593 let asteriskSeen = false; 1594 while (true) { 1595 tokenPos = pos; 1596 if (pos >= end) { 1597 return token = SyntaxKind.EndOfFileToken; 1598 } 1599 let ch = codePointAt(text, pos); 1600 1601 // Special handling for shebang 1602 if (ch === CharacterCodes.hash && pos === 0 && isShebangTrivia(text, pos)) { 1603 pos = scanShebangTrivia(text, pos); 1604 if (skipTrivia) { 1605 continue; 1606 } 1607 else { 1608 return token = SyntaxKind.ShebangTrivia; 1609 } 1610 } 1611 1612 switch (ch) { 1613 case CharacterCodes.lineFeed: 1614 case CharacterCodes.carriageReturn: 1615 tokenFlags |= TokenFlags.PrecedingLineBreak; 1616 if (skipTrivia) { 1617 pos++; 1618 continue; 1619 } 1620 else { 1621 if (ch === CharacterCodes.carriageReturn && pos + 1 < end && text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) { 1622 // consume both CR and LF 1623 pos += 2; 1624 } 1625 else { 1626 pos++; 1627 } 1628 return token = SyntaxKind.NewLineTrivia; 1629 } 1630 case CharacterCodes.tab: 1631 case CharacterCodes.verticalTab: 1632 case CharacterCodes.formFeed: 1633 case CharacterCodes.space: 1634 case CharacterCodes.nonBreakingSpace: 1635 case CharacterCodes.ogham: 1636 case CharacterCodes.enQuad: 1637 case CharacterCodes.emQuad: 1638 case CharacterCodes.enSpace: 1639 case CharacterCodes.emSpace: 1640 case CharacterCodes.threePerEmSpace: 1641 case CharacterCodes.fourPerEmSpace: 1642 case CharacterCodes.sixPerEmSpace: 1643 case CharacterCodes.figureSpace: 1644 case CharacterCodes.punctuationSpace: 1645 case CharacterCodes.thinSpace: 1646 case CharacterCodes.hairSpace: 1647 case CharacterCodes.zeroWidthSpace: 1648 case CharacterCodes.narrowNoBreakSpace: 1649 case CharacterCodes.mathematicalSpace: 1650 case CharacterCodes.ideographicSpace: 1651 case CharacterCodes.byteOrderMark: 1652 if (skipTrivia) { 1653 pos++; 1654 continue; 1655 } 1656 else { 1657 while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { 1658 pos++; 1659 } 1660 return token = SyntaxKind.WhitespaceTrivia; 1661 } 1662 case CharacterCodes.exclamation: 1663 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1664 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1665 return pos += 3, token = SyntaxKind.ExclamationEqualsEqualsToken; 1666 } 1667 return pos += 2, token = SyntaxKind.ExclamationEqualsToken; 1668 } 1669 pos++; 1670 return token = SyntaxKind.ExclamationToken; 1671 case CharacterCodes.doubleQuote: 1672 case CharacterCodes.singleQuote: 1673 tokenValue = scanString(); 1674 return token = SyntaxKind.StringLiteral; 1675 case CharacterCodes.backtick: 1676 return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ false); 1677 case CharacterCodes.percent: 1678 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1679 return pos += 2, token = SyntaxKind.PercentEqualsToken; 1680 } 1681 pos++; 1682 return token = SyntaxKind.PercentToken; 1683 case CharacterCodes.ampersand: 1684 if (text.charCodeAt(pos + 1) === CharacterCodes.ampersand) { 1685 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1686 return pos += 3, token = SyntaxKind.AmpersandAmpersandEqualsToken; 1687 } 1688 return pos += 2, token = SyntaxKind.AmpersandAmpersandToken; 1689 } 1690 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1691 return pos += 2, token = SyntaxKind.AmpersandEqualsToken; 1692 } 1693 pos++; 1694 return token = SyntaxKind.AmpersandToken; 1695 case CharacterCodes.openParen: 1696 pos++; 1697 return token = SyntaxKind.OpenParenToken; 1698 case CharacterCodes.closeParen: 1699 pos++; 1700 return token = SyntaxKind.CloseParenToken; 1701 case CharacterCodes.asterisk: 1702 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1703 return pos += 2, token = SyntaxKind.AsteriskEqualsToken; 1704 } 1705 if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { 1706 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1707 return pos += 3, token = SyntaxKind.AsteriskAsteriskEqualsToken; 1708 } 1709 return pos += 2, token = SyntaxKind.AsteriskAsteriskToken; 1710 } 1711 pos++; 1712 if (inJSDocType && !asteriskSeen && (tokenFlags & TokenFlags.PrecedingLineBreak)) { 1713 // decoration at the start of a JSDoc comment line 1714 asteriskSeen = true; 1715 continue; 1716 } 1717 return token = SyntaxKind.AsteriskToken; 1718 case CharacterCodes.plus: 1719 if (text.charCodeAt(pos + 1) === CharacterCodes.plus) { 1720 return pos += 2, token = SyntaxKind.PlusPlusToken; 1721 } 1722 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1723 return pos += 2, token = SyntaxKind.PlusEqualsToken; 1724 } 1725 pos++; 1726 return token = SyntaxKind.PlusToken; 1727 case CharacterCodes.comma: 1728 pos++; 1729 return token = SyntaxKind.CommaToken; 1730 case CharacterCodes.minus: 1731 if (text.charCodeAt(pos + 1) === CharacterCodes.minus) { 1732 return pos += 2, token = SyntaxKind.MinusMinusToken; 1733 } 1734 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1735 return pos += 2, token = SyntaxKind.MinusEqualsToken; 1736 } 1737 pos++; 1738 return token = SyntaxKind.MinusToken; 1739 case CharacterCodes.dot: 1740 if (isDigit(text.charCodeAt(pos + 1))) { 1741 tokenValue = scanNumber().value; 1742 return token = SyntaxKind.NumericLiteral; 1743 } 1744 if (text.charCodeAt(pos + 1) === CharacterCodes.dot && text.charCodeAt(pos + 2) === CharacterCodes.dot) { 1745 return pos += 3, token = SyntaxKind.DotDotDotToken; 1746 } 1747 pos++; 1748 return token = SyntaxKind.DotToken; 1749 case CharacterCodes.slash: 1750 // Single-line comment 1751 if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { 1752 pos += 2; 1753 1754 while (pos < end) { 1755 if (isLineBreak(text.charCodeAt(pos))) { 1756 break; 1757 } 1758 pos++; 1759 } 1760 1761 commentDirectives = appendIfCommentDirective( 1762 commentDirectives, 1763 text.slice(tokenPos, pos), 1764 commentDirectiveRegExSingleLine, 1765 tokenPos, 1766 ); 1767 1768 if (skipTrivia) { 1769 continue; 1770 } 1771 else { 1772 return token = SyntaxKind.SingleLineCommentTrivia; 1773 } 1774 } 1775 // Multi-line comment 1776 if (text.charCodeAt(pos + 1) === CharacterCodes.asterisk) { 1777 pos += 2; 1778 if (text.charCodeAt(pos) === CharacterCodes.asterisk && text.charCodeAt(pos + 1) !== CharacterCodes.slash) { 1779 tokenFlags |= TokenFlags.PrecedingJSDocComment; 1780 } 1781 1782 let commentClosed = false; 1783 let lastLineStart = tokenPos; 1784 while (pos < end) { 1785 const ch = text.charCodeAt(pos); 1786 1787 if (ch === CharacterCodes.asterisk && text.charCodeAt(pos + 1) === CharacterCodes.slash) { 1788 pos += 2; 1789 commentClosed = true; 1790 break; 1791 } 1792 1793 pos++; 1794 1795 if (isLineBreak(ch)) { 1796 lastLineStart = pos; 1797 tokenFlags |= TokenFlags.PrecedingLineBreak; 1798 } 1799 } 1800 1801 commentDirectives = appendIfCommentDirective(commentDirectives, text.slice(lastLineStart, pos), commentDirectiveRegExMultiLine, lastLineStart); 1802 1803 if (!commentClosed) { 1804 error(Diagnostics.Asterisk_Slash_expected); 1805 } 1806 1807 if (skipTrivia) { 1808 continue; 1809 } 1810 else { 1811 if (!commentClosed) { 1812 tokenFlags |= TokenFlags.Unterminated; 1813 } 1814 return token = SyntaxKind.MultiLineCommentTrivia; 1815 } 1816 } 1817 1818 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1819 return pos += 2, token = SyntaxKind.SlashEqualsToken; 1820 } 1821 1822 pos++; 1823 return token = SyntaxKind.SlashToken; 1824 1825 case CharacterCodes._0: 1826 if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.X || text.charCodeAt(pos + 1) === CharacterCodes.x)) { 1827 pos += 2; 1828 tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true); 1829 if (!tokenValue) { 1830 error(Diagnostics.Hexadecimal_digit_expected); 1831 tokenValue = "0"; 1832 } 1833 tokenValue = "0x" + tokenValue; 1834 tokenFlags |= TokenFlags.HexSpecifier; 1835 return token = checkBigIntSuffix(); 1836 } 1837 else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.B || text.charCodeAt(pos + 1) === CharacterCodes.b)) { 1838 pos += 2; 1839 tokenValue = scanBinaryOrOctalDigits(/* base */ 2); 1840 if (!tokenValue) { 1841 error(Diagnostics.Binary_digit_expected); 1842 tokenValue = "0"; 1843 } 1844 tokenValue = "0b" + tokenValue; 1845 tokenFlags |= TokenFlags.BinarySpecifier; 1846 return token = checkBigIntSuffix(); 1847 } 1848 else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) { 1849 pos += 2; 1850 tokenValue = scanBinaryOrOctalDigits(/* base */ 8); 1851 if (!tokenValue) { 1852 error(Diagnostics.Octal_digit_expected); 1853 tokenValue = "0"; 1854 } 1855 tokenValue = "0o" + tokenValue; 1856 tokenFlags |= TokenFlags.OctalSpecifier; 1857 return token = checkBigIntSuffix(); 1858 } 1859 // Try to parse as an octal 1860 if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) { 1861 tokenValue = "" + scanOctalDigits(); 1862 tokenFlags |= TokenFlags.Octal; 1863 return token = SyntaxKind.NumericLiteral; 1864 } 1865 // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero 1866 // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being 1867 // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do). 1868 // falls through 1869 case CharacterCodes._1: 1870 case CharacterCodes._2: 1871 case CharacterCodes._3: 1872 case CharacterCodes._4: 1873 case CharacterCodes._5: 1874 case CharacterCodes._6: 1875 case CharacterCodes._7: 1876 case CharacterCodes._8: 1877 case CharacterCodes._9: 1878 ({ type: token, value: tokenValue } = scanNumber()); 1879 return token; 1880 case CharacterCodes.colon: 1881 pos++; 1882 return token = SyntaxKind.ColonToken; 1883 case CharacterCodes.semicolon: 1884 pos++; 1885 return token = SyntaxKind.SemicolonToken; 1886 case CharacterCodes.lessThan: 1887 if (isConflictMarkerTrivia(text, pos)) { 1888 pos = scanConflictMarkerTrivia(text, pos, error); 1889 if (skipTrivia) { 1890 continue; 1891 } 1892 else { 1893 return token = SyntaxKind.ConflictMarkerTrivia; 1894 } 1895 } 1896 1897 if (text.charCodeAt(pos + 1) === CharacterCodes.lessThan) { 1898 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1899 return pos += 3, token = SyntaxKind.LessThanLessThanEqualsToken; 1900 } 1901 return pos += 2, token = SyntaxKind.LessThanLessThanToken; 1902 } 1903 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1904 return pos += 2, token = SyntaxKind.LessThanEqualsToken; 1905 } 1906 if (languageVariant === LanguageVariant.JSX && 1907 text.charCodeAt(pos + 1) === CharacterCodes.slash && 1908 text.charCodeAt(pos + 2) !== CharacterCodes.asterisk) { 1909 return pos += 2, token = SyntaxKind.LessThanSlashToken; 1910 } 1911 pos++; 1912 return token = SyntaxKind.LessThanToken; 1913 case CharacterCodes.equals: 1914 if (isConflictMarkerTrivia(text, pos)) { 1915 pos = scanConflictMarkerTrivia(text, pos, error); 1916 if (skipTrivia) { 1917 continue; 1918 } 1919 else { 1920 return token = SyntaxKind.ConflictMarkerTrivia; 1921 } 1922 } 1923 1924 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1925 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1926 return pos += 3, token = SyntaxKind.EqualsEqualsEqualsToken; 1927 } 1928 return pos += 2, token = SyntaxKind.EqualsEqualsToken; 1929 } 1930 if (text.charCodeAt(pos + 1) === CharacterCodes.greaterThan) { 1931 return pos += 2, token = SyntaxKind.EqualsGreaterThanToken; 1932 } 1933 pos++; 1934 return token = SyntaxKind.EqualsToken; 1935 case CharacterCodes.greaterThan: 1936 if (isConflictMarkerTrivia(text, pos)) { 1937 pos = scanConflictMarkerTrivia(text, pos, error); 1938 if (skipTrivia) { 1939 continue; 1940 } 1941 else { 1942 return token = SyntaxKind.ConflictMarkerTrivia; 1943 } 1944 } 1945 1946 pos++; 1947 return token = SyntaxKind.GreaterThanToken; 1948 case CharacterCodes.question: 1949 if (text.charCodeAt(pos + 1) === CharacterCodes.dot && !isDigit(text.charCodeAt(pos + 2))) { 1950 return pos += 2, token = SyntaxKind.QuestionDotToken; 1951 } 1952 if (text.charCodeAt(pos + 1) === CharacterCodes.question) { 1953 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1954 return pos += 3, token = SyntaxKind.QuestionQuestionEqualsToken; 1955 } 1956 return pos += 2, token = SyntaxKind.QuestionQuestionToken; 1957 } 1958 pos++; 1959 return token = SyntaxKind.QuestionToken; 1960 case CharacterCodes.openBracket: 1961 pos++; 1962 return token = SyntaxKind.OpenBracketToken; 1963 case CharacterCodes.closeBracket: 1964 pos++; 1965 return token = SyntaxKind.CloseBracketToken; 1966 case CharacterCodes.caret: 1967 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1968 return pos += 2, token = SyntaxKind.CaretEqualsToken; 1969 } 1970 pos++; 1971 return token = SyntaxKind.CaretToken; 1972 case CharacterCodes.openBrace: 1973 pos++; 1974 return token = SyntaxKind.OpenBraceToken; 1975 case CharacterCodes.bar: 1976 if (isConflictMarkerTrivia(text, pos)) { 1977 pos = scanConflictMarkerTrivia(text, pos, error); 1978 if (skipTrivia) { 1979 continue; 1980 } 1981 else { 1982 return token = SyntaxKind.ConflictMarkerTrivia; 1983 } 1984 } 1985 1986 if (text.charCodeAt(pos + 1) === CharacterCodes.bar) { 1987 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 1988 return pos += 3, token = SyntaxKind.BarBarEqualsToken; 1989 } 1990 return pos += 2, token = SyntaxKind.BarBarToken; 1991 } 1992 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 1993 return pos += 2, token = SyntaxKind.BarEqualsToken; 1994 } 1995 pos++; 1996 return token = SyntaxKind.BarToken; 1997 case CharacterCodes.closeBrace: 1998 pos++; 1999 return token = SyntaxKind.CloseBraceToken; 2000 case CharacterCodes.tilde: 2001 pos++; 2002 return token = SyntaxKind.TildeToken; 2003 case CharacterCodes.at: 2004 pos++; 2005 return token = SyntaxKind.AtToken; 2006 case CharacterCodes.backslash: 2007 const extendedCookedChar = peekExtendedUnicodeEscape(); 2008 if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) { 2009 pos += 3; 2010 tokenFlags |= TokenFlags.ExtendedUnicodeEscape; 2011 tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts(); 2012 return token = getIdentifierToken(); 2013 } 2014 2015 const cookedChar = peekUnicodeEscape(); 2016 if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { 2017 pos += 6; 2018 tokenFlags |= TokenFlags.UnicodeEscape; 2019 tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); 2020 return token = getIdentifierToken(); 2021 } 2022 2023 error(Diagnostics.Invalid_character); 2024 pos++; 2025 return token = SyntaxKind.Unknown; 2026 case CharacterCodes.hash: 2027 if (pos !== 0 && text[pos + 1] === "!") { 2028 error(Diagnostics.can_only_be_used_at_the_start_of_a_file); 2029 pos++; 2030 return token = SyntaxKind.Unknown; 2031 } 2032 pos++; 2033 if (isIdentifierStart(ch = text.charCodeAt(pos), languageVersion)) { 2034 pos++; 2035 while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion)) pos++; 2036 tokenValue = text.substring(tokenPos, pos); 2037 if (ch === CharacterCodes.backslash) { 2038 tokenValue += scanIdentifierParts(); 2039 } 2040 } 2041 else { 2042 tokenValue = "#"; 2043 error(Diagnostics.Invalid_character); 2044 } 2045 return token = SyntaxKind.PrivateIdentifier; 2046 default: 2047 const identifierKind = scanIdentifier(ch, languageVersion); 2048 if (identifierKind) { 2049 return token = identifierKind; 2050 } 2051 else if (isWhiteSpaceSingleLine(ch)) { 2052 pos += charSize(ch); 2053 continue; 2054 } 2055 else if (isLineBreak(ch)) { 2056 tokenFlags |= TokenFlags.PrecedingLineBreak; 2057 pos += charSize(ch); 2058 continue; 2059 } 2060 error(Diagnostics.Invalid_character); 2061 pos += charSize(ch); 2062 return token = SyntaxKind.Unknown; 2063 } 2064 } 2065 } 2066 2067 function reScanInvalidIdentifier(): SyntaxKind { 2068 Debug.assert(token === SyntaxKind.Unknown, "'reScanInvalidIdentifier' should only be called when the current token is 'SyntaxKind.Unknown'."); 2069 pos = tokenPos = startPos; 2070 tokenFlags = 0; 2071 const ch = codePointAt(text, pos); 2072 const identifierKind = scanIdentifier(ch, ScriptTarget.ESNext); 2073 if (identifierKind) { 2074 return token = identifierKind; 2075 } 2076 pos += charSize(ch); 2077 return token; // Still `SyntaKind.Unknown` 2078 } 2079 2080 function scanIdentifier(startCharacter: number, languageVersion: ScriptTarget) { 2081 let ch = startCharacter; 2082 if (isIdentifierStart(ch, languageVersion)) { 2083 pos += charSize(ch); 2084 while (pos < end && isIdentifierPart(ch = codePointAt(text, pos), languageVersion)) pos += charSize(ch); 2085 tokenValue = text.substring(tokenPos, pos); 2086 if (ch === CharacterCodes.backslash) { 2087 tokenValue += scanIdentifierParts(); 2088 } 2089 return getIdentifierToken(); 2090 } 2091 } 2092 2093 function reScanGreaterToken(): SyntaxKind { 2094 if (token === SyntaxKind.GreaterThanToken) { 2095 if (text.charCodeAt(pos) === CharacterCodes.greaterThan) { 2096 if (text.charCodeAt(pos + 1) === CharacterCodes.greaterThan) { 2097 if (text.charCodeAt(pos + 2) === CharacterCodes.equals) { 2098 return pos += 3, token = SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken; 2099 } 2100 return pos += 2, token = SyntaxKind.GreaterThanGreaterThanGreaterThanToken; 2101 } 2102 if (text.charCodeAt(pos + 1) === CharacterCodes.equals) { 2103 return pos += 2, token = SyntaxKind.GreaterThanGreaterThanEqualsToken; 2104 } 2105 pos++; 2106 return token = SyntaxKind.GreaterThanGreaterThanToken; 2107 } 2108 if (text.charCodeAt(pos) === CharacterCodes.equals) { 2109 pos++; 2110 return token = SyntaxKind.GreaterThanEqualsToken; 2111 } 2112 } 2113 return token; 2114 } 2115 2116 function reScanAsteriskEqualsToken(): SyntaxKind { 2117 Debug.assert(token === SyntaxKind.AsteriskEqualsToken, "'reScanAsteriskEqualsToken' should only be called on a '*='"); 2118 pos = tokenPos + 1; 2119 return token = SyntaxKind.EqualsToken; 2120 } 2121 2122 function reScanSlashToken(): SyntaxKind { 2123 if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) { 2124 let p = tokenPos + 1; 2125 let inEscape = false; 2126 let inCharacterClass = false; 2127 while (true) { 2128 // If we reach the end of a file, or hit a newline, then this is an unterminated 2129 // regex. Report error and return what we have so far. 2130 if (p >= end) { 2131 tokenFlags |= TokenFlags.Unterminated; 2132 error(Diagnostics.Unterminated_regular_expression_literal); 2133 break; 2134 } 2135 2136 const ch = text.charCodeAt(p); 2137 if (isLineBreak(ch)) { 2138 tokenFlags |= TokenFlags.Unterminated; 2139 error(Diagnostics.Unterminated_regular_expression_literal); 2140 break; 2141 } 2142 2143 if (inEscape) { 2144 // Parsing an escape character; 2145 // reset the flag and just advance to the next char. 2146 inEscape = false; 2147 } 2148 else if (ch === CharacterCodes.slash && !inCharacterClass) { 2149 // A slash within a character class is permissible, 2150 // but in general it signals the end of the regexp literal. 2151 p++; 2152 break; 2153 } 2154 else if (ch === CharacterCodes.openBracket) { 2155 inCharacterClass = true; 2156 } 2157 else if (ch === CharacterCodes.backslash) { 2158 inEscape = true; 2159 } 2160 else if (ch === CharacterCodes.closeBracket) { 2161 inCharacterClass = false; 2162 } 2163 p++; 2164 } 2165 2166 while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) { 2167 p++; 2168 } 2169 pos = p; 2170 tokenValue = text.substring(tokenPos, pos); 2171 token = SyntaxKind.RegularExpressionLiteral; 2172 } 2173 return token; 2174 } 2175 2176 function appendIfCommentDirective( 2177 commentDirectives: CommentDirective[] | undefined, 2178 text: string, 2179 commentDirectiveRegEx: RegExp, 2180 lineStart: number, 2181 ) { 2182 const type = getDirectiveFromComment(text, commentDirectiveRegEx); 2183 if (type === undefined) { 2184 return commentDirectives; 2185 } 2186 2187 return append( 2188 commentDirectives, 2189 { 2190 range: { pos: lineStart, end: pos }, 2191 type, 2192 }, 2193 ); 2194 } 2195 2196 function getDirectiveFromComment(text: string, commentDirectiveRegEx: RegExp) { 2197 const match = commentDirectiveRegEx.exec(text); 2198 if (!match) { 2199 return undefined; 2200 } 2201 2202 switch (match[1]) { 2203 case "ts-expect-error": 2204 return CommentDirectiveType.ExpectError; 2205 2206 case "ts-ignore": 2207 return CommentDirectiveType.Ignore; 2208 } 2209 2210 return undefined; 2211 } 2212 2213 /** 2214 * Unconditionally back up and scan a template expression portion. 2215 */ 2216 function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind { 2217 Debug.assert(token === SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'"); 2218 pos = tokenPos; 2219 return token = scanTemplateAndSetTokenValue(isTaggedTemplate); 2220 } 2221 2222 function reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind { 2223 pos = tokenPos; 2224 return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ true); 2225 } 2226 2227 function reScanJsxToken(): JsxTokenSyntaxKind { 2228 pos = tokenPos = startPos; 2229 return token = scanJsxToken(); 2230 } 2231 2232 function reScanLessThanToken(): SyntaxKind { 2233 if (token === SyntaxKind.LessThanLessThanToken) { 2234 pos = tokenPos + 1; 2235 return token = SyntaxKind.LessThanToken; 2236 } 2237 return token; 2238 } 2239 2240 function reScanQuestionToken(): SyntaxKind { 2241 Debug.assert(token === SyntaxKind.QuestionQuestionToken, "'reScanQuestionToken' should only be called on a '??'"); 2242 pos = tokenPos + 1; 2243 return token = SyntaxKind.QuestionToken; 2244 } 2245 2246 function scanJsxToken(): JsxTokenSyntaxKind { 2247 startPos = tokenPos = pos; 2248 2249 if (pos >= end) { 2250 return token = SyntaxKind.EndOfFileToken; 2251 } 2252 2253 let char = text.charCodeAt(pos); 2254 if (char === CharacterCodes.lessThan) { 2255 if (text.charCodeAt(pos + 1) === CharacterCodes.slash) { 2256 pos += 2; 2257 return token = SyntaxKind.LessThanSlashToken; 2258 } 2259 pos++; 2260 return token = SyntaxKind.LessThanToken; 2261 } 2262 2263 if (char === CharacterCodes.openBrace) { 2264 pos++; 2265 return token = SyntaxKind.OpenBraceToken; 2266 } 2267 2268 // First non-whitespace character on this line. 2269 let firstNonWhitespace = 0; 2270 let lastNonWhitespace = -1; 2271 2272 // These initial values are special because the first line is: 2273 // firstNonWhitespace = 0 to indicate that we want leading whitespace, 2274 2275 while (pos < end) { 2276 2277 // We want to keep track of the last non-whitespace (but including 2278 // newlines character for hitting the end of the JSX Text region) 2279 if (!isWhiteSpaceSingleLine(char)) { 2280 lastNonWhitespace = pos; 2281 } 2282 2283 char = text.charCodeAt(pos); 2284 if (char === CharacterCodes.openBrace) { 2285 break; 2286 } 2287 if (char === CharacterCodes.lessThan) { 2288 if (isConflictMarkerTrivia(text, pos)) { 2289 pos = scanConflictMarkerTrivia(text, pos, error); 2290 return token = SyntaxKind.ConflictMarkerTrivia; 2291 } 2292 break; 2293 } 2294 if (char === CharacterCodes.greaterThan) { 2295 error(Diagnostics.Unexpected_token_Did_you_mean_or_gt, pos, 1); 2296 } 2297 if (char === CharacterCodes.closeBrace) { 2298 error(Diagnostics.Unexpected_token_Did_you_mean_or_rbrace, pos, 1); 2299 } 2300 2301 if (lastNonWhitespace > 0) lastNonWhitespace++; 2302 2303 // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces. 2304 // i.e (- : whitespace) 2305 // <div>---- 2306 // </div> becomes <div></div> 2307 // 2308 // <div>----</div> becomes <div>----</div> 2309 if (isLineBreak(char) && firstNonWhitespace === 0) { 2310 firstNonWhitespace = -1; 2311 } 2312 else if (!isWhiteSpaceLike(char)) { 2313 firstNonWhitespace = pos; 2314 } 2315 2316 pos++; 2317 } 2318 2319 const endPosition = lastNonWhitespace === -1 ? pos : lastNonWhitespace; 2320 tokenValue = text.substring(startPos, endPosition); 2321 2322 return firstNonWhitespace === -1 ? SyntaxKind.JsxTextAllWhiteSpaces : SyntaxKind.JsxText; 2323 } 2324 2325 // Scans a JSX identifier; these differ from normal identifiers in that 2326 // they allow dashes 2327 function scanJsxIdentifier(): SyntaxKind { 2328 if (tokenIsIdentifierOrKeyword(token)) { 2329 // An identifier or keyword has already been parsed - check for a `-` or a single instance of `:` and then append it and 2330 // everything after it to the token 2331 // Do note that this means that `scanJsxIdentifier` effectively _mutates_ the visible token without advancing to a new token 2332 // Any caller should be expecting this behavior and should only read the pos or token value after calling it. 2333 let namespaceSeparator = false; 2334 while (pos < end) { 2335 const ch = text.charCodeAt(pos); 2336 if (ch === CharacterCodes.minus) { 2337 tokenValue += "-"; 2338 pos++; 2339 continue; 2340 } 2341 else if (ch === CharacterCodes.colon && !namespaceSeparator) { 2342 tokenValue += ":"; 2343 pos++; 2344 namespaceSeparator = true; 2345 continue; 2346 } 2347 const oldPos = pos; 2348 tokenValue += scanIdentifierParts(); // reuse `scanIdentifierParts` so unicode escapes are handled 2349 if (pos === oldPos) { 2350 break; 2351 } 2352 } 2353 // Do not include a trailing namespace separator in the token, since this is against the spec. 2354 if (tokenValue.slice(-1) === ":") { 2355 tokenValue = tokenValue.slice(0, -1); 2356 pos--; 2357 } 2358 } 2359 return token; 2360 } 2361 2362 function scanJsxAttributeValue(): SyntaxKind { 2363 startPos = pos; 2364 2365 switch (text.charCodeAt(pos)) { 2366 case CharacterCodes.doubleQuote: 2367 case CharacterCodes.singleQuote: 2368 tokenValue = scanString(/*jsxAttributeString*/ true); 2369 return token = SyntaxKind.StringLiteral; 2370 default: 2371 // If this scans anything other than `{`, it's a parse error. 2372 return scan(); 2373 } 2374 } 2375 2376 function reScanJsxAttributeValue(): SyntaxKind { 2377 pos = tokenPos = startPos; 2378 return scanJsxAttributeValue(); 2379 } 2380 2381 function scanJsDocToken(): JSDocSyntaxKind { 2382 startPos = tokenPos = pos; 2383 tokenFlags = TokenFlags.None; 2384 if (pos >= end) { 2385 return token = SyntaxKind.EndOfFileToken; 2386 } 2387 2388 const ch = codePointAt(text, pos); 2389 pos += charSize(ch); 2390 switch (ch) { 2391 case CharacterCodes.tab: 2392 case CharacterCodes.verticalTab: 2393 case CharacterCodes.formFeed: 2394 case CharacterCodes.space: 2395 while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { 2396 pos++; 2397 } 2398 return token = SyntaxKind.WhitespaceTrivia; 2399 case CharacterCodes.at: 2400 return token = SyntaxKind.AtToken; 2401 case CharacterCodes.carriageReturn: 2402 if (text.charCodeAt(pos) === CharacterCodes.lineFeed) { 2403 pos++; 2404 } 2405 // falls through 2406 case CharacterCodes.lineFeed: 2407 tokenFlags |= TokenFlags.PrecedingLineBreak; 2408 return token = SyntaxKind.NewLineTrivia; 2409 case CharacterCodes.asterisk: 2410 return token = SyntaxKind.AsteriskToken; 2411 case CharacterCodes.openBrace: 2412 return token = SyntaxKind.OpenBraceToken; 2413 case CharacterCodes.closeBrace: 2414 return token = SyntaxKind.CloseBraceToken; 2415 case CharacterCodes.openBracket: 2416 return token = SyntaxKind.OpenBracketToken; 2417 case CharacterCodes.closeBracket: 2418 return token = SyntaxKind.CloseBracketToken; 2419 case CharacterCodes.lessThan: 2420 return token = SyntaxKind.LessThanToken; 2421 case CharacterCodes.greaterThan: 2422 return token = SyntaxKind.GreaterThanToken; 2423 case CharacterCodes.equals: 2424 return token = SyntaxKind.EqualsToken; 2425 case CharacterCodes.comma: 2426 return token = SyntaxKind.CommaToken; 2427 case CharacterCodes.dot: 2428 return token = SyntaxKind.DotToken; 2429 case CharacterCodes.backtick: 2430 return token = SyntaxKind.BacktickToken; 2431 case CharacterCodes.backslash: 2432 pos--; 2433 const extendedCookedChar = peekExtendedUnicodeEscape(); 2434 if (extendedCookedChar >= 0 && isIdentifierStart(extendedCookedChar, languageVersion)) { 2435 pos += 3; 2436 tokenFlags |= TokenFlags.ExtendedUnicodeEscape; 2437 tokenValue = scanExtendedUnicodeEscape() + scanIdentifierParts(); 2438 return token = getIdentifierToken(); 2439 } 2440 2441 const cookedChar = peekUnicodeEscape(); 2442 if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { 2443 pos += 6; 2444 tokenFlags |= TokenFlags.UnicodeEscape; 2445 tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); 2446 return token = getIdentifierToken(); 2447 } 2448 pos++; 2449 return token = SyntaxKind.Unknown; 2450 } 2451 2452 if (isIdentifierStart(ch, languageVersion)) { 2453 let char = ch; 2454 while (pos < end && isIdentifierPart(char = codePointAt(text, pos), languageVersion) || text.charCodeAt(pos) === CharacterCodes.minus) pos += charSize(char); 2455 tokenValue = text.substring(tokenPos, pos); 2456 if (char === CharacterCodes.backslash) { 2457 tokenValue += scanIdentifierParts(); 2458 } 2459 return token = getIdentifierToken(); 2460 } 2461 else { 2462 return token = SyntaxKind.Unknown; 2463 } 2464 } 2465 2466 function speculationHelper<T>(callback: () => T, isLookahead: boolean): T { 2467 const savePos = pos; 2468 const saveStartPos = startPos; 2469 const saveTokenPos = tokenPos; 2470 const saveToken = token; 2471 const saveTokenValue = tokenValue; 2472 const saveTokenFlags = tokenFlags; 2473 const result = callback(); 2474 2475 // If our callback returned something 'falsy' or we're just looking ahead, 2476 // then unconditionally restore us to where we were. 2477 if (!result || isLookahead) { 2478 pos = savePos; 2479 startPos = saveStartPos; 2480 tokenPos = saveTokenPos; 2481 token = saveToken; 2482 tokenValue = saveTokenValue; 2483 tokenFlags = saveTokenFlags; 2484 } 2485 return result; 2486 } 2487 2488 function scanRange<T>(start: number, length: number, callback: () => T): T { 2489 const saveEnd = end; 2490 const savePos = pos; 2491 const saveStartPos = startPos; 2492 const saveTokenPos = tokenPos; 2493 const saveToken = token; 2494 const saveTokenValue = tokenValue; 2495 const saveTokenFlags = tokenFlags; 2496 const saveErrorExpectations = commentDirectives; 2497 2498 setText(text, start, length); 2499 const result = callback(); 2500 2501 end = saveEnd; 2502 pos = savePos; 2503 startPos = saveStartPos; 2504 tokenPos = saveTokenPos; 2505 token = saveToken; 2506 tokenValue = saveTokenValue; 2507 tokenFlags = saveTokenFlags; 2508 commentDirectives = saveErrorExpectations; 2509 2510 return result; 2511 } 2512 2513 function lookAhead<T>(callback: () => T): T { 2514 return speculationHelper(callback, /*isLookahead*/ true); 2515 } 2516 2517 function tryScan<T>(callback: () => T): T { 2518 return speculationHelper(callback, /*isLookahead*/ false); 2519 } 2520 2521 function getText(): string { 2522 return text; 2523 } 2524 2525 function clearCommentDirectives() { 2526 commentDirectives = undefined; 2527 } 2528 2529 function setText(newText: string | undefined, start: number | undefined, length: number | undefined) { 2530 text = newText || ""; 2531 end = length === undefined ? text.length : start! + length; 2532 setTextPos(start || 0); 2533 } 2534 2535 function setOnError(errorCallback: ErrorCallback | undefined) { 2536 onError = errorCallback; 2537 } 2538 2539 function setScriptTarget(scriptTarget: ScriptTarget) { 2540 languageVersion = scriptTarget; 2541 } 2542 2543 function setLanguageVariant(variant: LanguageVariant) { 2544 languageVariant = variant; 2545 } 2546 2547 function setTextPos(textPos: number) { 2548 Debug.assert(textPos >= 0); 2549 pos = textPos; 2550 startPos = textPos; 2551 tokenPos = textPos; 2552 token = SyntaxKind.Unknown; 2553 tokenValue = undefined!; 2554 tokenFlags = TokenFlags.None; 2555 } 2556 2557 function setInJSDocType(inType: boolean) { 2558 inJSDocType += inType ? 1 : -1; 2559 } 2560 } 2561 2562 /* @internal */ 2563 const codePointAt: (s: string, i: number) => number = (String.prototype as any).codePointAt ? (s, i) => (s as any).codePointAt(i) : function codePointAt(str, i): number { 2564 // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt 2565 const size = str.length; 2566 // Account for out-of-bounds indices: 2567 if (i < 0 || i >= size) { 2568 return undefined!; // String.codePointAt returns `undefined` for OOB indexes 2569 } 2570 // Get the first code unit 2571 const first = str.charCodeAt(i); 2572 // check if it’s the start of a surrogate pair 2573 if (first >= 0xD800 && first <= 0xDBFF && size > i + 1) { // high surrogate and there is a next code unit 2574 const second = str.charCodeAt(i + 1); 2575 if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate 2576 // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae 2577 return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; 2578 } 2579 } 2580 return first; 2581 }; 2582 2583 /* @internal */ 2584 function charSize(ch: number) { 2585 if (ch >= 0x10000) { 2586 return 2; 2587 } 2588 return 1; 2589 } 2590 2591 // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec. 2592 function utf16EncodeAsStringFallback(codePoint: number) { 2593 Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); 2594 2595 if (codePoint <= 65535) { 2596 return String.fromCharCode(codePoint); 2597 } 2598 2599 const codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800; 2600 const codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00; 2601 2602 return String.fromCharCode(codeUnit1, codeUnit2); 2603 } 2604 2605 const utf16EncodeAsStringWorker: (codePoint: number) => string = (String as any).fromCodePoint ? codePoint => (String as any).fromCodePoint(codePoint) : utf16EncodeAsStringFallback; 2606 2607 /* @internal */ 2608 export function utf16EncodeAsString(codePoint: number) { 2609 return utf16EncodeAsStringWorker(codePoint); 2610 } 2611} 2612