diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 17586e927d0ac..94a7044c80d94 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1,8559 +1,8563 @@ -{ - "Unterminated string literal.": { - "category": "Error", - "code": 1002 - }, - "Identifier expected.": { - "category": "Error", - "code": 1003 - }, - "'{0}' expected.": { - "category": "Error", - "code": 1005 - }, - "A file cannot have a reference to itself.": { - "category": "Error", - "code": 1006 - }, - "The parser expected to find a '{1}' to match the '{0}' token here.": { - "category": "Error", - "code": 1007 - }, - "Trailing comma not allowed.": { - "category": "Error", - "code": 1009 - }, - "'*/' expected.": { - "category": "Error", - "code": 1010 - }, - "An element access expression should take an argument.": { - "category": "Error", - "code": 1011 - }, - "Unexpected token.": { - "category": "Error", - "code": 1012 - }, - "A rest parameter or binding pattern may not have a trailing comma.": { - "category": "Error", - "code": 1013 - }, - "A rest parameter must be last in a parameter list.": { - "category": "Error", - "code": 1014 - }, - "Parameter cannot have question mark and initializer.": { - "category": "Error", - "code": 1015 - }, - "A required parameter cannot follow an optional parameter.": { - "category": "Error", - "code": 1016 - }, - "An index signature cannot have a rest parameter.": { - "category": "Error", - "code": 1017 - }, - "An index signature parameter cannot have an accessibility modifier.": { - "category": "Error", - "code": 1018 - }, - "An index signature parameter cannot have a question mark.": { - "category": "Error", - "code": 1019 - }, - "An index signature parameter cannot have an initializer.": { - "category": "Error", - "code": 1020 - }, - "An index signature must have a type annotation.": { - "category": "Error", - "code": 1021 - }, - "An index signature parameter must have a type annotation.": { - "category": "Error", - "code": 1022 - }, - "'readonly' modifier can only appear on a property declaration or index signature.": { - "category": "Error", - "code": 1024 - }, - "An index signature cannot have a trailing comma.": { - "category": "Error", - "code": 1025 - }, - "Accessibility modifier already seen.": { - "category": "Error", - "code": 1028 - }, - "'{0}' modifier must precede '{1}' modifier.": { - "category": "Error", - "code": 1029 - }, - "'{0}' modifier already seen.": { - "category": "Error", - "code": 1030 - }, - "'{0}' modifier cannot appear on class elements of this kind.": { - "category": "Error", - "code": 1031 - }, - "'super' must be followed by an argument list or member access.": { - "category": "Error", - "code": 1034 - }, - "Only ambient modules can use quoted names.": { - "category": "Error", - "code": 1035 - }, - "Statements are not allowed in ambient contexts.": { - "category": "Error", - "code": 1036 - }, - "A 'declare' modifier cannot be used in an already ambient context.": { - "category": "Error", - "code": 1038 - }, - "Initializers are not allowed in ambient contexts.": { - "category": "Error", - "code": 1039 - }, - "'{0}' modifier cannot be used in an ambient context.": { - "category": "Error", - "code": 1040 - }, - "'{0}' modifier cannot be used here.": { - "category": "Error", - "code": 1042 - }, - "'{0}' modifier cannot appear on a module or namespace element.": { - "category": "Error", - "code": 1044 - }, - "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.": { - "category": "Error", - "code": 1046 - }, - "A rest parameter cannot be optional.": { - "category": "Error", - "code": 1047 - }, - "A rest parameter cannot have an initializer.": { - "category": "Error", - "code": 1048 - }, - "A 'set' accessor must have exactly one parameter.": { - "category": "Error", - "code": 1049 - }, - "A 'set' accessor cannot have an optional parameter.": { - "category": "Error", - "code": 1051 - }, - "A 'set' accessor parameter cannot have an initializer.": { - "category": "Error", - "code": 1052 - }, - "A 'set' accessor cannot have rest parameter.": { - "category": "Error", - "code": 1053 - }, - "A 'get' accessor cannot have parameters.": { - "category": "Error", - "code": 1054 - }, - "Type '{0}' is not a valid async function return type in ES5 because it does not refer to a Promise-compatible constructor value.": { - "category": "Error", - "code": 1055 - }, - "Accessors are only available when targeting ECMAScript 5 and higher.": { - "category": "Error", - "code": 1056 - }, - "The return type of an async function must either be a valid promise or must not contain a callable 'then' member.": { - "category": "Error", - "code": 1058 - }, - "A promise must have a 'then' method.": { - "category": "Error", - "code": 1059 - }, - "The first parameter of the 'then' method of a promise must be a callback.": { - "category": "Error", - "code": 1060 - }, - "Enum member must have initializer.": { - "category": "Error", - "code": 1061 - }, - "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": { - "category": "Error", - "code": 1062 - }, - "An export assignment cannot be used in a namespace.": { - "category": "Error", - "code": 1063 - }, - "The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise<{0}>'?": { - "category": "Error", - "code": 1064 - }, - "The return type of an async function or method must be the global Promise type.": { - "category": "Error", - "code": 1065 - }, - "In ambient enum declarations member initializer must be constant expression.": { - "category": "Error", - "code": 1066 - }, - "Unexpected token. A constructor, method, accessor, or property was expected.": { - "category": "Error", - "code": 1068 - }, - "Unexpected token. A type parameter name was expected without curly braces.": { - "category": "Error", - "code": 1069 - }, - "'{0}' modifier cannot appear on a type member.": { - "category": "Error", - "code": 1070 - }, - "'{0}' modifier cannot appear on an index signature.": { - "category": "Error", - "code": 1071 - }, - "A '{0}' modifier cannot be used with an import declaration.": { - "category": "Error", - "code": 1079 - }, - "Invalid 'reference' directive syntax.": { - "category": "Error", - "code": 1084 - }, - "'{0}' modifier cannot appear on a constructor declaration.": { - "category": "Error", - "code": 1089 - }, - "'{0}' modifier cannot appear on a parameter.": { - "category": "Error", - "code": 1090 - }, - "Only a single variable declaration is allowed in a 'for...in' statement.": { - "category": "Error", - "code": 1091 - }, - "Type parameters cannot appear on a constructor declaration.": { - "category": "Error", - "code": 1092 - }, - "Type annotation cannot appear on a constructor declaration.": { - "category": "Error", - "code": 1093 - }, - "An accessor cannot have type parameters.": { - "category": "Error", - "code": 1094 - }, - "A 'set' accessor cannot have a return type annotation.": { - "category": "Error", - "code": 1095 - }, - "An index signature must have exactly one parameter.": { - "category": "Error", - "code": 1096 - }, - "'{0}' list cannot be empty.": { - "category": "Error", - "code": 1097 - }, - "Type parameter list cannot be empty.": { - "category": "Error", - "code": 1098 - }, - "Type argument list cannot be empty.": { - "category": "Error", - "code": 1099 - }, - "Invalid use of '{0}' in strict mode.": { - "category": "Error", - "code": 1100 - }, - "'with' statements are not allowed in strict mode.": { - "category": "Error", - "code": 1101 - }, - "'delete' cannot be called on an identifier in strict mode.": { - "category": "Error", - "code": 1102 - }, - "'for await' loops are only allowed within async functions and at the top levels of modules.": { - "category": "Error", - "code": 1103 - }, - "A 'continue' statement can only be used within an enclosing iteration statement.": { - "category": "Error", - "code": 1104 - }, - "A 'break' statement can only be used within an enclosing iteration or switch statement.": { - "category": "Error", - "code": 1105 - }, - "The left-hand side of a 'for...of' statement may not be 'async'.": { - "category": "Error", - "code": 1106 - }, - "Jump target cannot cross function boundary.": { - "category": "Error", - "code": 1107 - }, - "A 'return' statement can only be used within a function body.": { - "category": "Error", - "code": 1108 - }, - "Expression expected.": { - "category": "Error", - "code": 1109 - }, - "Type expected.": { - "category": "Error", - "code": 1110 - }, - "Private field '{0}' must be declared in an enclosing class.": { - "category": "Error", - "code": 1111 - }, - "A 'default' clause cannot appear more than once in a 'switch' statement.": { - "category": "Error", - "code": 1113 - }, - "Duplicate label '{0}'.": { - "category": "Error", - "code": 1114 - }, - "A 'continue' statement can only jump to a label of an enclosing iteration statement.": { - "category": "Error", - "code": 1115 - }, - "A 'break' statement can only jump to a label of an enclosing statement.": { - "category": "Error", - "code": 1116 - }, - "An object literal cannot have multiple properties with the same name.": { - "category": "Error", - "code": 1117 - }, - "An object literal cannot have multiple get/set accessors with the same name.": { - "category": "Error", - "code": 1118 - }, - "An object literal cannot have property and accessor with the same name.": { - "category": "Error", - "code": 1119 - }, - "An export assignment cannot have modifiers.": { - "category": "Error", - "code": 1120 - }, - "Octal literals are not allowed. Use the syntax '{0}'.": { - "category": "Error", - "code": 1121 - }, - "Variable declaration list cannot be empty.": { - "category": "Error", - "code": 1123 - }, - "Digit expected.": { - "category": "Error", - "code": 1124 - }, - "Hexadecimal digit expected.": { - "category": "Error", - "code": 1125 - }, - "Unexpected end of text.": { - "category": "Error", - "code": 1126 - }, - "Invalid character.": { - "category": "Error", - "code": 1127 - }, - "Declaration or statement expected.": { - "category": "Error", - "code": 1128 - }, - "Statement expected.": { - "category": "Error", - "code": 1129 - }, - "'case' or 'default' expected.": { - "category": "Error", - "code": 1130 - }, - "Property or signature expected.": { - "category": "Error", - "code": 1131 - }, - "Enum member expected.": { - "category": "Error", - "code": 1132 - }, - "Variable declaration expected.": { - "category": "Error", - "code": 1134 - }, - "Argument expression expected.": { - "category": "Error", - "code": 1135 - }, - "Property assignment expected.": { - "category": "Error", - "code": 1136 - }, - "Expression or comma expected.": { - "category": "Error", - "code": 1137 - }, - "Parameter declaration expected.": { - "category": "Error", - "code": 1138 - }, - "Type parameter declaration expected.": { - "category": "Error", - "code": 1139 - }, - "Type argument expected.": { - "category": "Error", - "code": 1140 - }, - "String literal expected.": { - "category": "Error", - "code": 1141 - }, - "Line break not permitted here.": { - "category": "Error", - "code": 1142 - }, - "'{' or ';' expected.": { - "category": "Error", - "code": 1144 - }, - "'{' or JSX element expected.": { - "category": "Error", - "code": 1145 - }, - "Declaration expected.": { - "category": "Error", - "code": 1146 - }, - "Import declarations in a namespace cannot reference a module.": { - "category": "Error", - "code": 1147 - }, - "Cannot use imports, exports, or module augmentations when '--module' is 'none'.": { - "category": "Error", - "code": 1148 - }, - "File name '{0}' differs from already included file name '{1}' only in casing.": { - "category": "Error", - "code": 1149 - }, - "'{0}' declarations must be initialized.": { - "category": "Error", - "code": 1155 - }, - "'{0}' declarations can only be declared inside a block.": { - "category": "Error", - "code": 1156 - }, - "Unterminated template literal.": { - "category": "Error", - "code": 1160 - }, - "Unterminated regular expression literal.": { - "category": "Error", - "code": 1161 - }, - "An object member cannot be declared optional.": { - "category": "Error", - "code": 1162 - }, - "A 'yield' expression is only allowed in a generator body.": { - "category": "Error", - "code": 1163 - }, - "Computed property names are not allowed in enums.": { - "category": "Error", - "code": 1164 - }, - "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type.": { - "category": "Error", - "code": 1165 - }, - "A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type.": { - "category": "Error", - "code": 1166 - }, - "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.": { - "category": "Error", - "code": 1168 - }, - "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.": { - "category": "Error", - "code": 1169 - }, - "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.": { - "category": "Error", - "code": 1170 - }, - "A comma expression is not allowed in a computed property name.": { - "category": "Error", - "code": 1171 - }, - "'extends' clause already seen.": { - "category": "Error", - "code": 1172 - }, - "'extends' clause must precede 'implements' clause.": { - "category": "Error", - "code": 1173 - }, - "Classes can only extend a single class.": { - "category": "Error", - "code": 1174 - }, - "'implements' clause already seen.": { - "category": "Error", - "code": 1175 - }, - "Interface declaration cannot have 'implements' clause.": { - "category": "Error", - "code": 1176 - }, - "Binary digit expected.": { - "category": "Error", - "code": 1177 - }, - "Octal digit expected.": { - "category": "Error", - "code": 1178 - }, - "Unexpected token. '{' expected.": { - "category": "Error", - "code": 1179 - }, - "Property destructuring pattern expected.": { - "category": "Error", - "code": 1180 - }, - "Array element destructuring pattern expected.": { - "category": "Error", - "code": 1181 - }, - "A destructuring declaration must have an initializer.": { - "category": "Error", - "code": 1182 - }, - "An implementation cannot be declared in ambient contexts.": { - "category": "Error", - "code": 1183 - }, - "Modifiers cannot appear here.": { - "category": "Error", - "code": 1184 - }, - "Merge conflict marker encountered.": { - "category": "Error", - "code": 1185 - }, - "A rest element cannot have an initializer.": { - "category": "Error", - "code": 1186 - }, - "A parameter property may not be declared using a binding pattern.": { - "category": "Error", - "code": 1187 - }, - "Only a single variable declaration is allowed in a 'for...of' statement.": { - "category": "Error", - "code": 1188 - }, - "The variable declaration of a 'for...in' statement cannot have an initializer.": { - "category": "Error", - "code": 1189 - }, - "The variable declaration of a 'for...of' statement cannot have an initializer.": { - "category": "Error", - "code": 1190 - }, - "An import declaration cannot have modifiers.": { - "category": "Error", - "code": 1191 - }, - "Module '{0}' has no default export.": { - "category": "Error", - "code": 1192 - }, - "An export declaration cannot have modifiers.": { - "category": "Error", - "code": 1193 - }, - "Export declarations are not permitted in a namespace.": { - "category": "Error", - "code": 1194 - }, - "'export *' does not re-export a default.": { - "category": "Error", - "code": 1195 - }, - "Catch clause variable type annotation must be 'any' or 'unknown' if specified.": { - "category": "Error", - "code": 1196 - }, - "Catch clause variable cannot have an initializer.": { - "category": "Error", - "code": 1197 - }, - "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive.": { - "category": "Error", - "code": 1198 - }, - "Unterminated Unicode escape sequence.": { - "category": "Error", - "code": 1199 - }, - "Line terminator not permitted before arrow.": { - "category": "Error", - "code": 1200 - }, - "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": { - "category": "Error", - "code": 1202 - }, - "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.": { - "category": "Error", - "code": 1203 - }, - "Re-exporting a type when '{0}' is enabled requires using 'export type'.": { - "category": "Error", - "code": 1205 - }, - "Decorators are not valid here.": { - "category": "Error", - "code": 1206 - }, - "Decorators cannot be applied to multiple get/set accessors of the same name.": { - "category": "Error", - "code": 1207 - }, - "Invalid optional chain from new expression. Did you mean to call '{0}()'?": { - "category": "Error", - "code": 1209 - }, - "Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of '{0}'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode.": { - "category": "Error", - "code": 1210 - }, - "A class declaration without the 'default' modifier must have a name.": { - "category": "Error", - "code": 1211 - }, - "Identifier expected. '{0}' is a reserved word in strict mode.": { - "category": "Error", - "code": 1212 - }, - "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.": { - "category": "Error", - "code": 1213 - }, - "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.": { - "category": "Error", - "code": 1214 - }, - "Invalid use of '{0}'. Modules are automatically in strict mode.": { - "category": "Error", - "code": 1215 - }, - "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules.": { - "category": "Error", - "code": 1216 - }, - "Export assignment is not supported when '--module' flag is 'system'.": { - "category": "Error", - "code": 1218 - }, - "Generators are not allowed in an ambient context.": { - "category": "Error", - "code": 1221 - }, - "An overload signature cannot be declared as a generator.": { - "category": "Error", - "code": 1222 - }, - "'{0}' tag already specified.": { - "category": "Error", - "code": 1223 - }, - "Signature '{0}' must be a type predicate.": { - "category": "Error", - "code": 1224 - }, - "Cannot find parameter '{0}'.": { - "category": "Error", - "code": 1225 - }, - "Type predicate '{0}' is not assignable to '{1}'.": { - "category": "Error", - "code": 1226 - }, - "Parameter '{0}' is not in the same position as parameter '{1}'.": { - "category": "Error", - "code": 1227 - }, - "A type predicate is only allowed in return type position for functions and methods.": { - "category": "Error", - "code": 1228 - }, - "A type predicate cannot reference a rest parameter.": { - "category": "Error", - "code": 1229 - }, - "A type predicate cannot reference element '{0}' in a binding pattern.": { - "category": "Error", - "code": 1230 - }, - "An export assignment must be at the top level of a file or module declaration.": { - "category": "Error", - "code": 1231 - }, - "An import declaration can only be used at the top level of a namespace or module.": { - "category": "Error", - "code": 1232 - }, - "An export declaration can only be used at the top level of a namespace or module.": { - "category": "Error", - "code": 1233 - }, - "An ambient module declaration is only allowed at the top level in a file.": { - "category": "Error", - "code": 1234 - }, - "A namespace declaration is only allowed at the top level of a namespace or module.": { - "category": "Error", - "code": 1235 - }, - "The return type of a property decorator function must be either 'void' or 'any'.": { - "category": "Error", - "code": 1236 - }, - "The return type of a parameter decorator function must be either 'void' or 'any'.": { - "category": "Error", - "code": 1237 - }, - "Unable to resolve signature of class decorator when called as an expression.": { - "category": "Error", - "code": 1238 - }, - "Unable to resolve signature of parameter decorator when called as an expression.": { - "category": "Error", - "code": 1239 - }, - "Unable to resolve signature of property decorator when called as an expression.": { - "category": "Error", - "code": 1240 - }, - "Unable to resolve signature of method decorator when called as an expression.": { - "category": "Error", - "code": 1241 - }, - "'abstract' modifier can only appear on a class, method, or property declaration.": { - "category": "Error", - "code": 1242 - }, - "'{0}' modifier cannot be used with '{1}' modifier.": { - "category": "Error", - "code": 1243 - }, - "Abstract methods can only appear within an abstract class.": { - "category": "Error", - "code": 1244 - }, - "Method '{0}' cannot have an implementation because it is marked abstract.": { - "category": "Error", - "code": 1245 - }, - "An interface property cannot have an initializer.": { - "category": "Error", - "code": 1246 - }, - "A type literal property cannot have an initializer.": { - "category": "Error", - "code": 1247 - }, - "A class member cannot have the '{0}' keyword.": { - "category": "Error", - "code": 1248 - }, - "A decorator can only decorate a method implementation, not an overload.": { - "category": "Error", - "code": 1249 - }, - "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'.": { - "category": "Error", - "code": 1250 - }, - "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'. Class definitions are automatically in strict mode.": { - "category": "Error", - "code": 1251 - }, - "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'. Modules are automatically in strict mode.": { - "category": "Error", - "code": 1252 - }, - "Abstract properties can only appear within an abstract class.": { - "category": "Error", - "code": 1253 - }, - "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.": { - "category": "Error", - "code": 1254 - }, - "A definite assignment assertion '!' is not permitted in this context.": { - "category": "Error", - "code": 1255 - }, - "A required element cannot follow an optional element.": { - "category": "Error", - "code": 1257 - }, - "A default export must be at the top level of a file or module declaration.": { - "category": "Error", - "code": 1258 - }, - "Module '{0}' can only be default-imported using the '{1}' flag": { - "category": "Error", - "code": 1259 - }, - "Keywords cannot contain escape characters.": { - "category": "Error", - "code": 1260 - }, - "Already included file name '{0}' differs from file name '{1}' only in casing.": { - "category": "Error", - "code": 1261 - }, - "Identifier expected. '{0}' is a reserved word at the top-level of a module.": { - "category": "Error", - "code": 1262 - }, - "Declarations with initializers cannot also have definite assignment assertions.": { - "category": "Error", - "code": 1263 - }, - "Declarations with definite assignment assertions must also have type annotations.": { - "category": "Error", - "code": 1264 - }, - "A rest element cannot follow another rest element.": { - "category": "Error", - "code": 1265 - }, - "An optional element cannot follow a rest element.": { - "category": "Error", - "code": 1266 - }, - "Property '{0}' cannot have an initializer because it is marked abstract.": { - "category": "Error", - "code": 1267 - }, - "An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type.": { - "category": "Error", - "code": 1268 - }, - "Cannot use 'export import' on a type or type-only namespace when '{0}' is enabled.": { - "category": "Error", - "code": 1269 - }, - "Decorator function return type '{0}' is not assignable to type '{1}'.": { - "category": "Error", - "code": 1270 - }, - "Decorator function return type is '{0}' but is expected to be 'void' or 'any'.": { - "category": "Error", - "code": 1271 - }, - "A type referenced in a decorated signature must be imported with 'import type' or a namespace import when 'isolatedModules' and 'emitDecoratorMetadata' are enabled.": { - "category": "Error", - "code": 1272 - }, - "'{0}' modifier cannot appear on a type parameter": { - "category": "Error", - "code": 1273 - }, - "'{0}' modifier can only appear on a type parameter of a class, interface or type alias": { - "category": "Error", - "code": 1274 - }, - "'accessor' modifier can only appear on a property declaration.": { - "category": "Error", - "code": 1275 - }, - "An 'accessor' property cannot be declared optional.": { - "category": "Error", - "code": 1276 - }, - "'{0}' modifier can only appear on a type parameter of a function, method or class": { - "category": "Error", - "code": 1277 - }, - "The runtime will invoke the decorator with {1} arguments, but the decorator expects {0}.": { - "category": "Error", - "code": 1278 - }, - "The runtime will invoke the decorator with {1} arguments, but the decorator expects at least {0}.": { - "category": "Error", - "code": 1279 - }, - "Namespaces are not allowed in global script files when '{0}' is enabled. If this file is not intended to be a global script, set 'moduleDetection' to 'force' or add an empty 'export {}' statement.": { - "category": "Error", - "code": 1280 - }, - "Cannot access '{0}' from another file without qualification when '{1}' is enabled. Use '{2}' instead.": { - "category": "Error", - "code": 1281 - }, - "An 'export =' declaration must reference a value when 'verbatimModuleSyntax' is enabled, but '{0}' only refers to a type.": { - "category": "Error", - "code": 1282 - }, - "An 'export =' declaration must reference a real value when 'verbatimModuleSyntax' is enabled, but '{0}' resolves to a type-only declaration.": { - "category": "Error", - "code": 1283 - }, - "An 'export default' must reference a value when 'verbatimModuleSyntax' is enabled, but '{0}' only refers to a type.": { - "category": "Error", - "code": 1284 - }, - "An 'export default' must reference a real value when 'verbatimModuleSyntax' is enabled, but '{0}' resolves to a type-only declaration.": { - "category": "Error", - "code": 1285 - }, - "ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.": { - "category": "Error", - "code": 1286 - }, - "A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled.": { - "category": "Error", - "code": 1287 - }, - "An import alias cannot resolve to a type or type-only declaration when 'verbatimModuleSyntax' is enabled.": { - "category": "Error", - "code": 1288 - }, - "'{0}' resolves to a type-only declaration and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'import type' where '{0}' is imported.": { - "category": "Error", - "code": 1289 - }, - "'{0}' resolves to a type-only declaration and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'export type { {0} as default }'.": { - "category": "Error", - "code": 1290 - }, - "'{0}' resolves to a type and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'import type' where '{0}' is imported.": { - "category": "Error", - "code": 1291 - }, - "'{0}' resolves to a type and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'export type { {0} as default }'.": { - "category": "Error", - "code": 1292 - }, - "ECMAScript module syntax is not allowed in a CommonJS module when 'module' is set to 'preserve'.": { - "category": "Error", - "code": 1293 - }, - "This syntax is not allowed when 'erasableSyntaxOnly' is enabled.": { - "category": "Error", - "code": 1294 - }, - "ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'. Adjust the 'type' field in the nearest 'package.json' to make this file an ECMAScript module, or adjust your 'verbatimModuleSyntax', 'module', and 'moduleResolution' settings in TypeScript.": { - "category": "Error", - "code": 1295 - }, - "'with' statements are not allowed in an async function block.": { - "category": "Error", - "code": 1300 - }, - "'await' expressions are only allowed within async functions and at the top levels of modules.": { - "category": "Error", - "code": 1308 - }, - "The current file is a CommonJS module and cannot use 'await' at the top level.": { - "category": "Error", - "code": 1309 - }, - "Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern.": { - "category": "Error", - "code": 1312 - }, - "The body of an 'if' statement cannot be the empty statement.": { - "category": "Error", - "code": 1313 - }, - "Global module exports may only appear in module files.": { - "category": "Error", - "code": 1314 - }, - "Global module exports may only appear in declaration files.": { - "category": "Error", - "code": 1315 - }, - "Global module exports may only appear at top level.": { - "category": "Error", - "code": 1316 - }, - "A parameter property cannot be declared using a rest parameter.": { - "category": "Error", - "code": 1317 - }, - "An abstract accessor cannot have an implementation.": { - "category": "Error", - "code": 1318 - }, - "A default export can only be used in an ECMAScript-style module.": { - "category": "Error", - "code": 1319 - }, - "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.": { - "category": "Error", - "code": 1320 - }, - "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member.": { - "category": "Error", - "code": 1321 - }, - "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member.": { - "category": "Error", - "code": 1322 - }, - "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', 'node20', or 'nodenext'.": { - "category": "Error", - "code": 1323 - }, - "Dynamic imports only support a second argument when the '--module' option is set to 'esnext', 'node16', 'node18', 'node20', 'nodenext', or 'preserve'.": { - "category": "Error", - "code": 1324 - }, - "Argument of dynamic import cannot be spread element.": { - "category": "Error", - "code": 1325 - }, - "This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.": { - "category": "Error", - "code": 1326 - }, - "String literal with double quotes expected.": { - "category": "Error", - "code": 1327 - }, - "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.": { - "category": "Error", - "code": 1328 - }, - "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?": { - "category": "Error", - "code": 1329 - }, - "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'.": { - "category": "Error", - "code": 1330 - }, - "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'.": { - "category": "Error", - "code": 1331 - }, - "A variable whose type is a 'unique symbol' type must be 'const'.": { - "category": "Error", - "code": 1332 - }, - "'unique symbol' types may not be used on a variable declaration with a binding name.": { - "category": "Error", - "code": 1333 - }, - "'unique symbol' types are only allowed on variables in a variable statement.": { - "category": "Error", - "code": 1334 - }, - "'unique symbol' types are not allowed here.": { - "category": "Error", - "code": 1335 - }, - "An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.": { - "category": "Error", - "code": 1337 - }, - "'infer' declarations are only permitted in the 'extends' clause of a conditional type.": { - "category": "Error", - "code": 1338 - }, - "Module '{0}' does not refer to a value, but is used as a value here.": { - "category": "Error", - "code": 1339 - }, - "Module '{0}' does not refer to a type, but is used as a type here. Did you mean 'typeof import('{0}')'?": { - "category": "Error", - "code": 1340 - }, - "Class constructor may not be an accessor.": { - "category": "Error", - "code": 1341 - }, - "The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', or 'nodenext'.": { - "category": "Error", - "code": 1343 - }, - "A label is not allowed here.": { - "category": "Error", - "code": 1344 - }, - "An expression of type 'void' cannot be tested for truthiness.": { - "category": "Error", - "code": 1345 - }, - "This parameter is not allowed with 'use strict' directive.": { - "category": "Error", - "code": 1346 - }, - "'use strict' directive cannot be used with non-simple parameter list.": { - "category": "Error", - "code": 1347 - }, - "Non-simple parameter declared here.": { - "category": "Error", - "code": 1348 - }, - "'use strict' directive used here.": { - "category": "Error", - "code": 1349 - }, - "Print the final configuration instead of building.": { - "category": "Message", - "code": 1350 - }, - "An identifier or keyword cannot immediately follow a numeric literal.": { - "category": "Error", - "code": 1351 - }, - "A bigint literal cannot use exponential notation.": { - "category": "Error", - "code": 1352 - }, - "A bigint literal must be an integer.": { - "category": "Error", - "code": 1353 - }, - "'readonly' type modifier is only permitted on array and tuple literal types.": { - "category": "Error", - "code": 1354 - }, - "A 'const' assertion can only be applied to references to enum members, or string, number, boolean, array, or object literals.": { - "category": "Error", - "code": 1355 - }, - "Did you mean to mark this function as 'async'?": { - "category": "Error", - "code": 1356 - }, - "An enum member name must be followed by a ',', '=', or '}'.": { - "category": "Error", - "code": 1357 - }, - "Tagged template expressions are not permitted in an optional chain.": { - "category": "Error", - "code": 1358 - }, - "Identifier expected. '{0}' is a reserved word that cannot be used here.": { - "category": "Error", - "code": 1359 - }, - "Type '{0}' does not satisfy the expected type '{1}'.": { - "category": "Error", - "code": 1360 - }, - "'{0}' cannot be used as a value because it was imported using 'import type'.": { - "category": "Error", - "code": 1361 - }, - "'{0}' cannot be used as a value because it was exported using 'export type'.": { - "category": "Error", - "code": 1362 - }, - "A type-only import can specify a default import or named bindings, but not both.": { - "category": "Error", - "code": 1363 - }, - "Convert to type-only export": { - "category": "Message", - "code": 1364 - }, - "Convert all re-exported types to type-only exports": { - "category": "Message", - "code": 1365 - }, - "Split into two separate import declarations": { - "category": "Message", - "code": 1366 - }, - "Split all invalid type-only imports": { - "category": "Message", - "code": 1367 - }, - "Class constructor may not be a generator.": { - "category": "Error", - "code": 1368 - }, - "Did you mean '{0}'?": { - "category": "Message", - "code": 1369 - }, - "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { - "category": "Error", - "code": 1375 - }, - "'{0}' was imported here.": { - "category": "Message", - "code": 1376 - }, - "'{0}' was exported here.": { - "category": "Message", - "code": 1377 - }, - "Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.": { - "category": "Error", - "code": 1378 - }, - "An import alias cannot reference a declaration that was exported using 'export type'.": { - "category": "Error", - "code": 1379 - }, - "An import alias cannot reference a declaration that was imported using 'import type'.": { - "category": "Error", - "code": 1380 - }, - "Unexpected token. Did you mean `{'}'}` or `}`?": { - "category": "Error", - "code": 1381 - }, - "Unexpected token. Did you mean `{'>'}` or `>`?": { - "category": "Error", - "code": 1382 - }, - "Function type notation must be parenthesized when used in a union type.": { - "category": "Error", - "code": 1385 - }, - "Constructor type notation must be parenthesized when used in a union type.": { - "category": "Error", - "code": 1386 - }, - "Function type notation must be parenthesized when used in an intersection type.": { - "category": "Error", - "code": 1387 - }, - "Constructor type notation must be parenthesized when used in an intersection type.": { - "category": "Error", - "code": 1388 - }, - "'{0}' is not allowed as a variable declaration name.": { - "category": "Error", - "code": 1389 - }, - "'{0}' is not allowed as a parameter name.": { - "category": "Error", - "code": 1390 - }, - "An import alias cannot use 'import type'": { - "category": "Error", - "code": 1392 - }, - "Imported via {0} from file '{1}'": { - "category": "Message", - "code": 1393 - }, - "Imported via {0} from file '{1}' with packageId '{2}'": { - "category": "Message", - "code": 1394 - }, - "Imported via {0} from file '{1}' to import 'importHelpers' as specified in compilerOptions": { - "category": "Message", - "code": 1395 - }, - "Imported via {0} from file '{1}' with packageId '{2}' to import 'importHelpers' as specified in compilerOptions": { - "category": "Message", - "code": 1396 - }, - "Imported via {0} from file '{1}' to import 'jsx' and 'jsxs' factory functions": { - "category": "Message", - "code": 1397 - }, - "Imported via {0} from file '{1}' with packageId '{2}' to import 'jsx' and 'jsxs' factory functions": { - "category": "Message", - "code": 1398 - }, - "File is included via import here.": { - "category": "Message", - "code": 1399 - }, - "Referenced via '{0}' from file '{1}'": { - "category": "Message", - "code": 1400 - }, - "File is included via reference here.": { - "category": "Message", - "code": 1401 - }, - "Type library referenced via '{0}' from file '{1}'": { - "category": "Message", - "code": 1402 - }, - "Type library referenced via '{0}' from file '{1}' with packageId '{2}'": { - "category": "Message", - "code": 1403 - }, - "File is included via type library reference here.": { - "category": "Message", - "code": 1404 - }, - "Library referenced via '{0}' from file '{1}'": { - "category": "Message", - "code": 1405 - }, - "File is included via library reference here.": { - "category": "Message", - "code": 1406 - }, - "Matched by include pattern '{0}' in '{1}'": { - "category": "Message", - "code": 1407 - }, - "File is matched by include pattern specified here.": { - "category": "Message", - "code": 1408 - }, - "Part of 'files' list in tsconfig.json": { - "category": "Message", - "code": 1409 - }, - "File is matched by 'files' list specified here.": { - "category": "Message", - "code": 1410 - }, - "Output from referenced project '{0}' included because '{1}' specified": { - "category": "Message", - "code": 1411 - }, - "Output from referenced project '{0}' included because '--module' is specified as 'none'": { - "category": "Message", - "code": 1412 - }, - "File is output from referenced project specified here.": { - "category": "Message", - "code": 1413 - }, - "Source from referenced project '{0}' included because '{1}' specified": { - "category": "Message", - "code": 1414 - }, - "Source from referenced project '{0}' included because '--module' is specified as 'none'": { - "category": "Message", - "code": 1415 - }, - "File is source from referenced project specified here.": { - "category": "Message", - "code": 1416 - }, - "Entry point of type library '{0}' specified in compilerOptions": { - "category": "Message", - "code": 1417 - }, - "Entry point of type library '{0}' specified in compilerOptions with packageId '{1}'": { - "category": "Message", - "code": 1418 - }, - "File is entry point of type library specified here.": { - "category": "Message", - "code": 1419 - }, - "Entry point for implicit type library '{0}'": { - "category": "Message", - "code": 1420 - }, - "Entry point for implicit type library '{0}' with packageId '{1}'": { - "category": "Message", - "code": 1421 - }, - "Library '{0}' specified in compilerOptions": { - "category": "Message", - "code": 1422 - }, - "File is library specified here.": { - "category": "Message", - "code": 1423 - }, - "Default library": { - "category": "Message", - "code": 1424 - }, - "Default library for target '{0}'": { - "category": "Message", - "code": 1425 - }, - "File is default library for target specified here.": { - "category": "Message", - "code": 1426 - }, - "Root file specified for compilation": { - "category": "Message", - "code": 1427 - }, - "File is output of project reference source '{0}'": { - "category": "Message", - "code": 1428 - }, - "File redirects to file '{0}'": { - "category": "Message", - "code": 1429 - }, - "The file is in the program because:": { - "category": "Message", - "code": 1430 - }, - "'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { - "category": "Error", - "code": 1431 - }, - "Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.": { - "category": "Error", - "code": 1432 - }, - "Neither decorators nor modifiers may be applied to 'this' parameters.": { - "category": "Error", - "code": 1433 - }, - "Unexpected keyword or identifier.": { - "category": "Error", - "code": 1434 - }, - "Unknown keyword or identifier. Did you mean '{0}'?": { - "category": "Error", - "code": 1435 - }, - "Decorators must precede the name and all keywords of property declarations.": { - "category": "Error", - "code": 1436 - }, - "Namespace must be given a name.": { - "category": "Error", - "code": 1437 - }, - "Interface must be given a name.": { - "category": "Error", - "code": 1438 - }, - "Type alias must be given a name.": { - "category": "Error", - "code": 1439 - }, - "Variable declaration not allowed at this location.": { - "category": "Error", - "code": 1440 - }, - "Cannot start a function call in a type annotation.": { - "category": "Error", - "code": 1441 - }, - "Expected '=' for property initializer.": { - "category": "Error", - "code": 1442 - }, - "Module declaration names may only use ' or \" quoted strings.": { - "category": "Error", - "code": 1443 - }, - "'{0}' resolves to a type-only declaration and must be re-exported using a type-only re-export when '{1}' is enabled.": { - "category": "Error", - "code": 1448 - }, - "Preserve unused imported values in the JavaScript output that would otherwise be removed.": { - "category": "Message", - "code": 1449 - }, - "Dynamic imports can only accept a module specifier and an optional set of attributes as arguments": { - "category": "Message", - "code": 1450 - }, - "Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression": { - "category": "Error", - "code": 1451 - }, - "`resolution-mode` should be either `require` or `import`.": { - "category": "Error", - "code": 1453 - }, - "`resolution-mode` can only be set for type-only imports.": { - "category": "Error", - "code": 1454 - }, - "`resolution-mode` is the only valid key for type import assertions.": { - "category": "Error", - "code": 1455 - }, - "Type import assertions should have exactly one key - `resolution-mode` - with value `import` or `require`.": { - "category": "Error", - "code": 1456 - }, - "Matched by default include pattern '**/*'": { - "category": "Message", - "code": 1457 - }, - "File is ECMAScript module because '{0}' has field \"type\" with value \"module\"": { - "category": "Message", - "code": 1458 - }, - "File is CommonJS module because '{0}' has field \"type\" whose value is not \"module\"": { - "category": "Message", - "code": 1459 - }, - "File is CommonJS module because '{0}' does not have field \"type\"": { - "category": "Message", - "code": 1460 - }, - "File is CommonJS module because 'package.json' was not found": { - "category": "Message", - "code": 1461 - }, - "'resolution-mode' is the only valid key for type import attributes.": { - "category": "Error", - "code": 1463 - }, - "Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'.": { - "category": "Error", - "code": 1464 - }, - - "The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": { - "category": "Error", - "code": 1470 - }, - "Module '{0}' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported with 'require'. Use an ECMAScript import instead.": { - "category": "Error", - "code": 1471 - }, - "'catch' or 'finally' expected.": { - "category": "Error", - "code": 1472 - }, - "An import declaration can only be used at the top level of a module.": { - "category": "Error", - "code": 1473 - }, - "An export declaration can only be used at the top level of a module.": { - "category": "Error", - "code": 1474 - }, - "Control what method is used to detect module-format JS files.": { - "category": "Message", - "code": 1475 - }, - "\"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.": { - "category": "Message", - "code": 1476 - }, - "An instantiation expression cannot be followed by a property access.": { - "category": "Error", - "code": 1477 - }, - "Identifier or string literal expected.": { - "category": "Error", - "code": 1478 - }, - "The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import(\"{0}\")' call instead.": { - "category": "Error", - "code": 1479 - }, - "To convert this file to an ECMAScript module, change its file extension to '{0}' or create a local package.json file with `{ \"type\": \"module\" }`.": { - "category": "Message", - "code": 1480 - }, - "To convert this file to an ECMAScript module, change its file extension to '{0}', or add the field `\"type\": \"module\"` to '{1}'.": { - "category": "Message", - "code": 1481 - }, - "To convert this file to an ECMAScript module, add the field `\"type\": \"module\"` to '{0}'.": { - "category": "Message", - "code": 1482 - }, - "To convert this file to an ECMAScript module, create a local package.json file with `{ \"type\": \"module\" }`.": { - "category": "Message", - "code": 1483 - }, - "'{0}' is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled.": { - "category": "Error", - "code": 1484 - }, - "'{0}' resolves to a type-only declaration and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled.": { - "category": "Error", - "code": 1485 - }, - "Decorator used before 'export' here.": { - "category": "Error", - "code": 1486 - }, - "Octal escape sequences are not allowed. Use the syntax '{0}'.": { - "category": "Error", - "code": 1487 - }, - "Escape sequence '{0}' is not allowed.": { - "category": "Error", - "code": 1488 - }, - "Decimals with leading zeros are not allowed.": { - "category": "Error", - "code": 1489 - }, - "File appears to be binary.": { - "category": "Error", - "code": 1490 - }, - "'{0}' modifier cannot appear on a 'using' declaration.": { - "category": "Error", - "code": 1491 - }, - "'{0}' declarations may not have binding patterns.": { - "category": "Error", - "code": 1492 - }, - "The left-hand side of a 'for...in' statement cannot be a 'using' declaration.": { - "category": "Error", - "code": 1493 - }, - "The left-hand side of a 'for...in' statement cannot be an 'await using' declaration.": { - "category": "Error", - "code": 1494 - }, - "'{0}' modifier cannot appear on an 'await using' declaration.": { - "category": "Error", - "code": 1495 - }, - "Identifier, string literal, or number literal expected.": { - "category": "Error", - "code": 1496 - }, - "Expression must be enclosed in parentheses to be used as a decorator.": { - "category": "Error", - "code": 1497 - }, - "Invalid syntax in decorator.": { - "category": "Error", - "code": 1498 - }, - "Unknown regular expression flag.": { - "category": "Error", - "code": 1499 - }, - "Duplicate regular expression flag.": { - "category": "Error", - "code": 1500 - }, - "This regular expression flag is only available when targeting '{0}' or later.": { - "category": "Error", - "code": 1501 - }, - "The Unicode (u) flag and the Unicode Sets (v) flag cannot be set simultaneously.": { - "category": "Error", - "code": 1502 - }, - "Named capturing groups are only available when targeting 'ES2018' or later.": { - "category": "Error", - "code": 1503 - }, - "Subpattern flags must be present when there is a minus sign.": { - "category": "Error", - "code": 1504 - }, - "Incomplete quantifier. Digit expected.": { - "category": "Error", - "code": 1505 - }, - "Numbers out of order in quantifier.": { - "category": "Error", - "code": 1506 - }, - "There is nothing available for repetition.": { - "category": "Error", - "code": 1507 - }, - "Unexpected '{0}'. Did you mean to escape it with backslash?": { - "category": "Error", - "code": 1508 - }, - "This regular expression flag cannot be toggled within a subpattern.": { - "category": "Error", - "code": 1509 - }, - "'\\k' must be followed by a capturing group name enclosed in angle brackets.": { - "category": "Error", - "code": 1510 - }, - "'\\q' is only available inside character class.": { - "category": "Error", - "code": 1511 - }, - "'\\c' must be followed by an ASCII letter.": { - "category": "Error", - "code": 1512 - }, - "Undetermined character escape.": { - "category": "Error", - "code": 1513 - }, - "Expected a capturing group name.": { - "category": "Error", - "code": 1514 - }, - "Named capturing groups with the same name must be mutually exclusive to each other.": { - "category": "Error", - "code": 1515 - }, - "A character class range must not be bounded by another character class.": { - "category": "Error", - "code": 1516 - }, - "Range out of order in character class.": { - "category": "Error", - "code": 1517 - }, - "Anything that would possibly match more than a single character is invalid inside a negated character class.": { - "category": "Error", - "code": 1518 - }, - "Operators must not be mixed within a character class. Wrap it in a nested class instead.": { - "category": "Error", - "code": 1519 - }, - "Expected a class set operand.": { - "category": "Error", - "code": 1520 - }, - "'\\q' must be followed by string alternatives enclosed in braces.": { - "category": "Error", - "code": 1521 - }, - "A character class must not contain a reserved double punctuator. Did you mean to escape it with backslash?": { - "category": "Error", - "code": 1522 - }, - "Expected a Unicode property name.": { - "category": "Error", - "code": 1523 - }, - "Unknown Unicode property name.": { - "category": "Error", - "code": 1524 - }, - "Expected a Unicode property value.": { - "category": "Error", - "code": 1525 - }, - "Unknown Unicode property value.": { - "category": "Error", - "code": 1526 - }, - "Expected a Unicode property name or value.": { - "category": "Error", - "code": 1527 - }, - "Any Unicode property that would possibly match more than a single character is only available when the Unicode Sets (v) flag is set.": { - "category": "Error", - "code": 1528 - }, - "Unknown Unicode property name or value.": { - "category": "Error", - "code": 1529 - }, - "Unicode property value expressions are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.": { - "category": "Error", - "code": 1530 - }, - "'\\{0}' must be followed by a Unicode property value expression enclosed in braces.": { - "category": "Error", - "code": 1531 - }, - "There is no capturing group named '{0}' in this regular expression.": { - "category": "Error", - "code": 1532 - }, - "This backreference refers to a group that does not exist. There are only {0} capturing groups in this regular expression.": { - "category": "Error", - "code": 1533 - }, - "This backreference refers to a group that does not exist. There are no capturing groups in this regular expression.": { - "category": "Error", - "code": 1534 - }, - "This character cannot be escaped in a regular expression.": { - "category": "Error", - "code": 1535 - }, - "Octal escape sequences and backreferences are not allowed in a character class. If this was intended as an escape sequence, use the syntax '{0}' instead.": { - "category": "Error", - "code": 1536 - }, - "Decimal escape sequences and backreferences are not allowed in a character class.": { - "category": "Error", - "code": 1537 - }, - "Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.": { - "category": "Error", - "code": 1538 - }, - "A 'bigint' literal cannot be used as a property name.": { - "category": "Error", - "code": 1539 - }, - "A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.": { - "category": "Error", - "code": 1540 - }, - "Type-only import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.": { - "category": "Error", - "code": 1541 - }, - "Type import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.": { - "category": "Error", - "code": 1542 - }, - "Importing a JSON file into an ECMAScript module requires a 'type: \"json\"' import attribute when 'module' is set to '{0}'.": { - "category": "Error", - "code": 1543 - }, - "Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to '{0}'.": { - "category": "Error", - "code": 1544 - }, - "'using' declarations are not allowed in ambient contexts.": { - "category": "Error", - "code": 1545 - }, - "'await using' declarations are not allowed in ambient contexts.": { - "category": "Error", - "code": 1546 - }, - "'using' declarations are not allowed in 'case' or 'default' clauses unless contained within a block.": { - "category": "Error", - "code": 1547 - }, - "'await using' declarations are not allowed in 'case' or 'default' clauses unless contained within a block.": { - "category": "Error", - "code": 1548 - }, - "Ignore the tsconfig found and build with commandline options and files.": { - "category": "Message", - "code": 1549 - }, - - "The types of '{0}' are incompatible between these types.": { - "category": "Error", - "code": 2200 - }, - "The types returned by '{0}' are incompatible between these types.": { - "category": "Error", - "code": 2201 - }, - "Call signature return types '{0}' and '{1}' are incompatible.": { - "category": "Error", - "code": 2202, - "elidedInCompatabilityPyramid": true - }, - "Construct signature return types '{0}' and '{1}' are incompatible.": { - "category": "Error", - "code": 2203, - "elidedInCompatabilityPyramid": true - }, - "Call signatures with no arguments have incompatible return types '{0}' and '{1}'.": { - "category": "Error", - "code": 2204, - "elidedInCompatabilityPyramid": true - }, - "Construct signatures with no arguments have incompatible return types '{0}' and '{1}'.": { - "category": "Error", - "code": 2205, - "elidedInCompatabilityPyramid": true - }, - "The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement.": { - "category": "Error", - "code": 2206 - }, - "The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement.": { - "category": "Error", - "code": 2207 - }, - "This type parameter might need an `extends {0}` constraint.": { - "category": "Error", - "code": 2208 - }, - - "The project root is ambiguous, but is required to resolve export map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": { - "category": "Error", - "code": 2209 - }, - "The project root is ambiguous, but is required to resolve import map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": { - "category": "Error", - "code": 2210 - }, - "Add `extends` constraint.": { - "category": "Message", - "code": 2211 - }, - "Add `extends` constraint to all type parameters": { - "category": "Message", - "code": 2212 - }, - - "Duplicate identifier '{0}'.": { - "category": "Error", - "code": 2300 - }, - "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": { - "category": "Error", - "code": 2301 - }, - "Static members cannot reference class type parameters.": { - "category": "Error", - "code": 2302 - }, - "Circular definition of import alias '{0}'.": { - "category": "Error", - "code": 2303 - }, - "Cannot find name '{0}'.": { - "category": "Error", - "code": 2304 - }, - "Module '{0}' has no exported member '{1}'.": { - "category": "Error", - "code": 2305 - }, - "File '{0}' is not a module.": { - "category": "Error", - "code": 2306 - }, - "Cannot find module '{0}' or its corresponding type declarations.": { - "category": "Error", - "code": 2307 - }, - "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { - "category": "Error", - "code": 2308 - }, - "An export assignment cannot be used in a module with other exported elements.": { - "category": "Error", - "code": 2309 - }, - "Type '{0}' recursively references itself as a base type.": { - "category": "Error", - "code": 2310 - }, - "Cannot find name '{0}'. Did you mean to write this in an async function?": { - "category": "Error", - "code": 2311 - }, - "An interface can only extend an object type or intersection of object types with statically known members.": { - "category": "Error", - "code": 2312 - }, - "Type parameter '{0}' has a circular constraint.": { - "category": "Error", - "code": 2313 - }, - "Generic type '{0}' requires {1} type argument(s).": { - "category": "Error", - "code": 2314 - }, - "Type '{0}' is not generic.": { - "category": "Error", - "code": 2315 - }, - "Global type '{0}' must be a class or interface type.": { - "category": "Error", - "code": 2316 - }, - "Global type '{0}' must have {1} type parameter(s).": { - "category": "Error", - "code": 2317 - }, - "Cannot find global type '{0}'.": { - "category": "Error", - "code": 2318 - }, - "Named property '{0}' of types '{1}' and '{2}' are not identical.": { - "category": "Error", - "code": 2319 - }, - "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'.": { - "category": "Error", - "code": 2320 - }, - "Excessive stack depth comparing types '{0}' and '{1}'.": { - "category": "Error", - "code": 2321 - }, - "Type '{0}' is not assignable to type '{1}'.": { - "category": "Error", - "code": 2322 - }, - "Cannot redeclare exported variable '{0}'.": { - "category": "Error", - "code": 2323 - }, - "Property '{0}' is missing in type '{1}'.": { - "category": "Error", - "code": 2324 - }, - "Property '{0}' is private in type '{1}' but not in type '{2}'.": { - "category": "Error", - "code": 2325 - }, - "Types of property '{0}' are incompatible.": { - "category": "Error", - "code": 2326 - }, - "Property '{0}' is optional in type '{1}' but required in type '{2}'.": { - "category": "Error", - "code": 2327 - }, - "Types of parameters '{0}' and '{1}' are incompatible.": { - "category": "Error", - "code": 2328 - }, - "Index signature for type '{0}' is missing in type '{1}'.": { - "category": "Error", - "code": 2329 - }, - "'{0}' and '{1}' index signatures are incompatible.": { - "category": "Error", - "code": 2330 - }, - "'this' cannot be referenced in a module or namespace body.": { - "category": "Error", - "code": 2331 - }, - "'this' cannot be referenced in current location.": { - "category": "Error", - "code": 2332 - }, - "'this' cannot be referenced in a static property initializer.": { - "category": "Error", - "code": 2334 - }, - "'super' can only be referenced in a derived class.": { - "category": "Error", - "code": 2335 - }, - "'super' cannot be referenced in constructor arguments.": { - "category": "Error", - "code": 2336 - }, - "Super calls are not permitted outside constructors or in nested functions inside constructors.": { - "category": "Error", - "code": 2337 - }, - "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.": { - "category": "Error", - "code": 2338 - }, - "Property '{0}' does not exist on type '{1}'.": { - "category": "Error", - "code": 2339 - }, - "Only public and protected methods of the base class are accessible via the 'super' keyword.": { - "category": "Error", - "code": 2340 - }, - "Property '{0}' is private and only accessible within class '{1}'.": { - "category": "Error", - "code": 2341 - }, - "This syntax requires an imported helper named '{1}' which does not exist in '{0}'. Consider upgrading your version of '{0}'.": { - "category": "Error", - "code": 2343 - }, - "Type '{0}' does not satisfy the constraint '{1}'.": { - "category": "Error", - "code": 2344 - }, - "Argument of type '{0}' is not assignable to parameter of type '{1}'.": { - "category": "Error", - "code": 2345 - }, - "Call target does not contain any signatures.": { - "category": "Error", - "code": 2346 - }, - "Untyped function calls may not accept type arguments.": { - "category": "Error", - "code": 2347 - }, - "Value of type '{0}' is not callable. Did you mean to include 'new'?": { - "category": "Error", - "code": 2348 - }, - "This expression is not callable.": { - "category": "Error", - "code": 2349 - }, - "Only a void function can be called with the 'new' keyword.": { - "category": "Error", - "code": 2350 - }, - "This expression is not constructable.": { - "category": "Error", - "code": 2351 - }, - "Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.": { - "category": "Error", - "code": 2352 - }, - "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'.": { - "category": "Error", - "code": 2353 - }, - "This syntax requires an imported helper but module '{0}' cannot be found.": { - "category": "Error", - "code": 2354 - }, - "A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.": { - "category": "Error", - "code": 2355 - }, - "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.": { - "category": "Error", - "code": 2356 - }, - "The operand of an increment or decrement operator must be a variable or a property access.": { - "category": "Error", - "code": 2357 - }, - "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.": { - "category": "Error", - "code": 2358 - }, - "The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method.": { - "category": "Error", - "code": 2359 - }, - "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": { - "category": "Error", - "code": 2362 - }, - "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": { - "category": "Error", - "code": 2363 - }, - "The left-hand side of an assignment expression must be a variable or a property access.": { - "category": "Error", - "code": 2364 - }, - "Operator '{0}' cannot be applied to types '{1}' and '{2}'.": { - "category": "Error", - "code": 2365 - }, - "Function lacks ending return statement and return type does not include 'undefined'.": { - "category": "Error", - "code": 2366 - }, - "This comparison appears to be unintentional because the types '{0}' and '{1}' have no overlap.": { - "category": "Error", - "code": 2367 - }, - "Type parameter name cannot be '{0}'.": { - "category": "Error", - "code": 2368 - }, - "A parameter property is only allowed in a constructor implementation.": { - "category": "Error", - "code": 2369 - }, - "A rest parameter must be of an array type.": { - "category": "Error", - "code": 2370 - }, - "A parameter initializer is only allowed in a function or constructor implementation.": { - "category": "Error", - "code": 2371 - }, - "Parameter '{0}' cannot reference itself.": { - "category": "Error", - "code": 2372 - }, - "Parameter '{0}' cannot reference identifier '{1}' declared after it.": { - "category": "Error", - "code": 2373 - }, - "Duplicate index signature for type '{0}'.": { - "category": "Error", - "code": 2374 - }, - "Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.": { - "category": "Error", - "code": 2375 - }, - "A 'super' call must be the first statement in the constructor to refer to 'super' or 'this' when a derived class contains initialized properties, parameter properties, or private identifiers.": { - "category": "Error", - "code": 2376 - }, - "Constructors for derived classes must contain a 'super' call.": { - "category": "Error", - "code": 2377 - }, - "A 'get' accessor must return a value.": { - "category": "Error", - "code": 2378 - }, - "Argument of type '{0}' is not assignable to parameter of type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.": { - "category": "Error", - "code": 2379 - }, - "Overload signatures must all be exported or non-exported.": { - "category": "Error", - "code": 2383 - }, - "Overload signatures must all be ambient or non-ambient.": { - "category": "Error", - "code": 2384 - }, - "Overload signatures must all be public, private or protected.": { - "category": "Error", - "code": 2385 - }, - "Overload signatures must all be optional or required.": { - "category": "Error", - "code": 2386 - }, - "Function overload must be static.": { - "category": "Error", - "code": 2387 - }, - "Function overload must not be static.": { - "category": "Error", - "code": 2388 - }, - "Function implementation name must be '{0}'.": { - "category": "Error", - "code": 2389 - }, - "Constructor implementation is missing.": { - "category": "Error", - "code": 2390 - }, - "Function implementation is missing or not immediately following the declaration.": { - "category": "Error", - "code": 2391 - }, - "Multiple constructor implementations are not allowed.": { - "category": "Error", - "code": 2392 - }, - "Duplicate function implementation.": { - "category": "Error", - "code": 2393 - }, - "This overload signature is not compatible with its implementation signature.": { - "category": "Error", - "code": 2394 - }, - "Individual declarations in merged declaration '{0}' must be all exported or all local.": { - "category": "Error", - "code": 2395 - }, - "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters.": { - "category": "Error", - "code": 2396 - }, - "Declaration name conflicts with built-in global identifier '{0}'.": { - "category": "Error", - "code": 2397 - }, - "'constructor' cannot be used as a parameter property name.": { - "category": "Error", - "code": 2398 - }, - "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference.": { - "category": "Error", - "code": 2399 - }, - "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference.": { - "category": "Error", - "code": 2400 - }, - "A 'super' call must be a root-level statement within a constructor of a derived class that contains initialized properties, parameter properties, or private identifiers.": { - "category": "Error", - "code": 2401 - }, - "Expression resolves to '_super' that compiler uses to capture base class reference.": { - "category": "Error", - "code": 2402 - }, - "Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.": { - "category": "Error", - "code": 2403 - }, - "The left-hand side of a 'for...in' statement cannot use a type annotation.": { - "category": "Error", - "code": 2404 - }, - "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'.": { - "category": "Error", - "code": 2405 - }, - "The left-hand side of a 'for...in' statement must be a variable or a property access.": { - "category": "Error", - "code": 2406 - }, - "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'.": { - "category": "Error", - "code": 2407 - }, - "Setters cannot return a value.": { - "category": "Error", - "code": 2408 - }, - "Return type of constructor signature must be assignable to the instance type of the class.": { - "category": "Error", - "code": 2409 - }, - "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.": { - "category": "Error", - "code": 2410 - }, - "Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.": { - "category": "Error", - "code": 2412 - }, - "Property '{0}' of type '{1}' is not assignable to '{2}' index type '{3}'.": { - "category": "Error", - "code": 2411 - }, - "'{0}' index type '{1}' is not assignable to '{2}' index type '{3}'.": { - "category": "Error", - "code": 2413 - }, - "Class name cannot be '{0}'.": { - "category": "Error", - "code": 2414 - }, - "Class '{0}' incorrectly extends base class '{1}'.": { - "category": "Error", - "code": 2415 - }, - "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.": { - "category": "Error", - "code": 2416 - }, - "Class static side '{0}' incorrectly extends base class static side '{1}'.": { - "category": "Error", - "code": 2417 - }, - "Type of computed property's value is '{0}', which is not assignable to type '{1}'.": { - "category": "Error", - "code": 2418 - }, - "Types of construct signatures are incompatible.": { - "category": "Error", - "code": 2419 - }, - "Class '{0}' incorrectly implements interface '{1}'.": { - "category": "Error", - "code": 2420 - }, - "A class can only implement an object type or intersection of object types with statically known members.": { - "category": "Error", - "code": 2422 - }, - "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor.": { - "category": "Error", - "code": 2423 - }, - "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function.": { - "category": "Error", - "code": 2425 - }, - "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function.": { - "category": "Error", - "code": 2426 - }, - "Interface name cannot be '{0}'.": { - "category": "Error", - "code": 2427 - }, - "All declarations of '{0}' must have identical type parameters.": { - "category": "Error", - "code": 2428 - }, - "Interface '{0}' incorrectly extends interface '{1}'.": { - "category": "Error", - "code": 2430 - }, - "Enum name cannot be '{0}'.": { - "category": "Error", - "code": 2431 - }, - "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.": { - "category": "Error", - "code": 2432 - }, - "A namespace declaration cannot be in a different file from a class or function with which it is merged.": { - "category": "Error", - "code": 2433 - }, - "A namespace declaration cannot be located prior to a class or function with which it is merged.": { - "category": "Error", - "code": 2434 - }, - "Ambient modules cannot be nested in other modules or namespaces.": { - "category": "Error", - "code": 2435 - }, - "Ambient module declaration cannot specify relative module name.": { - "category": "Error", - "code": 2436 - }, - "Module '{0}' is hidden by a local declaration with the same name.": { - "category": "Error", - "code": 2437 - }, - "Import name cannot be '{0}'.": { - "category": "Error", - "code": 2438 - }, - "Import or export declaration in an ambient module declaration cannot reference module through relative module name.": { - "category": "Error", - "code": 2439 - }, - "Import declaration conflicts with local declaration of '{0}'.": { - "category": "Error", - "code": 2440 - }, - "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module.": { - "category": "Error", - "code": 2441 - }, - "Types have separate declarations of a private property '{0}'.": { - "category": "Error", - "code": 2442 - }, - "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'.": { - "category": "Error", - "code": 2443 - }, - "Property '{0}' is protected in type '{1}' but public in type '{2}'.": { - "category": "Error", - "code": 2444 - }, - "Property '{0}' is protected and only accessible within class '{1}' and its subclasses.": { - "category": "Error", - "code": 2445 - }, - "Property '{0}' is protected and only accessible through an instance of class '{1}'. This is an instance of class '{2}'.": { - "category": "Error", - "code": 2446 - }, - "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead.": { - "category": "Error", - "code": 2447 - }, - "Block-scoped variable '{0}' used before its declaration.": { - "category": "Error", - "code": 2448 - }, - "Class '{0}' used before its declaration.": { - "category": "Error", - "code": 2449 - }, - "Enum '{0}' used before its declaration.": { - "category": "Error", - "code": 2450 - }, - "Cannot redeclare block-scoped variable '{0}'.": { - "category": "Error", - "code": 2451 - }, - "An enum member cannot have a numeric name.": { - "category": "Error", - "code": 2452 - }, - "Variable '{0}' is used before being assigned.": { - "category": "Error", - "code": 2454 - }, - "Type alias '{0}' circularly references itself.": { - "category": "Error", - "code": 2456 - }, - "Type alias name cannot be '{0}'.": { - "category": "Error", - "code": 2457 - }, - "An AMD module cannot have multiple name assignments.": { - "category": "Error", - "code": 2458 - }, - "Module '{0}' declares '{1}' locally, but it is not exported.": { - "category": "Error", - "code": 2459 - }, - "Module '{0}' declares '{1}' locally, but it is exported as '{2}'.": { - "category": "Error", - "code": 2460 - }, - "Type '{0}' is not an array type.": { - "category": "Error", - "code": 2461 - }, - "A rest element must be last in a destructuring pattern.": { - "category": "Error", - "code": 2462 - }, - "A binding pattern parameter cannot be optional in an implementation signature.": { - "category": "Error", - "code": 2463 - }, - "A computed property name must be of type 'string', 'number', 'symbol', or 'any'.": { - "category": "Error", - "code": 2464 - }, - "'this' cannot be referenced in a computed property name.": { - "category": "Error", - "code": 2465 - }, - "'super' cannot be referenced in a computed property name.": { - "category": "Error", - "code": 2466 - }, - "A computed property name cannot reference a type parameter from its containing type.": { - "category": "Error", - "code": 2467 - }, - "Cannot find global value '{0}'.": { - "category": "Error", - "code": 2468 - }, - "The '{0}' operator cannot be applied to type 'symbol'.": { - "category": "Error", - "code": 2469 - }, - "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher.": { - "category": "Error", - "code": 2472 - }, - "Enum declarations must all be const or non-const.": { - "category": "Error", - "code": 2473 - }, - "const enum member initializers must be constant expressions.": { - "category": "Error", - "code": 2474 - }, - "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.": { - "category": "Error", - "code": 2475 - }, - "A const enum member can only be accessed using a string literal.": { - "category": "Error", - "code": 2476 - }, - "'const' enum member initializer was evaluated to a non-finite value.": { - "category": "Error", - "code": 2477 - }, - "'const' enum member initializer was evaluated to disallowed value 'NaN'.": { - "category": "Error", - "code": 2478 - }, - "'let' is not allowed to be used as a name in 'let' or 'const' declarations.": { - "category": "Error", - "code": 2480 - }, - "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": { - "category": "Error", - "code": 2481 - }, - "The left-hand side of a 'for...of' statement cannot use a type annotation.": { - "category": "Error", - "code": 2483 - }, - "Export declaration conflicts with exported declaration of '{0}'.": { - "category": "Error", - "code": 2484 - }, - "The left-hand side of a 'for...of' statement must be a variable or a property access.": { - "category": "Error", - "code": 2487 - }, - "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator.": { - "category": "Error", - "code": 2488 - }, - "An iterator must have a 'next()' method.": { - "category": "Error", - "code": 2489 - }, - "The type returned by the '{0}()' method of an iterator must have a 'value' property.": { - "category": "Error", - "code": 2490 - }, - "The left-hand side of a 'for...in' statement cannot be a destructuring pattern.": { - "category": "Error", - "code": 2491 - }, - "Cannot redeclare identifier '{0}' in catch clause.": { - "category": "Error", - "code": 2492 - }, - "Tuple type '{0}' of length '{1}' has no element at index '{2}'.": { - "category": "Error", - "code": 2493 - }, - "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher.": { - "category": "Error", - "code": 2494 - }, - "Type '{0}' is not an array type or a string type.": { - "category": "Error", - "code": 2495 - }, - "The 'arguments' object cannot be referenced in an arrow function in ES5. Consider using a standard function expression.": { - "category": "Error", - "code": 2496 - }, - "This module can only be referenced with ECMAScript imports/exports by turning on the '{0}' flag and referencing its default export.": { - "category": "Error", - "code": 2497 - }, - "Module '{0}' uses 'export =' and cannot be used with 'export *'.": { - "category": "Error", - "code": 2498 - }, - "An interface can only extend an identifier/qualified-name with optional type arguments.": { - "category": "Error", - "code": 2499 - }, - "A class can only implement an identifier/qualified-name with optional type arguments.": { - "category": "Error", - "code": 2500 - }, - "A rest element cannot contain a binding pattern.": { - "category": "Error", - "code": 2501 - }, - "'{0}' is referenced directly or indirectly in its own type annotation.": { - "category": "Error", - "code": 2502 - }, - "Cannot find namespace '{0}'.": { - "category": "Error", - "code": 2503 - }, - "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.": { - "category": "Error", - "code": 2504 - }, - "A generator cannot have a 'void' type annotation.": { - "category": "Error", - "code": 2505 - }, - "'{0}' is referenced directly or indirectly in its own base expression.": { - "category": "Error", - "code": 2506 - }, - "Type '{0}' is not a constructor function type.": { - "category": "Error", - "code": 2507 - }, - "No base constructor has the specified number of type arguments.": { - "category": "Error", - "code": 2508 - }, - "Base constructor return type '{0}' is not an object type or intersection of object types with statically known members.": { - "category": "Error", - "code": 2509 - }, - "Base constructors must all have the same return type.": { - "category": "Error", - "code": 2510 - }, - "Cannot create an instance of an abstract class.": { - "category": "Error", - "code": 2511 - }, - "Overload signatures must all be abstract or non-abstract.": { - "category": "Error", - "code": 2512 - }, - "Abstract method '{0}' in class '{1}' cannot be accessed via super expression.": { - "category": "Error", - "code": 2513 - }, - "A tuple type cannot be indexed with a negative value.": { - "category": "Error", - "code": 2514 - }, - "Non-abstract class '{0}' does not implement inherited abstract member {1} from class '{2}'.": { - "category": "Error", - "code": 2515 - }, - "All declarations of an abstract method must be consecutive.": { - "category": "Error", - "code": 2516 - }, - "Cannot assign an abstract constructor type to a non-abstract constructor type.": { - "category": "Error", - "code": 2517 - }, - "A 'this'-based type guard is not compatible with a parameter-based type guard.": { - "category": "Error", - "code": 2518 - }, - "An async iterator must have a 'next()' method.": { - "category": "Error", - "code": 2519 - }, - "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": { - "category": "Error", - "code": 2520 - }, - "The 'arguments' object cannot be referenced in an async function or method in ES5. Consider using a standard function or method.": { - "category": "Error", - "code": 2522 - }, - "'yield' expressions cannot be used in a parameter initializer.": { - "category": "Error", - "code": 2523 - }, - "'await' expressions cannot be used in a parameter initializer.": { - "category": "Error", - "code": 2524 - }, - "A 'this' type is available only in a non-static member of a class or interface.": { - "category": "Error", - "code": 2526 - }, - "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.": { - "category": "Error", - "code": 2527 - }, - "A module cannot have multiple default exports.": { - "category": "Error", - "code": 2528 - }, - "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions.": { - "category": "Error", - "code": 2529 - }, - "Property '{0}' is incompatible with index signature.": { - "category": "Error", - "code": 2530 - }, - "Object is possibly 'null'.": { - "category": "Error", - "code": 2531 - }, - "Object is possibly 'undefined'.": { - "category": "Error", - "code": 2532 - }, - "Object is possibly 'null' or 'undefined'.": { - "category": "Error", - "code": 2533 - }, - "A function returning 'never' cannot have a reachable end point.": { - "category": "Error", - "code": 2534 - }, - "Type '{0}' cannot be used to index type '{1}'.": { - "category": "Error", - "code": 2536 - }, - "Type '{0}' has no matching index signature for type '{1}'.": { - "category": "Error", - "code": 2537 - }, - "Type '{0}' cannot be used as an index type.": { - "category": "Error", - "code": 2538 - }, - "Cannot assign to '{0}' because it is not a variable.": { - "category": "Error", - "code": 2539 - }, - "Cannot assign to '{0}' because it is a read-only property.": { - "category": "Error", - "code": 2540 - }, - "Index signature in type '{0}' only permits reading.": { - "category": "Error", - "code": 2542 - }, - "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference.": { - "category": "Error", - "code": 2543 - }, - "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference.": { - "category": "Error", - "code": 2544 - }, - "A mixin class must have a constructor with a single rest parameter of type 'any[]'.": { - "category": "Error", - "code": 2545 - }, - "The type returned by the '{0}()' method of an async iterator must be a promise for a type with a 'value' property.": { - "category": "Error", - "code": 2547 - }, - "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { - "category": "Error", - "code": 2548 - }, - "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { - "category": "Error", - "code": 2549 - }, - "Property '{0}' does not exist on type '{1}'. Do you need to change your target library? Try changing the 'lib' compiler option to '{2}' or later.": { - "category": "Error", - "code": 2550 - }, - "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?": { - "category": "Error", - "code": 2551 - }, - "Cannot find name '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 2552 - }, - "Computed values are not permitted in an enum with string valued members.": { - "category": "Error", - "code": 2553 - }, - "Expected {0} arguments, but got {1}.": { - "category": "Error", - "code": 2554 - }, - "Expected at least {0} arguments, but got {1}.": { - "category": "Error", - "code": 2555 - }, - "A spread argument must either have a tuple type or be passed to a rest parameter.": { - "category": "Error", - "code": 2556 - }, - "Expected {0} type arguments, but got {1}.": { - "category": "Error", - "code": 2558 - }, - "Type '{0}' has no properties in common with type '{1}'.": { - "category": "Error", - "code": 2559 - }, - "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?": { - "category": "Error", - "code": 2560 - }, - "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?": { - "category": "Error", - "code": 2561 - }, - "Base class expressions cannot reference class type parameters.": { - "category": "Error", - "code": 2562 - }, - "The containing function or module body is too large for control flow analysis.": { - "category": "Error", - "code": 2563 - }, - "Property '{0}' has no initializer and is not definitely assigned in the constructor.": { - "category": "Error", - "code": 2564 - }, - "Property '{0}' is used before being assigned.": { - "category": "Error", - "code": 2565 - }, - "A rest element cannot have a property name.": { - "category": "Error", - "code": 2566 - }, - "Enum declarations can only merge with namespace or other enum declarations.": { - "category": "Error", - "code": 2567 - }, - "Property '{0}' may not exist on type '{1}'. Did you mean '{2}'?": { - "category": "Error", - "code": 2568 - }, - - "Could not find name '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 2570 - }, - "Object is of type 'unknown'.": { - "category": "Error", - "code": 2571 - }, - "A rest element type must be an array type.": { - "category": "Error", - "code": 2574 - }, - "No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments.": { - "category": "Error", - "code": 2575 - }, - "Property '{0}' does not exist on type '{1}'. Did you mean to access the static member '{2}' instead?": { - "category": "Error", - "code": 2576 - }, - "Return type annotation circularly references itself.": { - "category": "Error", - "code": 2577 - }, - "Unused '@ts-expect-error' directive.": { - "category": "Error", - "code": 2578 - }, - "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.": { - "category": "Error", - "code": 2580 - }, - "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`.": { - "category": "Error", - "code": 2581 - }, - "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.": { - "category": "Error", - "code": 2582 - }, - "Cannot find name '{0}'. Do you need to change your target library? Try changing the 'lib' compiler option to '{1}' or later.": { - "category": "Error", - "code": 2583 - }, - "Cannot find name '{0}'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.": { - "category": "Error", - "code": 2584 - }, - "'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later.": { - "category": "Error", - "code": 2585 - }, - "Cannot assign to '{0}' because it is a constant.": { - "category": "Error", - "code": 2588 - }, - "Type instantiation is excessively deep and possibly infinite.": { - "category": "Error", - "code": 2589 - }, - "Expression produces a union type that is too complex to represent.": { - "category": "Error", - "code": 2590 - }, - "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.": { - "category": "Error", - "code": 2591 - }, - "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig.": { - "category": "Error", - "code": 2592 - }, - "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig.": { - "category": "Error", - "code": 2593 - }, - "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag.": { - "category": "Error", - "code": 2594 - }, - "'{0}' can only be imported by using a default import.": { - "category": "Error", - "code": 2595 - }, - "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import.": { - "category": "Error", - "code": 2596 - }, - "'{0}' can only be imported by using a 'require' call or by using a default import.": { - "category": "Error", - "code": 2597 - }, - "'{0}' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import.": { - "category": "Error", - "code": 2598 - }, - "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.": { - "category": "Error", - "code": 2602 - }, - "Property '{0}' in type '{1}' is not assignable to type '{2}'.": { - "category": "Error", - "code": 2603 - }, - "JSX element type '{0}' does not have any construct or call signatures.": { - "category": "Error", - "code": 2604 - }, - "Property '{0}' of JSX spread attribute is not assignable to target property.": { - "category": "Error", - "code": 2606 - }, - "JSX element class does not support attributes because it does not have a '{0}' property.": { - "category": "Error", - "code": 2607 - }, - "The global type 'JSX.{0}' may not have more than one property.": { - "category": "Error", - "code": 2608 - }, - "JSX spread child must be an array type.": { - "category": "Error", - "code": 2609 - }, - "'{0}' is defined as an accessor in class '{1}', but is overridden here in '{2}' as an instance property.": { - "category": "Error", - "code": 2610 - }, - "'{0}' is defined as a property in class '{1}', but is overridden here in '{2}' as an accessor.": { - "category": "Error", - "code": 2611 - }, - "Property '{0}' will overwrite the base property in '{1}'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration.": { - "category": "Error", - "code": 2612 - }, - "Module '{0}' has no default export. Did you mean to use 'import { {1} } from {0}' instead?": { - "category": "Error", - "code": 2613 - }, - "Module '{0}' has no exported member '{1}'. Did you mean to use 'import {1} from {0}' instead?": { - "category": "Error", - "code": 2614 - }, - "Type of property '{0}' circularly references itself in mapped type '{1}'.": { - "category": "Error", - "code": 2615 - }, - "'{0}' can only be imported by using 'import {1} = require({2})' or a default import.": { - "category": "Error", - "code": 2616 - }, - "'{0}' can only be imported by using 'import {1} = require({2})' or by turning on the 'esModuleInterop' flag and using a default import.": { - "category": "Error", - "code": 2617 - }, - "Source has {0} element(s) but target requires {1}.": { - "category": "Error", - "code": 2618 - }, - "Source has {0} element(s) but target allows only {1}.": { - "category": "Error", - "code": 2619 - }, - "Target requires {0} element(s) but source may have fewer.": { - "category": "Error", - "code": 2620 - }, - "Target allows only {0} element(s) but source may have more.": { - "category": "Error", - "code": 2621 - }, - "Source provides no match for required element at position {0} in target.": { - "category": "Error", - "code": 2623 - }, - "Source provides no match for variadic element at position {0} in target.": { - "category": "Error", - "code": 2624 - }, - "Variadic element at position {0} in source does not match element at position {1} in target.": { - "category": "Error", - "code": 2625 - }, - "Type at position {0} in source is not compatible with type at position {1} in target.": { - "category": "Error", - "code": 2626 - }, - "Type at positions {0} through {1} in source is not compatible with type at position {2} in target.": { - "category": "Error", - "code": 2627 - }, - "Cannot assign to '{0}' because it is an enum.": { - "category": "Error", - "code": 2628 - }, - "Cannot assign to '{0}' because it is a class.": { - "category": "Error", - "code": 2629 - }, - "Cannot assign to '{0}' because it is a function.": { - "category": "Error", - "code": 2630 - }, - "Cannot assign to '{0}' because it is a namespace.": { - "category": "Error", - "code": 2631 - }, - "Cannot assign to '{0}' because it is an import.": { - "category": "Error", - "code": 2632 - }, - "JSX property access expressions cannot include JSX namespace names": { - "category": "Error", - "code": 2633 - }, - "'{0}' index signatures are incompatible.": { - "category": "Error", - "code": 2634 - }, - "Type '{0}' has no signatures for which the type argument list is applicable.": { - "category": "Error", - "code": 2635 - }, - "Type '{0}' is not assignable to type '{1}' as implied by variance annotation.": { - "category": "Error", - "code": 2636 - }, - "Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.": { - "category": "Error", - "code": 2637 - }, - "Type '{0}' may represent a primitive value, which is not permitted as the right operand of the 'in' operator.": { - "category": "Error", - "code": 2638 - }, - "React components cannot include JSX namespace names": { - "category": "Error", - "code": 2639 - }, - - "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { - "category": "Error", - "code": 2649 - }, - "Non-abstract class expression is missing implementations for the following members of '{0}': {1} and {2} more.": { - "category": "Error", - "code": 2650 - }, - "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": { - "category": "Error", - "code": 2651 - }, - "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": { - "category": "Error", - "code": 2652 - }, - "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'.": { - "category": "Error", - "code": 2653 - }, - "Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2}.": { - "category": "Error", - "code": 2654 - }, - "Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2} and {3} more.": { - "category": "Error", - "code": 2655 - }, - "Non-abstract class expression is missing implementations for the following members of '{0}': {1}.": { - "category": "Error", - "code": 2656 - }, - "JSX expressions must have one parent element.": { - "category": "Error", - "code": 2657 - }, - "Type '{0}' provides no match for the signature '{1}'.": { - "category": "Error", - "code": 2658 - }, - "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher.": { - "category": "Error", - "code": 2659 - }, - "'super' can only be referenced in members of derived classes or object literal expressions.": { - "category": "Error", - "code": 2660 - }, - "Cannot export '{0}'. Only local declarations can be exported from a module.": { - "category": "Error", - "code": 2661 - }, - "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?": { - "category": "Error", - "code": 2662 - }, - "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?": { - "category": "Error", - "code": 2663 - }, - "Invalid module name in augmentation, module '{0}' cannot be found.": { - "category": "Error", - "code": 2664 - }, - "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented.": { - "category": "Error", - "code": 2665 - }, - "Exports and export assignments are not permitted in module augmentations.": { - "category": "Error", - "code": 2666 - }, - "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module.": { - "category": "Error", - "code": 2667 - }, - "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible.": { - "category": "Error", - "code": 2668 - }, - "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.": { - "category": "Error", - "code": 2669 - }, - "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.": { - "category": "Error", - "code": 2670 - }, - "Cannot augment module '{0}' because it resolves to a non-module entity.": { - "category": "Error", - "code": 2671 - }, - "Cannot assign a '{0}' constructor type to a '{1}' constructor type.": { - "category": "Error", - "code": 2672 - }, - "Constructor of class '{0}' is private and only accessible within the class declaration.": { - "category": "Error", - "code": 2673 - }, - "Constructor of class '{0}' is protected and only accessible within the class declaration.": { - "category": "Error", - "code": 2674 - }, - "Cannot extend a class '{0}'. Class constructor is marked as private.": { - "category": "Error", - "code": 2675 - }, - "Accessors must both be abstract or non-abstract.": { - "category": "Error", - "code": 2676 - }, - "A type predicate's type must be assignable to its parameter's type.": { - "category": "Error", - "code": 2677 - }, - "Type '{0}' is not comparable to type '{1}'.": { - "category": "Error", - "code": 2678 - }, - "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'.": { - "category": "Error", - "code": 2679 - }, - "A '{0}' parameter must be the first parameter.": { - "category": "Error", - "code": 2680 - }, - "A constructor cannot have a 'this' parameter.": { - "category": "Error", - "code": 2681 - }, - "'this' implicitly has type 'any' because it does not have a type annotation.": { - "category": "Error", - "code": 2683 - }, - "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'.": { - "category": "Error", - "code": 2684 - }, - "The 'this' types of each signature are incompatible.": { - "category": "Error", - "code": 2685 - }, - "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.": { - "category": "Error", - "code": 2686 - }, - "All declarations of '{0}' must have identical modifiers.": { - "category": "Error", - "code": 2687 - }, - "Cannot find type definition file for '{0}'.": { - "category": "Error", - "code": 2688 - }, - "Cannot extend an interface '{0}'. Did you mean 'implements'?": { - "category": "Error", - "code": 2689 - }, - "'{0}' only refers to a type, but is being used as a value here. Did you mean to use '{1} in {0}'?": { - "category": "Error", - "code": 2690 - }, - "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible.": { - "category": "Error", - "code": 2692 - }, - "'{0}' only refers to a type, but is being used as a value here.": { - "category": "Error", - "code": 2693 - }, - "Namespace '{0}' has no exported member '{1}'.": { - "category": "Error", - "code": 2694 - }, - "Left side of comma operator is unused and has no side effects.": { - "category": "Error", - "code": 2695, - "reportsUnnecessary": true - }, - "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?": { - "category": "Error", - "code": 2696 - }, - "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your '--lib' option.": { - "category": "Error", - "code": 2697 - }, - "Spread types may only be created from object types.": { - "category": "Error", - "code": 2698 - }, - "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'.": { - "category": "Error", - "code": 2699 - }, - "Rest types may only be created from object types.": { - "category": "Error", - "code": 2700 - }, - "The target of an object rest assignment must be a variable or a property access.": { - "category": "Error", - "code": 2701 - }, - "'{0}' only refers to a type, but is being used as a namespace here.": { - "category": "Error", - "code": 2702 - }, - "The operand of a 'delete' operator must be a property reference.": { - "category": "Error", - "code": 2703 - }, - "The operand of a 'delete' operator cannot be a read-only property.": { - "category": "Error", - "code": 2704 - }, - "An async function or method in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.": { - "category": "Error", - "code": 2705 - }, - "Required type parameters may not follow optional type parameters.": { - "category": "Error", - "code": 2706 - }, - "Generic type '{0}' requires between {1} and {2} type arguments.": { - "category": "Error", - "code": 2707 - }, - "Cannot use namespace '{0}' as a value.": { - "category": "Error", - "code": 2708 - }, - "Cannot use namespace '{0}' as a type.": { - "category": "Error", - "code": 2709 - }, - "'{0}' are specified twice. The attribute named '{0}' will be overwritten.": { - "category": "Error", - "code": 2710 - }, - "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your '--lib' option.": { - "category": "Error", - "code": 2711 - }, - "A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.": { - "category": "Error", - "code": 2712 - }, - "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?": { - "category": "Error", - "code": 2713 - }, - "The expression of an export assignment must be an identifier or qualified name in an ambient context.": { - "category": "Error", - "code": 2714 - }, - "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.": { - "category": "Error", - "code": 2715 - }, - "Type parameter '{0}' has a circular default.": { - "category": "Error", - "code": 2716 - }, - "Subsequent property declarations must have the same type. Property '{0}' must be of type '{1}', but here has type '{2}'.": { - "category": "Error", - "code": 2717 - }, - "Duplicate property '{0}'.": { - "category": "Error", - "code": 2718 - }, - "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated.": { - "category": "Error", - "code": 2719 - }, - "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?": { - "category": "Error", - "code": 2720 - }, - "Cannot invoke an object which is possibly 'null'.": { - "category": "Error", - "code": 2721 - }, - "Cannot invoke an object which is possibly 'undefined'.": { - "category": "Error", - "code": 2722 - }, - "Cannot invoke an object which is possibly 'null' or 'undefined'.": { - "category": "Error", - "code": 2723 - }, - "'{0}' has no exported member named '{1}'. Did you mean '{2}'?": { - "category": "Error", - "code": 2724 - }, - "Class name cannot be 'Object' when targeting ES5 and above with module {0}.": { - "category": "Error", - "code": 2725 - }, - "Cannot find lib definition for '{0}'.": { - "category": "Error", - "code": 2726 - }, - "Cannot find lib definition for '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 2727 - }, - "'{0}' is declared here.": { - "category": "Message", - "code": 2728 - }, - "Property '{0}' is used before its initialization.": { - "category": "Error", - "code": 2729 - }, - "An arrow function cannot have a 'this' parameter.": { - "category": "Error", - "code": 2730 - }, - "Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.": { - "category": "Error", - "code": 2731 - }, - "Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension.": { - "category": "Error", - "code": 2732 - }, - "Property '{0}' was also declared here.": { - "category": "Error", - "code": 2733 - }, - "Are you missing a semicolon?": { - "category": "Error", - "code": 2734 - }, - "Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?": { - "category": "Error", - "code": 2735 - }, - "Operator '{0}' cannot be applied to type '{1}'.": { - "category": "Error", - "code": 2736 - }, - "BigInt literals are not available when targeting lower than ES2020.": { - "category": "Error", - "code": 2737 - }, - "An outer value of 'this' is shadowed by this container.": { - "category": "Message", - "code": 2738 - }, - "Type '{0}' is missing the following properties from type '{1}': {2}": { - "category": "Error", - "code": 2739 - }, - "Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more.": { - "category": "Error", - "code": 2740 - }, - "Property '{0}' is missing in type '{1}' but required in type '{2}'.": { - "category": "Error", - "code": 2741 - }, - "The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary.": { - "category": "Error", - "code": 2742 - }, - "No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments.": { - "category": "Error", - "code": 2743 - }, - "Type parameter defaults can only reference previously declared type parameters.": { - "category": "Error", - "code": 2744 - }, - "This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided.": { - "category": "Error", - "code": 2745 - }, - "This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided.": { - "category": "Error", - "code": 2746 - }, - "'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'.": { - "category": "Error", - "code": 2747 - }, - "Cannot access ambient const enums when '{0}' is enabled.": { - "category": "Error", - "code": 2748 - }, - "'{0}' refers to a value, but is being used as a type here. Did you mean 'typeof {0}'?": { - "category": "Error", - "code": 2749 - }, - "The implementation signature is declared here.": { - "category": "Error", - "code": 2750 - }, - "Circularity originates in type at this location.": { - "category": "Error", - "code": 2751 - }, - "The first export default is here.": { - "category": "Error", - "code": 2752 - }, - "Another export default is here.": { - "category": "Error", - "code": 2753 - }, - "'super' may not use type arguments.": { - "category": "Error", - "code": 2754 - }, - "No constituent of type '{0}' is callable.": { - "category": "Error", - "code": 2755 - }, - "Not all constituents of type '{0}' are callable.": { - "category": "Error", - "code": 2756 - }, - "Type '{0}' has no call signatures.": { - "category": "Error", - "code": 2757 - }, - "Each member of the union type '{0}' has signatures, but none of those signatures are compatible with each other.": { - "category": "Error", - "code": 2758 - }, - "No constituent of type '{0}' is constructable.": { - "category": "Error", - "code": 2759 - }, - "Not all constituents of type '{0}' are constructable.": { - "category": "Error", - "code": 2760 - }, - "Type '{0}' has no construct signatures.": { - "category": "Error", - "code": 2761 - }, - "Each member of the union type '{0}' has construct signatures, but none of those signatures are compatible with each other.": { - "category": "Error", - "code": 2762 - }, - "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'.": { - "category": "Error", - "code": 2763 - }, - "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'.": { - "category": "Error", - "code": 2764 - }, - "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array destructuring will always send '{0}'.": { - "category": "Error", - "code": 2765 - }, - "Cannot delegate iteration to value because the 'next' method of its iterator expects type '{1}', but the containing generator will always send '{0}'.": { - "category": "Error", - "code": 2766 - }, - "The '{0}' property of an iterator must be a method.": { - "category": "Error", - "code": 2767 - }, - "The '{0}' property of an async iterator must be a method.": { - "category": "Error", - "code": 2768 - }, - "No overload matches this call.": { - "category": "Error", - "code": 2769 - }, - "The last overload gave the following error.": { - "category": "Error", - "code": 2770 - }, - "The last overload is declared here.": { - "category": "Error", - "code": 2771 - }, - "Overload {0} of {1}, '{2}', gave the following error.": { - "category": "Error", - "code": 2772 - }, - "Did you forget to use 'await'?": { - "category": "Error", - "code": 2773 - }, - "This condition will always return true since this function is always defined. Did you mean to call it instead?": { - "category": "Error", - "code": 2774 - }, - "Assertions require every name in the call target to be declared with an explicit type annotation.": { - "category": "Error", - "code": 2775 - }, - "Assertions require the call target to be an identifier or qualified name.": { - "category": "Error", - "code": 2776 - }, - "The operand of an increment or decrement operator may not be an optional property access.": { - "category": "Error", - "code": 2777 - }, - "The target of an object rest assignment may not be an optional property access.": { - "category": "Error", - "code": 2778 - }, - "The left-hand side of an assignment expression may not be an optional property access.": { - "category": "Error", - "code": 2779 - }, - "The left-hand side of a 'for...in' statement may not be an optional property access.": { - "category": "Error", - "code": 2780 - }, - "The left-hand side of a 'for...of' statement may not be an optional property access.": { - "category": "Error", - "code": 2781 - }, - "'{0}' needs an explicit type annotation.": { - "category": "Message", - "code": 2782 - }, - "'{0}' is specified more than once, so this usage will be overwritten.": { - "category": "Error", - "code": 2783 - }, - "'get' and 'set' accessors cannot declare 'this' parameters.": { - "category": "Error", - "code": 2784 - }, - "This spread always overwrites this property.": { - "category": "Error", - "code": 2785 - }, - "'{0}' cannot be used as a JSX component.": { - "category": "Error", - "code": 2786 - }, - "Its return type '{0}' is not a valid JSX element.": { - "category": "Error", - "code": 2787 - }, - "Its instance type '{0}' is not a valid JSX element.": { - "category": "Error", - "code": 2788 - }, - "Its element type '{0}' is not a valid JSX element.": { - "category": "Error", - "code": 2789 - }, - "The operand of a 'delete' operator must be optional.": { - "category": "Error", - "code": 2790 - }, - "Exponentiation cannot be performed on 'bigint' values unless the 'target' option is set to 'es2016' or later.": { - "category": "Error", - "code": 2791 - }, - "Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?": { - "category": "Error", - "code": 2792 - }, - "The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.": { - "category": "Error", - "code": 2793 - }, - "Expected {0} arguments, but got {1}. Did you forget to include 'void' in your type argument to 'Promise'?": { - "category": "Error", - "code": 2794 - }, - "The 'intrinsic' keyword can only be used to declare compiler provided intrinsic types.": { - "category": "Error", - "code": 2795 - }, - "It is likely that you are missing a comma to separate these two template expressions. They form a tagged template expression which cannot be invoked.": { - "category": "Error", - "code": 2796 - }, - "A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'.": { - "category": "Error", - "code": 2797 - }, - "The declaration was marked as deprecated here.": { - "category": "Error", - "code": 2798 - }, - "Type produces a tuple type that is too large to represent.": { - "category": "Error", - "code": 2799 - }, - "Expression produces a tuple type that is too large to represent.": { - "category": "Error", - "code": 2800 - }, - "This condition will always return true since this '{0}' is always defined.": { - "category": "Error", - "code": 2801 - }, - "Type '{0}' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.": { - "category": "Error", - "code": 2802 - }, - "Cannot assign to private method '{0}'. Private methods are not writable.": { - "category": "Error", - "code": 2803 - }, - "Duplicate identifier '{0}'. Static and instance elements cannot share the same private name.": { - "category": "Error", - "code": 2804 - }, - "Private accessor was defined without a getter.": { - "category": "Error", - "code": 2806 - }, - "This syntax requires an imported helper named '{1}' with {2} parameters, which is not compatible with the one in '{0}'. Consider upgrading your version of '{0}'.": { - "category": "Error", - "code": 2807 - }, - "A get accessor must be at least as accessible as the setter": { - "category": "Error", - "code": 2808 - }, - "Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the whole assignment in parentheses.": { - "category": "Error", - "code": 2809 - }, - "Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.": { - "category": "Error", - "code": 2810 - }, - "Initializer for property '{0}'": { - "category": "Error", - "code": 2811 - }, - "Property '{0}' does not exist on type '{1}'. Try changing the 'lib' compiler option to include 'dom'.": { - "category": "Error", - "code": 2812 - }, - "Class declaration cannot implement overload list for '{0}'.": { - "category": "Error", - "code": 2813 - }, - "Function with bodies can only merge with classes that are ambient.": { - "category": "Error", - "code": 2814 - }, - "'arguments' cannot be referenced in property initializers or class static initialization blocks.": { - "category": "Error", - "code": 2815 - }, - "Cannot use 'this' in a static property initializer of a decorated class.": { - "category": "Error", - "code": 2816 - }, - "Property '{0}' has no initializer and is not definitely assigned in a class static block.": { - "category": "Error", - "code": 2817 - }, - "Duplicate identifier '{0}'. Compiler reserves name '{1}' when emitting 'super' references in static initializers.": { - "category": "Error", - "code": 2818 - }, - "Namespace name cannot be '{0}'.": { - "category": "Error", - "code": 2819 - }, - "Type '{0}' is not assignable to type '{1}'. Did you mean '{2}'?": { - "category": "Error", - "code": 2820 - }, - "Import assertions are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'.": { - "category": "Error", - "code": 2821 - }, - "Import assertions cannot be used with type-only imports or exports.": { - "category": "Error", - "code": 2822 - }, - "Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'.": { - "category": "Error", - "code": 2823 - }, - "Cannot find namespace '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 2833 - }, - "Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path.": { - "category": "Error", - "code": 2834 - }, - "Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '{0}'?": { - "category": "Error", - "code": 2835 - }, - "Import assertions are not allowed on statements that compile to CommonJS 'require' calls.": { - "category": "Error", - "code": 2836 - }, - "Import assertion values must be string literal expressions.": { - "category": "Error", - "code": 2837 - }, - "All declarations of '{0}' must have identical constraints.": { - "category": "Error", - "code": 2838 - }, - "This condition will always return '{0}' since JavaScript compares objects by reference, not value.": { - "category": "Error", - "code": 2839 - }, - "An interface cannot extend a primitive type like '{0}'. It can only extend other named object types.": { - "category": "Error", - "code": 2840 - }, - "'{0}' is an unused renaming of '{1}'. Did you intend to use it as a type annotation?": { - "category": "Error", - "code": 2842 - }, - "We can only write a type for '{0}' by adding a type for the entire parameter here.": { - "category": "Error", - "code": 2843 - }, - "Type of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": { - "category": "Error", - "code": 2844 - }, - "This condition will always return '{0}'.": { - "category": "Error", - "code": 2845 - }, - "A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file '{0}' instead?": { - "category": "Error", - "code": 2846 - }, - "The right-hand side of an 'instanceof' expression must not be an instantiation expression.": { - "category": "Error", - "code": 2848 - }, - "Target signature provides too few arguments. Expected {0} or more, but got {1}.": { - "category": "Error", - "code": 2849 - }, - "The initializer of a 'using' declaration must be either an object with a '[Symbol.dispose]()' method, or be 'null' or 'undefined'.": { - "category": "Error", - "code": 2850 - }, - "The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'.": { - "category": "Error", - "code": 2851 - }, - "'await using' statements are only allowed within async functions and at the top levels of modules.": { - "category": "Error", - "code": 2852 - }, - "'await using' statements are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { - "category": "Error", - "code": 2853 - }, - "Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.": { - "category": "Error", - "code": 2854 - }, - "Class field '{0}' defined by the parent class is not accessible in the child class via super.": { - "category": "Error", - "code": 2855 - }, - "Import attributes are not allowed on statements that compile to CommonJS 'require' calls.": { - "category": "Error", - "code": 2856 - }, - "Import attributes cannot be used with type-only imports or exports.": { - "category": "Error", - "code": 2857 - }, - "Import attribute values must be string literal expressions.": { - "category": "Error", - "code": 2858 - }, - "Excessive complexity comparing types '{0}' and '{1}'.": { - "category": "Error", - "code": 2859 - }, - "The left-hand side of an 'instanceof' expression must be assignable to the first argument of the right-hand side's '[Symbol.hasInstance]' method.": { - "category": "Error", - "code": 2860 - }, - "An object's '[Symbol.hasInstance]' method must return a boolean value for it to be used on the right-hand side of an 'instanceof' expression.": { - "category": "Error", - "code": 2861 - }, - "Type '{0}' is generic and can only be indexed for reading.": { - "category": "Error", - "code": 2862 - }, - "A class cannot extend a primitive type like '{0}'. Classes can only extend constructable values.": { - "category": "Error", - "code": 2863 - }, - "A class cannot implement a primitive type like '{0}'. It can only implement other named object types.": { - "category": "Error", - "code": 2864 - }, - "Import '{0}' conflicts with local value, so must be declared with a type-only import when 'isolatedModules' is enabled.": { - "category": "Error", - "code": 2865 - }, - "Import '{0}' conflicts with global value used in this file, so must be declared with a type-only import when 'isolatedModules' is enabled.": { - "category": "Error", - "code": 2866 - }, - "Cannot find name '{0}'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`.": { - "category": "Error", - "code": 2867 - }, - "Cannot find name '{0}'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun` and then add 'bun' to the types field in your tsconfig.": { - "category": "Error", - "code": 2868 - }, - "Right operand of ?? is unreachable because the left operand is never nullish.": { - "category": "Error", - "code": 2869 - }, - "This binary expression is never nullish. Are you missing parentheses?": { - "category": "Error", - "code": 2870 - }, - "This expression is always nullish.": { - "category": "Error", - "code": 2871 - }, - "This kind of expression is always truthy.": { - "category": "Error", - "code": 2872 - }, - "This kind of expression is always falsy.": { - "category": "Error", - "code": 2873 - }, - "This JSX tag requires '{0}' to be in scope, but it could not be found.": { - "category": "Error", - "code": 2874 - }, - "This JSX tag requires the module path '{0}' to exist, but none could be found. Make sure you have types for the appropriate package installed.": { - "category": "Error", - "code": 2875 - }, - "This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to \"{0}\".": { - "category": "Error", - "code": 2876 - }, - "This import uses a '{0}' extension to resolve to an input TypeScript file, but will not be rewritten during emit because it is not a relative path.": { - "category": "Error", - "code": 2877 - }, - "This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files.": { - "category": "Error", - "code": 2878 - }, - "Using JSX fragments requires fragment factory '{0}' to be in scope, but it could not be found.": { - "category": "Error", - "code": 2879 - }, - "Import assertions have been replaced by import attributes. Use 'with' instead of 'assert'.": { - "category": "Error", - "code": 2880 - }, - "This expression is never nullish.": { - "category": "Error", - "code": 2881 - }, - "Cannot find module or type declarations for side-effect import of '{0}'.": { - "category": "Error", - "code": 2882 - }, - "The inferred type of '{0}' cannot be named without a reference to '{2}' from '{1}'. This is likely not portable. A type annotation is necessary.": { - "category": "Error", - "code": 2883 - }, - - "Import declaration '{0}' is using private name '{1}'.": { - "category": "Error", - "code": 4000 - }, - "Type parameter '{0}' of exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4002 - }, - "Type parameter '{0}' of exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4004 - }, - "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4006 - }, - "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4008 - }, - "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4010 - }, - "Type parameter '{0}' of public method from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4012 - }, - "Type parameter '{0}' of method from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4014 - }, - "Type parameter '{0}' of exported function has or is using private name '{1}'.": { - "category": "Error", - "code": 4016 - }, - "Implements clause of exported class '{0}' has or is using private name '{1}'.": { - "category": "Error", - "code": 4019 - }, - "'extends' clause of exported class '{0}' has or is using private name '{1}'.": { - "category": "Error", - "code": 4020 - }, - "'extends' clause of exported class has or is using private name '{0}'.": { - "category": "Error", - "code": 4021 - }, - "'extends' clause of exported interface '{0}' has or is using private name '{1}'.": { - "category": "Error", - "code": 4022 - }, - "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4023 - }, - "Exported variable '{0}' has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4024 - }, - "Exported variable '{0}' has or is using private name '{1}'.": { - "category": "Error", - "code": 4025 - }, - "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4026 - }, - "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4027 - }, - "Public static property '{0}' of exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4028 - }, - "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4029 - }, - "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4030 - }, - "Public property '{0}' of exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4031 - }, - "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4032 - }, - "Property '{0}' of exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4033 - }, - "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4034 - }, - "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4035 - }, - "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4036 - }, - "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4037 - }, - "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4038 - }, - "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4039 - }, - "Return type of public static getter '{0}' from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4040 - }, - "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4041 - }, - "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4042 - }, - "Return type of public getter '{0}' from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4043 - }, - "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4044 - }, - "Return type of constructor signature from exported interface has or is using private name '{0}'.": { - "category": "Error", - "code": 4045 - }, - "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4046 - }, - "Return type of call signature from exported interface has or is using private name '{0}'.": { - "category": "Error", - "code": 4047 - }, - "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4048 - }, - "Return type of index signature from exported interface has or is using private name '{0}'.": { - "category": "Error", - "code": 4049 - }, - "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named.": { - "category": "Error", - "code": 4050 - }, - "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4051 - }, - "Return type of public static method from exported class has or is using private name '{0}'.": { - "category": "Error", - "code": 4052 - }, - "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named.": { - "category": "Error", - "code": 4053 - }, - "Return type of public method from exported class has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4054 - }, - "Return type of public method from exported class has or is using private name '{0}'.": { - "category": "Error", - "code": 4055 - }, - "Return type of method from exported interface has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4056 - }, - "Return type of method from exported interface has or is using private name '{0}'.": { - "category": "Error", - "code": 4057 - }, - "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named.": { - "category": "Error", - "code": 4058 - }, - "Return type of exported function has or is using name '{0}' from private module '{1}'.": { - "category": "Error", - "code": 4059 - }, - "Return type of exported function has or is using private name '{0}'.": { - "category": "Error", - "code": 4060 - }, - "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4061 - }, - "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4062 - }, - "Parameter '{0}' of constructor from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4063 - }, - "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4064 - }, - "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4065 - }, - "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4066 - }, - "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4067 - }, - "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4068 - }, - "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4069 - }, - "Parameter '{0}' of public static method from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4070 - }, - "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4071 - }, - "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4072 - }, - "Parameter '{0}' of public method from exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4073 - }, - "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4074 - }, - "Parameter '{0}' of method from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4075 - }, - "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4076 - }, - "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4077 - }, - "Parameter '{0}' of exported function has or is using private name '{1}'.": { - "category": "Error", - "code": 4078 - }, - "Exported type alias '{0}' has or is using private name '{1}'.": { - "category": "Error", - "code": 4081 - }, - "Default export of the module has or is using private name '{0}'.": { - "category": "Error", - "code": 4082 - }, - "Type parameter '{0}' of exported type alias has or is using private name '{1}'.": { - "category": "Error", - "code": 4083 - }, - "Exported type alias '{0}' has or is using private name '{1}' from module {2}.": { - "category": "Error", - "code": 4084 - }, - "Extends clause for inferred type '{0}' has or is using private name '{1}'.": { - "category": "Error", - "code": 4085 - }, - "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4091 - }, - "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4092 - }, - "Property '{0}' of exported anonymous class type may not be private or protected.": { - "category": "Error", - "code": 4094 - }, - "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4095 - }, - "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4096 - }, - "Public static method '{0}' of exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4097 - }, - "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { - "category": "Error", - "code": 4098 - }, - "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4099 - }, - "Public method '{0}' of exported class has or is using private name '{1}'.": { - "category": "Error", - "code": 4100 - }, - "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4101 - }, - "Method '{0}' of exported interface has or is using private name '{1}'.": { - "category": "Error", - "code": 4102 - }, - "Type parameter '{0}' of exported mapped object type is using private name '{1}'.": { - "category": "Error", - "code": 4103 - }, - "The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'.": { - "category": "Error", - "code": 4104 - }, - "Private or protected member '{0}' cannot be accessed on a type parameter.": { - "category": "Error", - "code": 4105 - }, - "Parameter '{0}' of accessor has or is using private name '{1}'.": { - "category": "Error", - "code": 4106 - }, - "Parameter '{0}' of accessor has or is using name '{1}' from private module '{2}'.": { - "category": "Error", - "code": 4107 - }, - "Parameter '{0}' of accessor has or is using name '{1}' from external module '{2}' but cannot be named.": { - "category": "Error", - "code": 4108 - }, - "Type arguments for '{0}' circularly reference themselves.": { - "category": "Error", - "code": 4109 - }, - "Tuple type arguments circularly reference themselves.": { - "category": "Error", - "code": 4110 - }, - "Property '{0}' comes from an index signature, so it must be accessed with ['{0}'].": { - "category": "Error", - "code": 4111 - }, - "This member cannot have an 'override' modifier because its containing class '{0}' does not extend another class.": { - "category": "Error", - "code": 4112 - }, - "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'.": { - "category": "Error", - "code": 4113 - }, - "This member must have an 'override' modifier because it overrides a member in the base class '{0}'.": { - "category": "Error", - "code": 4114 - }, - "This parameter property must have an 'override' modifier because it overrides a member in base class '{0}'.": { - "category": "Error", - "code": 4115 - }, - "This member must have an 'override' modifier because it overrides an abstract method that is declared in the base class '{0}'.": { - "category": "Error", - "code": 4116 - }, - "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 4117 - }, - "The type of this node cannot be serialized because its property '{0}' cannot be serialized.": { - "category": "Error", - "code": 4118 - }, - "This member must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'.": { - "category": "Error", - "code": 4119 - }, - "This parameter property must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'.": { - "category": "Error", - "code": 4120 - }, - "This member cannot have a JSDoc comment with an '@override' tag because its containing class '{0}' does not extend another class.": { - "category": "Error", - "code": 4121 - }, - "This member cannot have a JSDoc comment with an '@override' tag because it is not declared in the base class '{0}'.": { - "category": "Error", - "code": 4122 - }, - "This member cannot have a JSDoc comment with an 'override' tag because it is not declared in the base class '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 4123 - }, - "Compiler option '{0}' of value '{1}' is unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": { - "category": "Error", - "code": 4124 - }, - "Each declaration of '{0}.{1}' differs in its value, where '{2}' was expected but '{3}' was given.": { - "category": "Error", - "code": 4125 - }, - "One value of '{0}.{1}' is the string '{2}', and the other is assumed to be an unknown numeric value.": { - "category": "Error", - "code": 4126 - }, - "This member cannot have an 'override' modifier because its name is dynamic.": { - "category": "Error", - "code": 4127 - }, - "This member cannot have a JSDoc comment with an '@override' tag because its name is dynamic.": { - "category": "Error", - "code": 4128 - }, - - "The current host does not support the '{0}' option.": { - "category": "Error", - "code": 5001 - }, - "Cannot find the common subdirectory path for the input files.": { - "category": "Error", - "code": 5009 - }, - "File specification cannot end in a recursive directory wildcard ('**'): '{0}'.": { - "category": "Error", - "code": 5010 - }, - "The common source directory of '{0}' is '{1}'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.": { - "category": "Error", - "code": 5011 - }, - "Cannot read file '{0}': {1}.": { - "category": "Error", - "code": 5012 - }, - "Unknown compiler option '{0}'.": { - "category": "Error", - "code": 5023 - }, - "Compiler option '{0}' requires a value of type {1}.": { - "category": "Error", - "code": 5024 - }, - "Unknown compiler option '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 5025 - }, - "Could not write file '{0}': {1}.": { - "category": "Error", - "code": 5033 - }, - "Option 'project' cannot be mixed with source files on a command line.": { - "category": "Error", - "code": 5042 - }, - "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher.": { - "category": "Error", - "code": 5047 - }, - "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided.": { - "category": "Error", - "code": 5051 - }, - "Option '{0}' cannot be specified without specifying option '{1}'.": { - "category": "Error", - "code": 5052 - }, - "Option '{0}' cannot be specified with option '{1}'.": { - "category": "Error", - "code": 5053 - }, - "A 'tsconfig.json' file is already defined at: '{0}'.": { - "category": "Error", - "code": 5054 - }, - "Cannot write file '{0}' because it would overwrite input file.": { - "category": "Error", - "code": 5055 - }, - "Cannot write file '{0}' because it would be overwritten by multiple input files.": { - "category": "Error", - "code": 5056 - }, - "Cannot find a tsconfig.json file at the specified directory: '{0}'.": { - "category": "Error", - "code": 5057 - }, - "The specified path does not exist: '{0}'.": { - "category": "Error", - "code": 5058 - }, - "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier.": { - "category": "Error", - "code": 5059 - }, - "Pattern '{0}' can have at most one '*' character.": { - "category": "Error", - "code": 5061 - }, - "Substitution '{0}' in pattern '{1}' can have at most one '*' character.": { - "category": "Error", - "code": 5062 - }, - "Substitutions for pattern '{0}' should be an array.": { - "category": "Error", - "code": 5063 - }, - "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'.": { - "category": "Error", - "code": 5064 - }, - "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'.": { - "category": "Error", - "code": 5065 - }, - "Substitutions for pattern '{0}' shouldn't be an empty array.": { - "category": "Error", - "code": 5066 - }, - "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name.": { - "category": "Error", - "code": 5067 - }, - "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.": { - "category": "Error", - "code": 5068 - }, - "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'.": { - "category": "Error", - "code": 5069 - }, - "Option '--resolveJsonModule' cannot be specified when 'moduleResolution' is set to 'classic'.": { - "category": "Error", - "code": 5070 - }, - "Option '--resolveJsonModule' cannot be specified when 'module' is set to 'none', 'system', or 'umd'.": { - "category": "Error", - "code": 5071 - }, - "Unknown build option '{0}'.": { - "category": "Error", - "code": 5072 - }, - "Build option '{0}' requires a value of type {1}.": { - "category": "Error", - "code": 5073 - }, - "Option '--incremental' can only be specified using tsconfig, emitting to single file or when option '--tsBuildInfoFile' is specified.": { - "category": "Error", - "code": 5074 - }, - "'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'.": { - "category": "Error", - "code": 5075 - }, - "'{0}' and '{1}' operations cannot be mixed without parentheses.": { - "category": "Error", - "code": 5076 - }, - "Unknown build option '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 5077 - }, - "Unknown watch option '{0}'.": { - "category": "Error", - "code": 5078 - }, - "Unknown watch option '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 5079 - }, - "Watch option '{0}' requires a value of type {1}.": { - "category": "Error", - "code": 5080 - }, - "Cannot find a tsconfig.json file at the current directory: {0}.": { - "category": "Error", - "code": 5081 - }, - "'{0}' could be instantiated with an arbitrary type which could be unrelated to '{1}'.": { - "category": "Error", - "code": 5082 - }, - "Cannot read file '{0}'.": { - "category": "Error", - "code": 5083 - }, - "A tuple member cannot be both optional and rest.": { - "category": "Error", - "code": 5085 - }, - "A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type.": { - "category": "Error", - "code": 5086 - }, - "A labeled tuple element is declared as rest with a '...' before the name, rather than before the type.": { - "category": "Error", - "code": 5087 - }, - "The inferred type of '{0}' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary.": { - "category": "Error", - "code": 5088 - }, - "Option '{0}' cannot be specified when option 'jsx' is '{1}'.": { - "category": "Error", - "code": 5089 - }, - "Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'?": { - "category": "Error", - "code": 5090 - }, - "Option 'preserveConstEnums' cannot be disabled when '{0}' is enabled.": { - "category": "Error", - "code": 5091 - }, - "The root value of a '{0}' file must be an object.": { - "category": "Error", - "code": 5092 - }, - "Compiler option '--{0}' may only be used with '--build'.": { - "category": "Error", - "code": 5093 - }, - "Compiler option '--{0}' may not be used with '--build'.": { - "category": "Error", - "code": 5094 - }, - "Option '{0}' can only be used when 'module' is set to 'preserve', 'commonjs', or 'es2015' or later.": { - "category": "Error", - "code": 5095 - }, - "Option 'allowImportingTsExtensions' can only be used when one of 'noEmit', 'emitDeclarationOnly', or 'rewriteRelativeImportExtensions' is set.": { - "category": "Error", - "code": 5096 - }, - "An import path can only end with a '{0}' extension when 'allowImportingTsExtensions' is enabled.": { - "category": "Error", - "code": 5097 - }, - "Option '{0}' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'.": { - "category": "Error", - "code": 5098 - }, - "Option '{0}' is deprecated and will stop functioning in TypeScript {1}. Specify compilerOption '\"ignoreDeprecations\": \"{2}\"' to silence this error.": { - "category": "Error", - "code": 5101 - }, - "Option '{0}' has been removed. Please remove it from your configuration.": { - "category": "Error", - "code": 5102 - }, - "Invalid value for '--ignoreDeprecations'.": { - "category": "Error", - "code": 5103 - }, - "Option '{0}' is redundant and cannot be specified with option '{1}'.": { - "category": "Error", - "code": 5104 - }, - "Option 'verbatimModuleSyntax' cannot be used when 'module' is set to 'UMD', 'AMD', or 'System'.": { - "category": "Error", - "code": 5105 - }, - "Use '{0}' instead.": { - "category": "Message", - "code": 5106 - }, - "Option '{0}={1}' is deprecated and will stop functioning in TypeScript {2}. Specify compilerOption '\"ignoreDeprecations\": \"{3}\"' to silence this error.": { - "category": "Error", - "code": 5107 - }, - "Option '{0}={1}' has been removed. Please remove it from your configuration.": { - "category": "Error", - "code": 5108 - }, - "Option 'moduleResolution' must be set to '{0}' (or left unspecified) when option 'module' is set to '{1}'.": { - "category": "Error", - "code": 5109 - }, - "Option 'module' must be set to '{0}' when option 'moduleResolution' is set to '{1}'.": { - "category": "Error", - "code": 5110 - }, - "Visit https://aka.ms/ts6 for migration information.": { - "category": "Message", - "code": 5111 - }, - "tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.": { - "category": "Error", - "code": 5112 - }, - - "Generates a sourcemap for each corresponding '.d.ts' file.": { - "category": "Message", - "code": 6000 - }, - "Concatenate and emit output to single file.": { - "category": "Message", - "code": 6001 - }, - "Generates corresponding '.d.ts' file.": { - "category": "Message", - "code": 6002 - }, - "Specify the location where debugger should locate TypeScript files instead of source locations.": { - "category": "Message", - "code": 6004 - }, - "Watch input files.": { - "category": "Message", - "code": 6005 - }, - "Redirect output structure to the directory.": { - "category": "Message", - "code": 6006 - }, - "Do not erase const enum declarations in generated code.": { - "category": "Message", - "code": 6007 - }, - "Do not emit outputs if any errors were reported.": { - "category": "Message", - "code": 6008 - }, - "Do not emit comments to output.": { - "category": "Message", - "code": 6009 - }, - "Do not emit outputs.": { - "category": "Message", - "code": 6010 - }, - "Allow default imports from modules with no default export. This does not affect code emit, just typechecking.": { - "category": "Message", - "code": 6011 - }, - "Skip type checking of declaration files.": { - "category": "Message", - "code": 6012 - }, - "Do not resolve the real path of symlinks.": { - "category": "Message", - "code": 6013 - }, - "Only emit '.d.ts' declaration files.": { - "category": "Message", - "code": 6014 - }, - "Specify ECMAScript target version.": { - "category": "Message", - "code": 6015 - }, - "Specify module code generation.": { - "category": "Message", - "code": 6016 - }, - "Print this message.": { - "category": "Message", - "code": 6017 - }, - "Print the compiler's version.": { - "category": "Message", - "code": 6019 - }, - "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.": { - "category": "Message", - "code": 6020 - }, - "Syntax: {0}": { - "category": "Message", - "code": 6023 - }, - "options": { - "category": "Message", - "code": 6024 - }, - "file": { - "category": "Message", - "code": 6025 - }, - "Examples: {0}": { - "category": "Message", - "code": 6026 - }, - "Options:": { - "category": "Message", - "code": 6027 - }, - "Version {0}": { - "category": "Message", - "code": 6029 - }, - "Insert command line options and files from a file.": { - "category": "Message", - "code": 6030 - }, - "Starting compilation in watch mode...": { - "category": "Message", - "code": 6031 - }, - "File change detected. Starting incremental compilation...": { - "category": "Message", - "code": 6032 - }, - "KIND": { - "category": "Message", - "code": 6034 - }, - "FILE": { - "category": "Message", - "code": 6035 - }, - "VERSION": { - "category": "Message", - "code": 6036 - }, - "LOCATION": { - "category": "Message", - "code": 6037 - }, - "DIRECTORY": { - "category": "Message", - "code": 6038 - }, - "STRATEGY": { - "category": "Message", - "code": 6039 - }, - "FILE OR DIRECTORY": { - "category": "Message", - "code": 6040 - }, - "Errors Files": { - "_locale_notes": "There is a double space, and the order cannot be changed (they're table headings) ^", - "category": "Message", - "code": 6041 - }, - "Generates corresponding '.map' file.": { - "category": "Message", - "code": 6043 - }, - "Compiler option '{0}' expects an argument.": { - "category": "Error", - "code": 6044 - }, - "Unterminated quoted string in response file '{0}'.": { - "category": "Error", - "code": 6045 - }, - "Argument for '{0}' option must be: {1}.": { - "category": "Error", - "code": 6046 - }, - "Locale must be of the form or -. For example '{0}' or '{1}'.": { - "category": "Error", - "code": 6048 - }, - "Unable to open file '{0}'.": { - "category": "Error", - "code": 6050 - }, - "Corrupted locale file {0}.": { - "category": "Error", - "code": 6051 - }, - "Raise error on expressions and declarations with an implied 'any' type.": { - "category": "Message", - "code": 6052 - }, - "File '{0}' not found.": { - "category": "Error", - "code": 6053 - }, - "File '{0}' has an unsupported extension. The only supported extensions are {1}.": { - "category": "Error", - "code": 6054 - }, - "Suppress noImplicitAny errors for indexing objects lacking index signatures.": { - "category": "Message", - "code": 6055 - }, - "Do not emit declarations for code that has an '@internal' annotation.": { - "category": "Message", - "code": 6056 - }, - "Specify the root directory of input files. Use to control the output directory structure with --outDir.": { - "category": "Message", - "code": 6058 - }, - "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files.": { - "category": "Error", - "code": 6059 - }, - "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).": { - "category": "Message", - "code": 6060 - }, - "NEWLINE": { - "category": "Message", - "code": 6061 - }, - "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line.": { - "category": "Error", - "code": 6064 - }, - "Enables experimental support for ES7 decorators.": { - "category": "Message", - "code": 6065 - }, - "Enables experimental support for emitting type metadata for decorators.": { - "category": "Message", - "code": 6066 - }, - "Initializes a TypeScript project and creates a tsconfig.json file.": { - "category": "Message", - "code": 6070 - }, - "Successfully created a tsconfig.json file.": { - "category": "Message", - "code": 6071 - }, - "Suppress excess property checks for object literals.": { - "category": "Message", - "code": 6072 - }, - "Stylize errors and messages using color and context (experimental).": { - "category": "Message", - "code": 6073 - }, - "Do not report errors on unused labels.": { - "category": "Message", - "code": 6074 - }, - "Report error when not all code paths in function return a value.": { - "category": "Message", - "code": 6075 - }, - "Report errors for fallthrough cases in switch statement.": { - "category": "Message", - "code": 6076 - }, - "Do not report errors on unreachable code.": { - "category": "Message", - "code": 6077 - }, - "Disallow inconsistently-cased references to the same file.": { - "category": "Message", - "code": 6078 - }, - "Specify library files to be included in the compilation.": { - "category": "Message", - "code": 6079 - }, - "Specify JSX code generation.": { - "category": "Message", - "code": 6080 - }, - "Only 'amd' and 'system' modules are supported alongside --{0}.": { - "category": "Error", - "code": 6082 - }, - "Base directory to resolve non-absolute module names.": { - "category": "Message", - "code": 6083 - }, - "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit": { - "category": "Message", - "code": 6084 - }, - "Enable tracing of the name resolution process.": { - "category": "Message", - "code": 6085 - }, - "======== Resolving module '{0}' from '{1}'. ========": { - "category": "Message", - "code": 6086 - }, - "Explicitly specified module resolution kind: '{0}'.": { - "category": "Message", - "code": 6087 - }, - "Module resolution kind is not specified, using '{0}'.": { - "category": "Message", - "code": 6088 - }, - "======== Module name '{0}' was successfully resolved to '{1}'. ========": { - "category": "Message", - "code": 6089 - }, - "======== Module name '{0}' was not resolved. ========": { - "category": "Message", - "code": 6090 - }, - "'paths' option is specified, looking for a pattern to match module name '{0}'.": { - "category": "Message", - "code": 6091 - }, - "Module name '{0}', matched pattern '{1}'.": { - "category": "Message", - "code": 6092 - }, - "Trying substitution '{0}', candidate module location: '{1}'.": { - "category": "Message", - "code": 6093 - }, - "Resolving module name '{0}' relative to base url '{1}' - '{2}'.": { - "category": "Message", - "code": 6094 - }, - "Loading module as file / folder, candidate module location '{0}', target file types: {1}.": { - "category": "Message", - "code": 6095 - }, - "File '{0}' does not exist.": { - "category": "Message", - "code": 6096 - }, - "File '{0}' exists - use it as a name resolution result.": { - "category": "Message", - "code": 6097 - }, - "Loading module '{0}' from 'node_modules' folder, target file types: {1}.": { - "category": "Message", - "code": 6098 - }, - "Found 'package.json' at '{0}'.": { - "category": "Message", - "code": 6099 - }, - "'package.json' does not have a '{0}' field.": { - "category": "Message", - "code": 6100 - }, - "'package.json' has '{0}' field '{1}' that references '{2}'.": { - "category": "Message", - "code": 6101 - }, - "Allow javascript files to be compiled.": { - "category": "Message", - "code": 6102 - }, - "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'.": { - "category": "Message", - "code": 6104 - }, - "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.": { - "category": "Message", - "code": 6105 - }, - "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'.": { - "category": "Message", - "code": 6106 - }, - "'rootDirs' option is set, using it to resolve relative module name '{0}'.": { - "category": "Message", - "code": 6107 - }, - "Longest matching prefix for '{0}' is '{1}'.": { - "category": "Message", - "code": 6108 - }, - "Loading '{0}' from the root dir '{1}', candidate location '{2}'.": { - "category": "Message", - "code": 6109 - }, - "Trying other entries in 'rootDirs'.": { - "category": "Message", - "code": 6110 - }, - "Module resolution using 'rootDirs' has failed.": { - "category": "Message", - "code": 6111 - }, - "Do not emit 'use strict' directives in module output.": { - "category": "Message", - "code": 6112 - }, - "Enable strict null checks.": { - "category": "Message", - "code": 6113 - }, - "Unknown option 'excludes'. Did you mean 'exclude'?": { - "category": "Error", - "code": 6114 - }, - "Raise error on 'this' expressions with an implied 'any' type.": { - "category": "Message", - "code": 6115 - }, - "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========": { - "category": "Message", - "code": 6116 - }, - "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========": { - "category": "Message", - "code": 6119 - }, - "======== Type reference directive '{0}' was not resolved. ========": { - "category": "Message", - "code": 6120 - }, - "Resolving with primary search path '{0}'.": { - "category": "Message", - "code": 6121 - }, - "Root directory cannot be determined, skipping primary search paths.": { - "category": "Message", - "code": 6122 - }, - "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========": { - "category": "Message", - "code": 6123 - }, - "Type declaration files to be included in compilation.": { - "category": "Message", - "code": 6124 - }, - "Looking up in 'node_modules' folder, initial location '{0}'.": { - "category": "Message", - "code": 6125 - }, - "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder.": { - "category": "Message", - "code": 6126 - }, - "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========": { - "category": "Message", - "code": 6127 - }, - "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========": { - "category": "Message", - "code": 6128 - }, - "Resolving real path for '{0}', result '{1}'.": { - "category": "Message", - "code": 6130 - }, - "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'.": { - "category": "Error", - "code": 6131 - }, - "File name '{0}' has a '{1}' extension - stripping it.": { - "category": "Message", - "code": 6132 - }, - "'{0}' is declared but its value is never read.": { - "category": "Error", - "code": 6133, - "reportsUnnecessary": true - }, - "Report errors on unused locals.": { - "category": "Message", - "code": 6134 - }, - "Report errors on unused parameters.": { - "category": "Message", - "code": 6135 - }, - "The maximum dependency depth to search under node_modules and load JavaScript files.": { - "category": "Message", - "code": 6136 - }, - "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'.": { - "category": "Error", - "code": 6137 - }, - "Property '{0}' is declared but its value is never read.": { - "category": "Error", - "code": 6138, - "reportsUnnecessary": true - }, - "Import emit helpers from 'tslib'.": { - "category": "Message", - "code": 6139 - }, - "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'.": { - "category": "Error", - "code": 6140 - }, - "Parse in strict mode and emit \"use strict\" for each source file.": { - "category": "Message", - "code": 6141 - }, - "Module '{0}' was resolved to '{1}', but '--jsx' is not set.": { - "category": "Error", - "code": 6142 - }, - "Module '{0}' was resolved as locally declared ambient module in file '{1}'.": { - "category": "Message", - "code": 6144 - }, - "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'.": { - "category": "Message", - "code": 6146 - }, - "Resolution for module '{0}' was found in cache from location '{1}'.": { - "category": "Message", - "code": 6147 - }, - "Directory '{0}' does not exist, skipping all lookups in it.": { - "category": "Message", - "code": 6148 - }, - "Show diagnostic information.": { - "category": "Message", - "code": 6149 - }, - "Show verbose diagnostic information.": { - "category": "Message", - "code": 6150 - }, - "Emit a single file with source maps instead of having a separate file.": { - "category": "Message", - "code": 6151 - }, - "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set.": { - "category": "Message", - "code": 6152 - }, - "Transpile each file as a separate module (similar to 'ts.transpileModule').": { - "category": "Message", - "code": 6153 - }, - "Print names of generated files part of the compilation.": { - "category": "Message", - "code": 6154 - }, - "Print names of files part of the compilation.": { - "category": "Message", - "code": 6155 - }, - "The locale used when displaying messages to the user (e.g. 'en-us')": { - "category": "Message", - "code": 6156 - }, - "Do not generate custom helper functions like '__extends' in compiled output.": { - "category": "Message", - "code": 6157 - }, - "Do not include the default library file (lib.d.ts).": { - "category": "Message", - "code": 6158 - }, - "Do not add triple-slash references or imported modules to the list of compiled files.": { - "category": "Message", - "code": 6159 - }, - "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files.": { - "category": "Message", - "code": 6160 - }, - "List of folders to include type definitions from.": { - "category": "Message", - "code": 6161 - }, - "Disable size limitations on JavaScript projects.": { - "category": "Message", - "code": 6162 - }, - "The character set of the input files.": { - "category": "Message", - "code": 6163 - }, - "Skipping module '{0}' that looks like an absolute URI, target file types: {1}.": { - "category": "Message", - "code": 6164 - }, - "Do not truncate error messages.": { - "category": "Message", - "code": 6165 - }, - "Output directory for generated declaration files.": { - "category": "Message", - "code": 6166 - }, - "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.": { - "category": "Message", - "code": 6167 - }, - "List of root folders whose combined content represents the structure of the project at runtime.": { - "category": "Message", - "code": 6168 - }, - "Show all compiler options.": { - "category": "Message", - "code": 6169 - }, - "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file": { - "category": "Message", - "code": 6170 - }, - "Command-line Options": { - "category": "Message", - "code": 6171 - }, - "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5'.": { - "category": "Message", - "code": 6179 - }, - "Enable all strict type-checking options.": { - "category": "Message", - "code": 6180 - }, - "Scoped package detected, looking in '{0}'": { - "category": "Message", - "code": 6182 - }, - "Reusing resolution of module '{0}' from '{1}' of old program, it was successfully resolved to '{2}'.": { - "category": "Message", - "code": 6183 - }, - "Reusing resolution of module '{0}' from '{1}' of old program, it was successfully resolved to '{2}' with Package ID '{3}'.": { - "category": "Message", - "code": 6184 - }, - "Enable strict checking of function types.": { - "category": "Message", - "code": 6186 - }, - "Enable strict checking of property initialization in classes.": { - "category": "Message", - "code": 6187 - }, - "Numeric separators are not allowed here.": { - "category": "Error", - "code": 6188 - }, - "Multiple consecutive numeric separators are not permitted.": { - "category": "Error", - "code": 6189 - }, - "Whether to keep outdated console output in watch mode instead of clearing the screen.": { - "category": "Message", - "code": 6191 - }, - "All imports in import declaration are unused.": { - "category": "Error", - "code": 6192, - "reportsUnnecessary": true - }, - "Found 1 error. Watching for file changes.": { - "category": "Message", - "code": 6193 - }, - "Found {0} errors. Watching for file changes.": { - "category": "Message", - "code": 6194 - }, - "Resolve 'keyof' to string valued property names only (no numbers or symbols).": { - "category": "Message", - "code": 6195 - }, - "'{0}' is declared but never used.": { - "category": "Error", - "code": 6196, - "reportsUnnecessary": true - }, - "Include modules imported with '.json' extension": { - "category": "Message", - "code": 6197 - }, - "All destructured elements are unused.": { - "category": "Error", - "code": 6198, - "reportsUnnecessary": true - }, - "All variables are unused.": { - "category": "Error", - "code": 6199, - "reportsUnnecessary": true - }, - "Definitions of the following identifiers conflict with those in another file: {0}": { - "category": "Error", - "code": 6200 - }, - "Conflicts are in this file.": { - "category": "Message", - "code": 6201 - }, - "Project references may not form a circular graph. Cycle detected: {0}": { - "category": "Error", - "code": 6202 - }, - "'{0}' was also declared here.": { - "category": "Message", - "code": 6203 - }, - "and here.": { - "category": "Message", - "code": 6204 - }, - "All type parameters are unused.": { - "category": "Error", - "code": 6205 - }, - "'package.json' has a 'typesVersions' field with version-specific path mappings.": { - "category": "Message", - "code": 6206 - }, - "'package.json' does not have a 'typesVersions' entry that matches version '{0}'.": { - "category": "Message", - "code": 6207 - }, - "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'.": { - "category": "Message", - "code": 6208 - }, - "'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range.": { - "category": "Message", - "code": 6209 - }, - "An argument for '{0}' was not provided.": { - "category": "Message", - "code": 6210 - }, - "An argument matching this binding pattern was not provided.": { - "category": "Message", - "code": 6211 - }, - "Did you mean to call this expression?": { - "category": "Message", - "code": 6212 - }, - "Did you mean to use 'new' with this expression?": { - "category": "Message", - "code": 6213 - }, - "Enable strict 'bind', 'call', and 'apply' methods on functions.": { - "category": "Message", - "code": 6214 - }, - "Using compiler options of project reference redirect '{0}'.": { - "category": "Message", - "code": 6215 - }, - "Found 1 error.": { - "category": "Message", - "code": 6216 - }, - "Found {0} errors.": { - "category": "Message", - "code": 6217 - }, - "======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========": { - "category": "Message", - "code": 6218 - }, - "======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========": { - "category": "Message", - "code": 6219 - }, - "'package.json' had a falsy '{0}' field.": { - "category": "Message", - "code": 6220 - }, - "Disable use of source files instead of declaration files from referenced projects.": { - "category": "Message", - "code": 6221 - }, - "Emit class fields with Define instead of Set.": { - "category": "Message", - "code": 6222 - }, - "Generates a CPU profile.": { - "category": "Message", - "code": 6223 - }, - "Disable solution searching for this project.": { - "category": "Message", - "code": 6224 - }, - "Specify strategy for watching file: 'FixedPollingInterval' (default), 'PriorityPollingInterval', 'DynamicPriorityPolling', 'FixedChunkSizePolling', 'UseFsEvents', 'UseFsEventsOnParentDirectory'.": { - "category": "Message", - "code": 6225 - }, - "Specify strategy for watching directory on platforms that don't support recursive watching natively: 'UseFsEvents' (default), 'FixedPollingInterval', 'DynamicPriorityPolling', 'FixedChunkSizePolling'.": { - "category": "Message", - "code": 6226 - }, - "Specify strategy for creating a polling watch when it fails to create using file system events: 'FixedInterval' (default), 'PriorityInterval', 'DynamicPriority', 'FixedChunkSize'.": { - "category": "Message", - "code": 6227 - }, - "Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'.": { - "category": "Error", - "code": 6229 - }, - "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line.": { - "category": "Error", - "code": 6230 - }, - "Could not resolve the path '{0}' with the extensions: {1}.": { - "category": "Error", - "code": 6231 - }, - "Declaration augments declaration in another file. This cannot be serialized.": { - "category": "Error", - "code": 6232 - }, - "This is the declaration being augmented. Consider moving the augmenting declaration into the same file.": { - "category": "Error", - "code": 6233 - }, - "This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?": { - "category": "Error", - "code": 6234 - }, - "Disable loading referenced projects.": { - "category": "Message", - "code": 6235 - }, - "Arguments for the rest parameter '{0}' were not provided.": { - "category": "Error", - "code": 6236 - }, - "Generates an event trace and a list of types.": { - "category": "Message", - "code": 6237 - }, - "Specify the module specifier to be used to import the 'jsx' and 'jsxs' factory functions from. eg, react": { - "category": "Error", - "code": 6238 - }, - "File '{0}' exists according to earlier cached lookups.": { - "category": "Message", - "code": 6239 - }, - "File '{0}' does not exist according to earlier cached lookups.": { - "category": "Message", - "code": 6240 - }, - "Resolution for type reference directive '{0}' was found in cache from location '{1}'.": { - "category": "Message", - "code": 6241 - }, - "======== Resolving type reference directive '{0}', containing file '{1}'. ========": { - "category": "Message", - "code": 6242 - }, - "Interpret optional property types as written, rather than adding 'undefined'.": { - "category": "Message", - "code": 6243 - }, - "Modules": { - "category": "Message", - "code": 6244 - }, - "File Management": { - "category": "Message", - "code": 6245 - }, - "Emit": { - "category": "Message", - "code": 6246 - }, - "JavaScript Support": { - "category": "Message", - "code": 6247 - }, - "Type Checking": { - "category": "Message", - "code": 6248 - }, - "Editor Support": { - "category": "Message", - "code": 6249 - }, - "Watch and Build Modes": { - "category": "Message", - "code": 6250 - }, - "Compiler Diagnostics": { - "category": "Message", - "code": 6251 - }, - "Interop Constraints": { - "category": "Message", - "code": 6252 - }, - "Backwards Compatibility": { - "category": "Message", - "code": 6253 - }, - "Language and Environment": { - "category": "Message", - "code": 6254 - }, - "Projects": { - "category": "Message", - "code": 6255 - }, - "Output Formatting": { - "category": "Message", - "code": 6256 - }, - "Completeness": { - "category": "Message", - "code": 6257 - }, - "'{0}' should be set inside the 'compilerOptions' object of the config json file": { - "category": "Error", - "code": 6258 - }, - "Found 1 error in {0}": { - "category": "Message", - "code": 6259 - }, - "Found {0} errors in the same file, starting at: {1}": { - "category": "Message", - "code": 6260 - }, - "Found {0} errors in {1} files.": { - "category": "Message", - "code": 6261 - }, - "File name '{0}' has a '{1}' extension - looking up '{2}' instead.": { - "category": "Message", - "code": 6262 - }, - "Module '{0}' was resolved to '{1}', but '--allowArbitraryExtensions' is not set.": { - "category": "Error", - "code": 6263 - }, - "Enable importing files with any extension, provided a declaration file is present.": { - "category": "Message", - "code": 6264 - }, - "Resolving type reference directive for program that specifies custom typeRoots, skipping lookup in 'node_modules' folder.": { - "category": "Message", - "code": 6265 - }, - "Option '{0}' can only be specified on command line.": { - "category": "Error", - "code": 6266 - }, - - "Directory '{0}' has no containing package.json scope. Imports will not resolve.": { - "category": "Message", - "code": 6270 - }, - "Import specifier '{0}' does not exist in package.json scope at path '{1}'.": { - "category": "Message", - "code": 6271 - }, - "Invalid import specifier '{0}' has no possible resolutions.": { - "category": "Message", - "code": 6272 - }, - "package.json scope '{0}' has no imports defined.": { - "category": "Message", - "code": 6273 - }, - "package.json scope '{0}' explicitly maps specifier '{1}' to null.": { - "category": "Message", - "code": 6274 - }, - "package.json scope '{0}' has invalid type for target of specifier '{1}'": { - "category": "Message", - "code": 6275 - }, - "Export specifier '{0}' does not exist in package.json scope at path '{1}'.": { - "category": "Message", - "code": 6276 - }, - "Resolution of non-relative name failed; trying with modern Node resolution features disabled to see if npm library needs configuration update.": { - "category": "Message", - "code": 6277 - }, - "There are types at '{0}', but this result could not be resolved when respecting package.json \"exports\". The '{1}' library may need to update its package.json or typings.": { - "category": "Message", - "code": 6278 - }, - "Resolution of non-relative name failed; trying with '--moduleResolution bundler' to see if project may need configuration update.": { - "category": "Message", - "code": 6279 - }, - "There are types at '{0}', but this result could not be resolved under your current 'moduleResolution' setting. Consider updating to 'node16', 'nodenext', or 'bundler'.": { - "category": "Message", - "code": 6280 - }, - "'package.json' has a 'peerDependencies' field.": { - "category": "Message", - "code": 6281 - }, - "Found peerDependency '{0}' with '{1}' version.": { - "category": "Message", - "code": 6282 - }, - "Failed to find peerDependency '{0}'.": { - "category": "Message", - "code": 6283 - }, - "File Layout": { - "category": "Message", - "code": 6284 - }, - "Environment Settings": { - "category": "Message", - "code": 6285 - }, - "See also https://aka.ms/tsconfig/module": { - "category": "Message", - "code": 6286 - }, - "For nodejs:": { - "category": "Message", - "code": 6287 - }, - "and npm install -D @types/node": { - "category": "Message", - "code": 6290 - }, - "Other Outputs": { - "category": "Message", - "code": 6291 - }, - "Stricter Typechecking Options": { - "category": "Message", - "code": 6292 - }, - "Style Options": { - "category": "Message", - "code": 6293 - }, - "Recommended Options": { - "category": "Message", - "code": 6294 - }, - - "Enable project compilation": { - "category": "Message", - "code": 6302 - }, - "Composite projects may not disable declaration emit.": { - "category": "Error", - "code": 6304 - }, - "Output file '{0}' has not been built from source file '{1}'.": { - "category": "Error", - "code": 6305 - }, - "Referenced project '{0}' must have setting \"composite\": true.": { - "category": "Error", - "code": 6306 - }, - "File '{0}' is not listed within the file list of project '{1}'. Projects must list all files or use an 'include' pattern.": { - "category": "Error", - "code": 6307 - }, - "Referenced project '{0}' may not disable emit.": { - "category": "Error", - "code": 6310 - }, - "Project '{0}' is out of date because output '{1}' is older than input '{2}'": { - "category": "Message", - "code": 6350 - }, - "Project '{0}' is up to date because newest input '{1}' is older than output '{2}'": { - "category": "Message", - "code": 6351 - }, - "Project '{0}' is out of date because output file '{1}' does not exist": { - "category": "Message", - "code": 6352 - }, - "Project '{0}' is out of date because its dependency '{1}' is out of date": { - "category": "Message", - "code": 6353 - }, - "Project '{0}' is up to date with .d.ts files from its dependencies": { - "category": "Message", - "code": 6354 - }, - "Projects in this build: {0}": { - "category": "Message", - "code": 6355 - }, - "A non-dry build would delete the following files: {0}": { - "category": "Message", - "code": 6356 - }, - "A non-dry build would build project '{0}'": { - "category": "Message", - "code": 6357 - }, - "Building project '{0}'...": { - "category": "Message", - "code": 6358 - }, - "Updating output timestamps of project '{0}'...": { - "category": "Message", - "code": 6359 - }, - "Project '{0}' is up to date": { - "category": "Message", - "code": 6361 - }, - "Skipping build of project '{0}' because its dependency '{1}' has errors": { - "category": "Message", - "code": 6362 - }, - "Project '{0}' can't be built because its dependency '{1}' has errors": { - "category": "Message", - "code": 6363 - }, - "Build one or more projects and their dependencies, if out of date": { - "category": "Message", - "code": 6364 - }, - "Delete the outputs of all projects.": { - "category": "Message", - "code": 6365 - }, - "Show what would be built (or deleted, if specified with '--clean')": { - "category": "Message", - "code": 6367 - }, - "Option '--build' must be the first command line argument.": { - "category": "Error", - "code": 6369 - }, - "Options '{0}' and '{1}' cannot be combined.": { - "category": "Error", - "code": 6370 - }, - "Updating unchanged output timestamps of project '{0}'...": { - "category": "Message", - "code": 6371 - }, - "A non-dry build would update timestamps for output of project '{0}'": { - "category": "Message", - "code": 6374 - }, - "Cannot write file '{0}' because it will overwrite '.tsbuildinfo' file generated by referenced project '{1}'": { - "category": "Error", - "code": 6377 - }, - "Composite projects may not disable incremental compilation.": { - "category": "Error", - "code": 6379 - }, - "Specify file to store incremental compilation information": { - "category": "Message", - "code": 6380 - }, - "Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'": { - "category": "Message", - "code": 6381 - }, - "Skipping build of project '{0}' because its dependency '{1}' was not built": { - "category": "Message", - "code": 6382 - }, - "Project '{0}' can't be built because its dependency '{1}' was not built": { - "category": "Message", - "code": 6383 - }, - "Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it.": { - "category": "Message", - "code": 6384 - }, - "'{0}' is deprecated.": { - "category": "Suggestion", - "code": 6385, - "reportsDeprecated": true - }, - "Performance timings for '--diagnostics' or '--extendedDiagnostics' are not available in this session. A native implementation of the Web Performance API could not be found.": { - "category": "Message", - "code": 6386 - }, - "The signature '{0}' of '{1}' is deprecated.": { - "category": "Suggestion", - "code": 6387, - "reportsDeprecated": true - }, - "Project '{0}' is being forcibly rebuilt": { - "category": "Message", - "code": 6388 - }, - "Reusing resolution of module '{0}' from '{1}' of old program, it was not resolved.": { - "category": "Message", - "code": 6389 - }, - "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was successfully resolved to '{2}'.": { - "category": "Message", - "code": 6390 - }, - "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was successfully resolved to '{2}' with Package ID '{3}'.": { - "category": "Message", - "code": 6391 - }, - "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was not resolved.": { - "category": "Message", - "code": 6392 - }, - "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}'.": { - "category": "Message", - "code": 6393 - }, - "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}' with Package ID '{4}'.": { - "category": "Message", - "code": 6394 - }, - "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was not resolved.": { - "category": "Message", - "code": 6395 - }, - "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}'.": { - "category": "Message", - "code": 6396 - }, - "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}' with Package ID '{4}'.": { - "category": "Message", - "code": 6397 - }, - "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was not resolved.": { - "category": "Message", - "code": 6398 - }, - "Project '{0}' is out of date because buildinfo file '{1}' indicates that some of the changes were not emitted": { - "category": "Message", - "code": 6399 - }, - "Project '{0}' is up to date but needs to update timestamps of output files that are older than input files": { - "category": "Message", - "code": 6400 - }, - "Project '{0}' is out of date because there was error reading file '{1}'": { - "category": "Message", - "code": 6401 - }, - "Resolving in {0} mode with conditions {1}.": { - "category": "Message", - "code": 6402 - }, - "Matched '{0}' condition '{1}'.": { - "category": "Message", - "code": 6403 - }, - "Using '{0}' subpath '{1}' with target '{2}'.": { - "category": "Message", - "code": 6404 - }, - "Saw non-matching condition '{0}'.": { - "category": "Message", - "code": 6405 - }, - "Project '{0}' is out of date because buildinfo file '{1}' indicates there is change in compilerOptions": { - "category": "Message", - "code": 6406 - }, - "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.": { - "category": "Message", - "code": 6407 - }, - "Use the package.json 'exports' field when resolving package imports.": { - "category": "Message", - "code": 6408 - }, - "Use the package.json 'imports' field when resolving imports.": { - "category": "Message", - "code": 6409 - }, - "Conditions to set in addition to the resolver-specific defaults when resolving imports.": { - "category": "Message", - "code": 6410 - }, - "`true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.": { - "category": "Message", - "code": 6411 - }, - "Project '{0}' is out of date because buildinfo file '{1}' indicates that file '{2}' was root file of compilation but not any more.": { - "category": "Message", - "code": 6412 - }, - "Entering conditional exports.": { - "category": "Message", - "code": 6413 - }, - "Resolved under condition '{0}'.": { - "category": "Message", - "code": 6414 - }, - "Failed to resolve under condition '{0}'.": { - "category": "Message", - "code": 6415 - }, - "Exiting conditional exports.": { - "category": "Message", - "code": 6416 - }, - "Searching all ancestor node_modules directories for preferred extensions: {0}.": { - "category": "Message", - "code": 6417 - }, - "Searching all ancestor node_modules directories for fallback extensions: {0}.": { - "category": "Message", - "code": 6418 - }, - "Project '{0}' is out of date because buildinfo file '{1}' indicates that program needs to report errors.": { - "category": "Message", - "code": 6419 - }, - "Project '{0}' is out of date because {1}.": { - "category": "Message", - "code": 6420 - }, - "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.": { - "category": "Message", - "code": 6421 - }, - - "The expected type comes from property '{0}' which is declared here on type '{1}'": { - "category": "Message", - "code": 6500 - }, - "The expected type comes from this index signature.": { - "category": "Message", - "code": 6501 - }, - "The expected type comes from the return type of this signature.": { - "category": "Message", - "code": 6502 - }, - "Print names of files that are part of the compilation and then stop processing.": { - "category": "Message", - "code": 6503 - }, - "File '{0}' is a JavaScript file. Did you mean to enable the 'allowJs' option?": { - "category": "Error", - "code": 6504 - }, - "Print names of files and the reason they are part of the compilation.": { - "category": "Message", - "code": 6505 - }, - "Consider adding a 'declare' modifier to this class.": { - "category": "Message", - "code": 6506 - }, - "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files.": { - "category": "Message", - "code": 6600 - }, - "Allow 'import x from y' when a module doesn't have a default export.": { - "category": "Message", - "code": 6601 - }, - "Allow accessing UMD globals from modules.": { - "category": "Message", - "code": 6602 - }, - "Disable error reporting for unreachable code.": { - "category": "Message", - "code": 6603 - }, - "Disable error reporting for unused labels.": { - "category": "Message", - "code": 6604 - }, - "Ensure 'use strict' is always emitted.": { - "category": "Message", - "code": 6605 - }, - "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it.": { - "category": "Message", - "code": 6606 - }, - "Specify the base directory to resolve non-relative module names.": { - "category": "Message", - "code": 6607 - }, - "No longer supported. In early versions, manually set the text encoding for reading files.": { - "category": "Message", - "code": 6608 - }, - "Enable error reporting in type-checked JavaScript files.": { - "category": "Message", - "code": 6609 - }, - "Enable constraints that allow a TypeScript project to be used with project references.": { - "category": "Message", - "code": 6611 - }, - "Generate .d.ts files from TypeScript and JavaScript files in your project.": { - "category": "Message", - "code": 6612 - }, - "Specify the output directory for generated declaration files.": { - "category": "Message", - "code": 6613 - }, - "Create sourcemaps for d.ts files.": { - "category": "Message", - "code": 6614 - }, - "Output compiler performance information after building.": { - "category": "Message", - "code": 6615 - }, - "Disables inference for type acquisition by looking at filenames in a project.": { - "category": "Message", - "code": 6616 - }, - "Reduce the number of projects loaded automatically by TypeScript.": { - "category": "Message", - "code": 6617 - }, - "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.": { - "category": "Message", - "code": 6618 - }, - "Opt a project out of multi-project reference checking when editing.": { - "category": "Message", - "code": 6619 - }, - "Disable preferring source files instead of declaration files when referencing composite projects.": { - "category": "Message", - "code": 6620 - }, - "Emit more compliant, but verbose and less performant JavaScript for iteration.": { - "category": "Message", - "code": 6621 - }, - "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": { - "category": "Message", - "code": 6622 - }, - "Only output d.ts files and not JavaScript files.": { - "category": "Message", - "code": 6623 - }, - "Emit design-type metadata for decorated declarations in source files.": { - "category": "Message", - "code": 6624 - }, - "Disable the type acquisition for JavaScript projects": { - "category": "Message", - "code": 6625 - }, - "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.": { - "category": "Message", - "code": 6626 - }, - "Filters results from the `include` option.": { - "category": "Message", - "code": 6627 - }, - "Remove a list of directories from the watch process.": { - "category": "Message", - "code": 6628 - }, - "Remove a list of files from the watch mode's processing.": { - "category": "Message", - "code": 6629 - }, - "Enable experimental support for legacy experimental decorators.": { - "category": "Message", - "code": 6630 - }, - "Print files read during the compilation including why it was included.": { - "category": "Message", - "code": 6631 - }, - "Output more detailed compiler performance information after building.": { - "category": "Message", - "code": 6632 - }, - "Specify one or more path or node module references to base configuration files from which settings are inherited.": { - "category": "Message", - "code": 6633 - }, - "Specify what approach the watcher should use if the system runs out of native file watchers.": { - "category": "Message", - "code": 6634 - }, - "Include a list of files. This does not support glob patterns, as opposed to `include`.": { - "category": "Message", - "code": 6635 - }, - "Build all projects, including those that appear to be up to date.": { - "category": "Message", - "code": 6636 - }, - "Ensure that casing is correct in imports.": { - "category": "Message", - "code": 6637 - }, - "Emit a v8 CPU profile of the compiler run for debugging.": { - "category": "Message", - "code": 6638 - }, - "Allow importing helper functions from tslib once per project, instead of including them per-file.": { - "category": "Message", - "code": 6639 - }, - "Skip building downstream projects on error in upstream project.": { - "category": "Message", - "code": 6640 - }, - "Specify a list of glob patterns that match files to be included in compilation.": { - "category": "Message", - "code": 6641 - }, - "Save .tsbuildinfo files to allow for incremental compilation of projects.": { - "category": "Message", - "code": 6642 - }, - "Include sourcemap files inside the emitted JavaScript.": { - "category": "Message", - "code": 6643 - }, - "Include source code in the sourcemaps inside the emitted JavaScript.": { - "category": "Message", - "code": 6644 - }, - "Ensure that each file can be safely transpiled without relying on other imports.": { - "category": "Message", - "code": 6645 - }, - "Specify what JSX code is generated.": { - "category": "Message", - "code": 6646 - }, - "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'.": { - "category": "Message", - "code": 6647 - }, - "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.": { - "category": "Message", - "code": 6648 - }, - "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'.": { - "category": "Message", - "code": 6649 - }, - "Make keyof only return strings instead of string, numbers or symbols. Legacy option.": { - "category": "Message", - "code": 6650 - }, - "Specify a set of bundled library declaration files that describe the target runtime environment.": { - "category": "Message", - "code": 6651 - }, - "Print the names of emitted files after a compilation.": { - "category": "Message", - "code": 6652 - }, - "Print all of the files read during the compilation.": { - "category": "Message", - "code": 6653 - }, - "Set the language of the messaging from TypeScript. This does not affect emit.": { - "category": "Message", - "code": 6654 - }, - "Specify the location where debugger should locate map files instead of generated locations.": { - "category": "Message", - "code": 6655 - }, - "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'.": { - "category": "Message", - "code": 6656 - }, - "Specify what module code is generated.": { - "category": "Message", - "code": 6657 - }, - "Specify how TypeScript looks up a file from a given module specifier.": { - "category": "Message", - "code": 6658 - }, - "Set the newline character for emitting files.": { - "category": "Message", - "code": 6659 - }, - "Disable emitting files from a compilation.": { - "category": "Message", - "code": 6660 - }, - "Disable generating custom helper functions like '__extends' in compiled output.": { - "category": "Message", - "code": 6661 - }, - "Disable emitting files if any type checking errors are reported.": { - "category": "Message", - "code": 6662 - }, - "Disable truncating types in error messages.": { - "category": "Message", - "code": 6663 - }, - "Enable error reporting for fallthrough cases in switch statements.": { - "category": "Message", - "code": 6664 - }, - "Enable error reporting for expressions and declarations with an implied 'any' type.": { - "category": "Message", - "code": 6665 - }, - "Ensure overriding members in derived classes are marked with an override modifier.": { - "category": "Message", - "code": 6666 - }, - "Enable error reporting for codepaths that do not explicitly return in a function.": { - "category": "Message", - "code": 6667 - }, - "Enable error reporting when 'this' is given the type 'any'.": { - "category": "Message", - "code": 6668 - }, - "Disable adding 'use strict' directives in emitted JavaScript files.": { - "category": "Message", - "code": 6669 - }, - "Disable including any library files, including the default lib.d.ts.": { - "category": "Message", - "code": 6670 - }, - "Enforces using indexed accessors for keys declared using an indexed type.": { - "category": "Message", - "code": 6671 - }, - "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project.": { - "category": "Message", - "code": 6672 - }, - "Disable strict checking of generic signatures in function types.": { - "category": "Message", - "code": 6673 - }, - "Add 'undefined' to a type when accessed using an index.": { - "category": "Message", - "code": 6674 - }, - "Enable error reporting when local variables aren't read.": { - "category": "Message", - "code": 6675 - }, - "Raise an error when a function parameter isn't read.": { - "category": "Message", - "code": 6676 - }, - "Deprecated setting. Use 'outFile' instead.": { - "category": "Message", - "code": 6677 - }, - "Specify an output folder for all emitted files.": { - "category": "Message", - "code": 6678 - }, - "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.": { - "category": "Message", - "code": 6679 - }, - "Specify a set of entries that re-map imports to additional lookup locations.": { - "category": "Message", - "code": 6680 - }, - "Specify a list of language service plugins to include.": { - "category": "Message", - "code": 6681 - }, - "Disable erasing 'const enum' declarations in generated code.": { - "category": "Message", - "code": 6682 - }, - "Disable resolving symlinks to their realpath. This correlates to the same flag in node.": { - "category": "Message", - "code": 6683 - }, - "Disable wiping the console in watch mode.": { - "category": "Message", - "code": 6684 - }, - "Enable color and formatting in TypeScript's output to make compiler errors easier to read.": { - "category": "Message", - "code": 6685 - }, - "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit.": { - "category": "Message", - "code": 6686 - }, - "Specify an array of objects that specify paths for projects. Used in project references.": { - "category": "Message", - "code": 6687 - }, - "Disable emitting comments.": { - "category": "Message", - "code": 6688 - }, - "Enable importing .json files.": { - "category": "Message", - "code": 6689 - }, - "Specify the root folder within your source files.": { - "category": "Message", - "code": 6690 - }, - "Allow multiple folders to be treated as one when resolving modules.": { - "category": "Message", - "code": 6691 - }, - "Skip type checking .d.ts files that are included with TypeScript.": { - "category": "Message", - "code": 6692 - }, - "Skip type checking all .d.ts files.": { - "category": "Message", - "code": 6693 - }, - "Create source map files for emitted JavaScript files.": { - "category": "Message", - "code": 6694 - }, - "Specify the root path for debuggers to find the reference source code.": { - "category": "Message", - "code": 6695 - }, - "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function.": { - "category": "Message", - "code": 6697 - }, - "When assigning functions, check to ensure parameters and the return values are subtype-compatible.": { - "category": "Message", - "code": 6698 - }, - "When type checking, take into account 'null' and 'undefined'.": { - "category": "Message", - "code": 6699 - }, - "Check for class properties that are declared but not set in the constructor.": { - "category": "Message", - "code": 6700 - }, - "Disable emitting declarations that have '@internal' in their JSDoc comments.": { - "category": "Message", - "code": 6701 - }, - "Disable reporting of excess property errors during the creation of object literals.": { - "category": "Message", - "code": 6702 - }, - "Suppress 'noImplicitAny' errors when indexing objects that lack index signatures.": { - "category": "Message", - "code": 6703 - }, - "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.": { - "category": "Message", - "code": 6704 - }, - "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.": { - "category": "Message", - "code": 6705 - }, - "Log paths used during the 'moduleResolution' process.": { - "category": "Message", - "code": 6706 - }, - "Specify the path to .tsbuildinfo incremental compilation file.": { - "category": "Message", - "code": 6707 - }, - "Specify options for automatic acquisition of declaration files.": { - "category": "Message", - "code": 6709 - }, - "Specify multiple folders that act like './node_modules/@types'.": { - "category": "Message", - "code": 6710 - }, - "Specify type package names to be included without being referenced in a source file.": { - "category": "Message", - "code": 6711 - }, - "Emit ECMAScript-standard-compliant class fields.": { - "category": "Message", - "code": 6712 - }, - "Enable verbose logging.": { - "category": "Message", - "code": 6713 - }, - "Specify how directories are watched on systems that lack recursive file-watching functionality.": { - "category": "Message", - "code": 6714 - }, - "Specify how the TypeScript watch mode works.": { - "category": "Message", - "code": 6715 - }, - "Require undeclared properties from index signatures to use element accesses.": { - "category": "Message", - "code": 6717 - }, - "Specify emit/checking behavior for imports that are only used for types.": { - "category": "Message", - "code": 6718 - }, - "Require sufficient annotation on exports so other tools can trivially generate declaration files.": { - "category": "Message", - "code": 6719 - }, - "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'.": { - "category": "Message", - "code": 6720 - }, - "Do not allow runtime constructs that are not part of ECMAScript.": { - "category": "Message", - "code": 6721 - }, - "Default catch clause variables as 'unknown' instead of 'any'.": { - "category": "Message", - "code": 6803 - }, - "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.": { - "category": "Message", - "code": 6804 - }, - "Disable full type checking (only critical parse and emit errors will be reported).": { - "category": "Message", - "code": 6805 - }, - "Check side effect imports.": { - "category": "Message", - "code": 6806 - }, - "This operation can be simplified. This shift is identical to `{0} {1} {2}`.": { - "category": "Error", - "code": 6807 - }, - "Enable lib replacement.": { - "category": "Message", - "code": 6808 - }, - "Ensure types are ordered stably and deterministically across compilations.": { - "category": "Message", - "code": 6809 - }, - - "one of:": { - "category": "Message", - "code": 6900 - }, - "one or more:": { - "category": "Message", - "code": 6901 - }, - "type:": { - "category": "Message", - "code": 6902 - }, - "default:": { - "category": "Message", - "code": 6903 - }, - - "`true`, unless `strict` is `false`": { - "category": "Message", - "code": 6905 - }, - "`false`, unless `composite` is set": { - "category": "Message", - "code": 6906 - }, - "`[\"node_modules\", \"bower_components\", \"jspm_packages\"]`, plus the value of `outDir` if one is specified.": { - "category": "Message", - "code": 6907 - }, - "`[]` if `files` is specified, otherwise `[\"**/*\"]`": { - "category": "Message", - "code": 6908 - }, - "`true` if `composite`, `false` otherwise": { - "category": "Message", - "code": 6909 - }, - "`nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.": { - "category": "Message", - "code": 69010 - }, - "Computed from the list of input files": { - "category": "Message", - "code": 6911 - }, - "Platform specific": { - "category": "Message", - "code": 6912 - }, - "You can learn about all of the compiler options at {0}": { - "category": "Message", - "code": 6913 - }, - "Including --watch, -w will start watching the current project for the file changes. Once set, you can config watch mode with:": { - "category": "Message", - "code": 6914 - }, - "Using --build, -b will make tsc behave more like a build orchestrator than a compiler. This is used to trigger building composite projects which you can learn more about at {0}": { - "category": "Message", - "code": 6915 - }, - "COMMON COMMANDS": { - "category": "Message", - "code": 6916 - }, - "ALL COMPILER OPTIONS": { - "category": "Message", - "code": 6917 - }, - "WATCH OPTIONS": { - "category": "Message", - "code": 6918 - }, - "BUILD OPTIONS": { - "category": "Message", - "code": 6919 - }, - "COMMON COMPILER OPTIONS": { - "category": "Message", - "code": 6920 - }, - "COMMAND LINE FLAGS": { - "category": "Message", - "code": 6921 - }, - "tsc: The TypeScript Compiler": { - "category": "Message", - "code": 6922 - }, - "Compiles the current project (tsconfig.json in the working directory.)": { - "category": "Message", - "code": 6923 - }, - "Ignoring tsconfig.json, compiles the specified files with default compiler options.": { - "category": "Message", - "code": 6924 - }, - "Build a composite project in the working directory.": { - "category": "Message", - "code": 6925 - }, - "Creates a tsconfig.json with the recommended settings in the working directory.": { - "category": "Message", - "code": 6926 - }, - "Compiles the TypeScript project located at the specified path.": { - "category": "Message", - "code": 6927 - }, - "An expanded version of this information, showing all possible compiler options": { - "category": "Message", - "code": 6928 - }, - "Compiles the current project, with additional settings.": { - "category": "Message", - "code": 6929 - }, - "`true` for ES2022 and above, including ESNext.": { - "category": "Message", - "code": 6930 - }, - "List of file name suffixes to search when resolving a module.": { - "category": "Error", - "code": 6931 - }, - "`false`, unless `checkJs` is set": { - "category": "Message", - "code": 6932 - }, - - "Variable '{0}' implicitly has an '{1}' type.": { - "category": "Error", - "code": 7005 - }, - "Parameter '{0}' implicitly has an '{1}' type.": { - "category": "Error", - "code": 7006 - }, - "Member '{0}' implicitly has an '{1}' type.": { - "category": "Error", - "code": 7008 - }, - "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.": { - "category": "Error", - "code": 7009 - }, - "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type.": { - "category": "Error", - "code": 7010 - }, - "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type.": { - "category": "Error", - "code": 7011 - }, - "This overload implicitly returns the type '{0}' because it lacks a return type annotation.": { - "category": "Error", - "code": 7012 - }, - "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.": { - "category": "Error", - "code": 7013 - }, - "Function type, which lacks return-type annotation, implicitly has an '{0}' return type.": { - "category": "Error", - "code": 7014 - }, - "Element implicitly has an 'any' type because index expression is not of type 'number'.": { - "category": "Error", - "code": 7015 - }, - "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.": { - "category": "Error", - "code": 7016 - }, - "Element implicitly has an 'any' type because type '{0}' has no index signature.": { - "category": "Error", - "code": 7017 - }, - "Object literal's property '{0}' implicitly has an '{1}' type.": { - "category": "Error", - "code": 7018 - }, - "Rest parameter '{0}' implicitly has an 'any[]' type.": { - "category": "Error", - "code": 7019 - }, - "Call signature, which lacks return-type annotation, implicitly has an 'any' return type.": { - "category": "Error", - "code": 7020 - }, - "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.": { - "category": "Error", - "code": 7022 - }, - "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.": { - "category": "Error", - "code": 7023 - }, - "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.": { - "category": "Error", - "code": 7024 - }, - "Generator implicitly has yield type '{0}'. Consider supplying a return type annotation.": { - "category": "Error", - "code": 7025 - }, - "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists.": { - "category": "Error", - "code": 7026 - }, - "Unreachable code detected.": { - "category": "Error", - "code": 7027, - "reportsUnnecessary": true - }, - "Unused label.": { - "category": "Error", - "code": 7028, - "reportsUnnecessary": true - }, - "Fallthrough case in switch.": { - "category": "Error", - "code": 7029 - }, - "Not all code paths return a value.": { - "category": "Error", - "code": 7030 - }, - "Binding element '{0}' implicitly has an '{1}' type.": { - "category": "Error", - "code": 7031 - }, - "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation.": { - "category": "Error", - "code": 7032 - }, - "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation.": { - "category": "Error", - "code": 7033 - }, - "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.": { - "category": "Error", - "code": 7034 - }, - "Try `npm i --save-dev @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`": { - "category": "Error", - "code": 7035 - }, - "Dynamic import's specifier must be of type 'string', but here has type '{0}'.": { - "category": "Error", - "code": 7036 - }, - "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.": { - "category": "Message", - "code": 7037 - }, - "Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.": { - "category": "Message", - "code": 7038 - }, - "Mapped object type implicitly has an 'any' template type.": { - "category": "Error", - "code": 7039 - }, - "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}'": { - "category": "Error", - "code": 7040 - }, - "The containing arrow function captures the global value of 'this'.": { - "category": "Error", - "code": 7041 - }, - "Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used.": { - "category": "Error", - "code": 7042 - }, - "Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": { - "category": "Suggestion", - "code": 7043 - }, - "Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": { - "category": "Suggestion", - "code": 7044 - }, - "Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": { - "category": "Suggestion", - "code": 7045 - }, - "Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage.": { - "category": "Suggestion", - "code": 7046 - }, - "Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage.": { - "category": "Suggestion", - "code": 7047 - }, - "Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage.": { - "category": "Suggestion", - "code": 7048 - }, - "Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage.": { - "category": "Suggestion", - "code": 7049 - }, - "'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage.": { - "category": "Suggestion", - "code": 7050 - }, - "Parameter has a name but no type. Did you mean '{0}: {1}'?": { - "category": "Error", - "code": 7051 - }, - "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?": { - "category": "Error", - "code": 7052 - }, - "Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'.": { - "category": "Error", - "code": 7053 - }, - "No index signature with a parameter of type '{0}' was found on type '{1}'.": { - "category": "Error", - "code": 7054 - }, - "'{0}', which lacks return-type annotation, implicitly has an '{1}' yield type.": { - "category": "Error", - "code": 7055 - }, - "The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.": { - "category": "Error", - "code": 7056 - }, - "'yield' expression implicitly results in an 'any' type because its containing generator lacks a return-type annotation.": { - "category": "Error", - "code": 7057 - }, - "If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`": { - "category": "Error", - "code": 7058 - }, - "This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead.": { - "category": "Error", - "code": 7059 - }, - "This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma or explicit constraint.": { - "category": "Error", - "code": 7060 - }, - "A mapped type may not declare properties or methods.": { - "category": "Error", - "code": 7061 - }, - - "You cannot rename this element.": { - "category": "Error", - "code": 8000 - }, - "You cannot rename elements that are defined in the standard TypeScript library.": { - "category": "Error", - "code": 8001 - }, - "'import ... =' can only be used in TypeScript files.": { - "category": "Error", - "code": 8002 - }, - "'export =' can only be used in TypeScript files.": { - "category": "Error", - "code": 8003 - }, - "Type parameter declarations can only be used in TypeScript files.": { - "category": "Error", - "code": 8004 - }, - "'implements' clauses can only be used in TypeScript files.": { - "category": "Error", - "code": 8005 - }, - "'{0}' declarations can only be used in TypeScript files.": { - "category": "Error", - "code": 8006 - }, - "Type aliases can only be used in TypeScript files.": { - "category": "Error", - "code": 8008 - }, - "The '{0}' modifier can only be used in TypeScript files.": { - "category": "Error", - "code": 8009 - }, - "Type annotations can only be used in TypeScript files.": { - "category": "Error", - "code": 8010 - }, - "Type arguments can only be used in TypeScript files.": { - "category": "Error", - "code": 8011 - }, - "Parameter modifiers can only be used in TypeScript files.": { - "category": "Error", - "code": 8012 - }, - "Non-null assertions can only be used in TypeScript files.": { - "category": "Error", - "code": 8013 - }, - "Type assertion expressions can only be used in TypeScript files.": { - "category": "Error", - "code": 8016 - }, - "Signature declarations can only be used in TypeScript files.": { - "category": "Error", - "code": 8017 - }, - "Report errors in .js files.": { - "category": "Message", - "code": 8019 - }, - "JSDoc types can only be used inside documentation comments.": { - "category": "Error", - "code": 8020 - }, - "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.": { - "category": "Error", - "code": 8021 - }, - "JSDoc '@{0}' is not attached to a class.": { - "category": "Error", - "code": 8022 - }, - "JSDoc '@{0} {1}' does not match the 'extends {2}' clause.": { - "category": "Error", - "code": 8023 - }, - "JSDoc '@param' tag has name '{0}', but there is no parameter with that name.": { - "category": "Error", - "code": 8024 - }, - "Class declarations cannot have more than one '@augments' or '@extends' tag.": { - "category": "Error", - "code": 8025 - }, - "Expected {0} type arguments; provide these with an '@extends' tag.": { - "category": "Error", - "code": 8026 - }, - "Expected {0}-{1} type arguments; provide these with an '@extends' tag.": { - "category": "Error", - "code": 8027 - }, - "JSDoc '...' may only appear in the last parameter of a signature.": { - "category": "Error", - "code": 8028 - }, - "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type.": { - "category": "Error", - "code": 8029 - }, - "The type of a function declaration must match the function's signature.": { - "category": "Error", - "code": 8030 - }, - "You cannot rename a module via a global import.": { - "category": "Error", - "code": 8031 - }, - "Qualified name '{0}' is not allowed without a leading '@param {object} {1}'.": { - "category": "Error", - "code": 8032 - }, - "A JSDoc '@typedef' comment may not contain multiple '@type' tags.": { - "category": "Error", - "code": 8033 - }, - "The tag was first specified here.": { - "category": "Error", - "code": 8034 - }, - "You cannot rename elements that are defined in a 'node_modules' folder.": { - "category": "Error", - "code": 8035 - }, - "You cannot rename elements that are defined in another 'node_modules' folder.": { - "category": "Error", - "code": 8036 - }, - "Type satisfaction expressions can only be used in TypeScript files.": { - "category": "Error", - "code": 8037 - }, - "Decorators may not appear after 'export' or 'export default' if they also appear before 'export'.": { - "category": "Error", - "code": 8038 - }, - "A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag": { - "category": "Error", - "code": 8039 - }, - - "Declaration emit for this file requires using private name '{0}'. An explicit type annotation may unblock declaration emit.": { - "category": "Error", - "code": 9005 - }, - "Declaration emit for this file requires using private name '{0}' from module '{1}'. An explicit type annotation may unblock declaration emit.": { - "category": "Error", - "code": 9006 - }, - "Function must have an explicit return type annotation with --isolatedDeclarations.": { - "category": "Error", - "code": 9007 - }, - "Method must have an explicit return type annotation with --isolatedDeclarations.": { - "category": "Error", - "code": 9008 - }, - "At least one accessor must have an explicit type annotation with --isolatedDeclarations.": { - "category": "Error", - "code": 9009 - }, - "Variable must have an explicit type annotation with --isolatedDeclarations.": { - "category": "Error", - "code": 9010 - }, - "Parameter must have an explicit type annotation with --isolatedDeclarations.": { - "category": "Error", - "code": 9011 - }, - "Property must have an explicit type annotation with --isolatedDeclarations.": { - "category": "Error", - "code": 9012 - }, - "Expression type can't be inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9013 - }, - "Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.": { - "category": "Error", - "code": 9014 - }, - "Objects that contain spread assignments can't be inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9015 - }, - "Objects that contain shorthand properties can't be inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9016 - }, - "Only const arrays can be inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9017 - }, - "Arrays with spread elements can't inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9018 - }, - "Binding elements can't be exported directly with --isolatedDeclarations.": { - "category": "Error", - "code": 9019 - }, - "Enum member initializers must be computable without references to external symbols with --isolatedDeclarations.": { - "category": "Error", - "code": 9020 - }, - "Extends clause can't contain an expression with --isolatedDeclarations.": { - "category": "Error", - "code": 9021 - }, - "Inference from class expressions is not supported with --isolatedDeclarations.": { - "category": "Error", - "code": 9022 - }, - "Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.": { - "category": "Error", - "code": 9023 - }, - "Declaration emit for this parameter requires implicitly adding undefined to its type. This is not supported with --isolatedDeclarations.": { - "category": "Error", - "code": 9025 - }, - "Declaration emit for this file requires preserving this import for augmentations. This is not supported with --isolatedDeclarations.": { - "category": "Error", - "code": 9026 - }, - "Add a type annotation to the variable {0}.": { - "category": "Error", - "code": 9027 - }, - "Add a type annotation to the parameter {0}.": { - "category": "Error", - "code": 9028 - }, - "Add a type annotation to the property {0}.": { - "category": "Error", - "code": 9029 - }, - "Add a return type to the function expression.": { - "category": "Error", - "code": 9030 - }, - "Add a return type to the function declaration.": { - "category": "Error", - "code": 9031 - }, - "Add a return type to the get accessor declaration.": { - "category": "Error", - "code": 9032 - }, - "Add a type to parameter of the set accessor declaration.": { - "category": "Error", - "code": 9033 - }, - "Add a return type to the method": { - "category": "Error", - "code": 9034 - }, - "Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit.": { - "category": "Error", - "code": 9035 - }, - "Move the expression in default export to a variable and add a type annotation to it.": { - "category": "Error", - "code": 9036 - }, - "Default exports can't be inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9037 - }, - "Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.": { - "category": "Error", - "code": 9038 - }, - "Type containing private name '{0}' can't be used with --isolatedDeclarations.": { - "category": "Error", - "code": 9039 - }, - "JSX attributes must only be assigned a non-empty 'expression'.": { - "category": "Error", - "code": 17000 - }, - "JSX elements cannot have multiple attributes with the same name.": { - "category": "Error", - "code": 17001 - }, - "Expected corresponding JSX closing tag for '{0}'.": { - "category": "Error", - "code": 17002 - }, - "Cannot use JSX unless the '--jsx' flag is provided.": { - "category": "Error", - "code": 17004 - }, - "A constructor cannot contain a 'super' call when its class extends 'null'.": { - "category": "Error", - "code": 17005 - }, - "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.": { - "category": "Error", - "code": 17006 - }, - "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.": { - "category": "Error", - "code": 17007 - }, - "JSX element '{0}' has no corresponding closing tag.": { - "category": "Error", - "code": 17008 - }, - "'super' must be called before accessing 'this' in the constructor of a derived class.": { - "category": "Error", - "code": 17009 - }, - "Unknown type acquisition option '{0}'.": { - "category": "Error", - "code": 17010 - }, - "'super' must be called before accessing a property of 'super' in the constructor of a derived class.": { - "category": "Error", - "code": 17011 - }, - "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?": { - "category": "Error", - "code": 17012 - }, - "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor.": { - "category": "Error", - "code": 17013 - }, - "JSX fragment has no corresponding closing tag.": { - "category": "Error", - "code": 17014 - }, - "Expected corresponding closing tag for JSX fragment.": { - "category": "Error", - "code": 17015 - }, - "The 'jsxFragmentFactory' compiler option must be provided to use JSX fragments with the 'jsxFactory' compiler option.": { - "category": "Error", - "code": 17016 - }, - "An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments.": { - "category": "Error", - "code": 17017 - }, - "Unknown type acquisition option '{0}'. Did you mean '{1}'?": { - "category": "Error", - "code": 17018 - }, - "'{0}' at the end of a type is not valid TypeScript syntax. Did you mean to write '{1}'?": { - "category": "Error", - "code": 17019 - }, - "'{0}' at the start of a type is not valid TypeScript syntax. Did you mean to write '{1}'?": { - "category": "Error", - "code": 17020 - }, - "Unicode escape sequence cannot appear here.": { - "category": "Error", - "code": 17021 - }, - "Circularity detected while resolving configuration: {0}": { - "category": "Error", - "code": 18000 - }, - "The 'files' list in config file '{0}' is empty.": { - "category": "Error", - "code": 18002 - }, - "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'.": { - "category": "Error", - "code": 18003 - }, - - "File is a CommonJS module; it may be converted to an ES module.": { - "category": "Suggestion", - "code": 80001 - }, - "This constructor function may be converted to a class declaration.": { - "category": "Suggestion", - "code": 80002 - }, - "Import may be converted to a default import.": { - "category": "Suggestion", - "code": 80003 - }, - "JSDoc types may be moved to TypeScript types.": { - "category": "Suggestion", - "code": 80004 - }, - "'require' call may be converted to an import.": { - "category": "Suggestion", - "code": 80005 - }, - "This may be converted to an async function.": { - "category": "Suggestion", - "code": 80006 - }, - "'await' has no effect on the type of this expression.": { - "category": "Suggestion", - "code": 80007 - }, - "Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as integers.": { - "category": "Suggestion", - "code": 80008 - }, - "JSDoc typedef may be converted to TypeScript type.": { - "category": "Suggestion", - "code": 80009 - }, - "JSDoc typedefs may be converted to TypeScript types.": { - "category": "Suggestion", - "code": 80010 - }, - - "Add missing 'super()' call": { - "category": "Message", - "code": 90001 - }, - "Make 'super()' call the first statement in the constructor": { - "category": "Message", - "code": 90002 - }, - "Change 'extends' to 'implements'": { - "category": "Message", - "code": 90003 - }, - "Remove unused declaration for: '{0}'": { - "category": "Message", - "code": 90004 - }, - "Remove import from '{0}'": { - "category": "Message", - "code": 90005 - }, - "Implement interface '{0}'": { - "category": "Message", - "code": 90006 - }, - "Implement inherited abstract class": { - "category": "Message", - "code": 90007 - }, - "Add '{0}.' to unresolved variable": { - "category": "Message", - "code": 90008 - }, - "Remove variable statement": { - "category": "Message", - "code": 90010 - }, - "Remove template tag": { - "category": "Message", - "code": 90011 - }, - "Remove type parameters": { - "category": "Message", - "code": 90012 - }, - "Import '{0}' from \"{1}\"": { - "category": "Message", - "code": 90013 - }, - "Change '{0}' to '{1}'": { - "category": "Message", - "code": 90014 - }, - "Declare property '{0}'": { - "category": "Message", - "code": 90016 - }, - "Add index signature for property '{0}'": { - "category": "Message", - "code": 90017 - }, - "Disable checking for this file": { - "category": "Message", - "code": 90018 - }, - "Ignore this error message": { - "category": "Message", - "code": 90019 - }, - "Initialize property '{0}' in the constructor": { - "category": "Message", - "code": 90020 - }, - "Initialize static property '{0}'": { - "category": "Message", - "code": 90021 - }, - "Change spelling to '{0}'": { - "category": "Message", - "code": 90022 - }, - "Declare method '{0}'": { - "category": "Message", - "code": 90023 - }, - "Declare static method '{0}'": { - "category": "Message", - "code": 90024 - }, - "Prefix '{0}' with an underscore": { - "category": "Message", - "code": 90025 - }, - "Rewrite as the indexed access type '{0}'": { - "category": "Message", - "code": 90026 - }, - "Declare static property '{0}'": { - "category": "Message", - "code": 90027 - }, - "Call decorator expression": { - "category": "Message", - "code": 90028 - }, - "Add async modifier to containing function": { - "category": "Message", - "code": 90029 - }, - "Replace 'infer {0}' with 'unknown'": { - "category": "Message", - "code": 90030 - }, - "Replace all unused 'infer' with 'unknown'": { - "category": "Message", - "code": 90031 - }, - "Add parameter name": { - "category": "Message", - "code": 90034 - }, - "Declare private property '{0}'": { - "category": "Message", - "code": 90035 - }, - "Replace '{0}' with 'Promise<{1}>'": { - "category": "Message", - "code": 90036 - }, - "Fix all incorrect return type of an async functions": { - "category": "Message", - "code": 90037 - }, - "Declare private method '{0}'": { - "category": "Message", - "code": 90038 - }, - "Remove unused destructuring declaration": { - "category": "Message", - "code": 90039 - }, - "Remove unused declarations for: '{0}'": { - "category": "Message", - "code": 90041 - }, - "Declare a private field named '{0}'.": { - "category": "Message", - "code": 90053 - }, - "Includes imports of types referenced by '{0}'": { - "category": "Message", - "code": 90054 - }, - "Remove 'type' from import declaration from \"{0}\"": { - "category": "Message", - "code": 90055 - }, - "Remove 'type' from import of '{0}' from \"{1}\"": { - "category": "Message", - "code": 90056 - }, - "Add import from \"{0}\"": { - "category": "Message", - "code": 90057 - }, - "Update import from \"{0}\"": { - "category": "Message", - "code": 90058 - }, - "Export '{0}' from module '{1}'": { - "category": "Message", - "code": 90059 - }, - "Export all referenced locals": { - "category": "Message", - "code": 90060 - }, - "Update modifiers of '{0}'": { - "category": "Message", - "code": 90061 - }, - "Add annotation of type '{0}'": { - "category": "Message", - "code": 90062 - }, - "Add return type '{0}'": { - "category": "Message", - "code": 90063 - }, - "Extract base class to variable": { - "category": "Message", - "code": 90064 - }, - "Extract default export to variable": { - "category": "Message", - "code": 90065 - }, - "Extract binding expressions to variable": { - "category": "Message", - "code": 90066 - }, - "Add all missing type annotations": { - "category": "Message", - "code": 90067 - }, - "Add satisfies and an inline type assertion with '{0}'": { - "category": "Message", - "code": 90068 - }, - "Extract to variable and replace with '{0} as typeof {0}'": { - "category": "Message", - "code": 90069 - }, - "Mark array literal as const": { - "category": "Message", - "code": 90070 - }, - "Annotate types of properties expando function in a namespace": { - "category": "Message", - "code": 90071 - }, - - "Convert function to an ES2015 class": { - "category": "Message", - "code": 95001 - }, - "Convert '{0}' to '{1} in {0}'": { - "category": "Message", - "code": 95003 - }, - "Extract to {0} in {1}": { - "category": "Message", - "code": 95004 - }, - "Extract function": { - "category": "Message", - "code": 95005 - }, - "Extract constant": { - "category": "Message", - "code": 95006 - }, - "Extract to {0} in enclosing scope": { - "category": "Message", - "code": 95007 - }, - "Extract to {0} in {1} scope": { - "category": "Message", - "code": 95008 - }, - "Annotate with type from JSDoc": { - "category": "Message", - "code": 95009 - }, - "Infer type of '{0}' from usage": { - "category": "Message", - "code": 95011 - }, - "Infer parameter types from usage": { - "category": "Message", - "code": 95012 - }, - "Convert to default import": { - "category": "Message", - "code": 95013 - }, - "Install '{0}'": { - "category": "Message", - "code": 95014 - }, - "Replace import with '{0}'.": { - "category": "Message", - "code": 95015 - }, - "Use synthetic 'default' member.": { - "category": "Message", - "code": 95016 - }, - "Convert to ES module": { - "category": "Message", - "code": 95017 - }, - "Add 'undefined' type to property '{0}'": { - "category": "Message", - "code": 95018 - }, - "Add initializer to property '{0}'": { - "category": "Message", - "code": 95019 - }, - "Add definite assignment assertion to property '{0}'": { - "category": "Message", - "code": 95020 - }, - "Convert all type literals to mapped type": { - "category": "Message", - "code": 95021 - }, - "Add all missing members": { - "category": "Message", - "code": 95022 - }, - "Infer all types from usage": { - "category": "Message", - "code": 95023 - }, - "Delete all unused declarations": { - "category": "Message", - "code": 95024 - }, - "Prefix all unused declarations with '_' where possible": { - "category": "Message", - "code": 95025 - }, - "Fix all detected spelling errors": { - "category": "Message", - "code": 95026 - }, - "Add initializers to all uninitialized properties": { - "category": "Message", - "code": 95027 - }, - "Add definite assignment assertions to all uninitialized properties": { - "category": "Message", - "code": 95028 - }, - "Add undefined type to all uninitialized properties": { - "category": "Message", - "code": 95029 - }, - "Change all jsdoc-style types to TypeScript": { - "category": "Message", - "code": 95030 - }, - "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)": { - "category": "Message", - "code": 95031 - }, - "Implement all unimplemented interfaces": { - "category": "Message", - "code": 95032 - }, - "Install all missing types packages": { - "category": "Message", - "code": 95033 - }, - "Rewrite all as indexed access types": { - "category": "Message", - "code": 95034 - }, - "Convert all to default imports": { - "category": "Message", - "code": 95035 - }, - "Make all 'super()' calls the first statement in their constructor": { - "category": "Message", - "code": 95036 - }, - "Add qualifier to all unresolved variables matching a member name": { - "category": "Message", - "code": 95037 - }, - "Change all extended interfaces to 'implements'": { - "category": "Message", - "code": 95038 - }, - "Add all missing super calls": { - "category": "Message", - "code": 95039 - }, - "Implement all inherited abstract classes": { - "category": "Message", - "code": 95040 - }, - "Add all missing 'async' modifiers": { - "category": "Message", - "code": 95041 - }, - "Add '@ts-ignore' to all error messages": { - "category": "Message", - "code": 95042 - }, - "Annotate everything with types from JSDoc": { - "category": "Message", - "code": 95043 - }, - "Add '()' to all uncalled decorators": { - "category": "Message", - "code": 95044 - }, - "Convert all constructor functions to classes": { - "category": "Message", - "code": 95045 - }, - "Generate 'get' and 'set' accessors": { - "category": "Message", - "code": 95046 - }, - "Convert 'require' to 'import'": { - "category": "Message", - "code": 95047 - }, - "Convert all 'require' to 'import'": { - "category": "Message", - "code": 95048 - }, - "Move to a new file": { - "category": "Message", - "code": 95049 - }, - "Remove unreachable code": { - "category": "Message", - "code": 95050 - }, - "Remove all unreachable code": { - "category": "Message", - "code": 95051 - }, - "Add missing 'typeof'": { - "category": "Message", - "code": 95052 - }, - "Remove unused label": { - "category": "Message", - "code": 95053 - }, - "Remove all unused labels": { - "category": "Message", - "code": 95054 - }, - "Convert '{0}' to mapped object type": { - "category": "Message", - "code": 95055 - }, - "Convert namespace import to named imports": { - "category": "Message", - "code": 95056 - }, - "Convert named imports to namespace import": { - "category": "Message", - "code": 95057 - }, - "Add or remove braces in an arrow function": { - "category": "Message", - "code": 95058 - }, - "Add braces to arrow function": { - "category": "Message", - "code": 95059 - }, - "Remove braces from arrow function": { - "category": "Message", - "code": 95060 - }, - "Convert default export to named export": { - "category": "Message", - "code": 95061 - }, - "Convert named export to default export": { - "category": "Message", - "code": 95062 - }, - "Add missing enum member '{0}'": { - "category": "Message", - "code": 95063 - }, - "Add all missing imports": { - "category": "Message", - "code": 95064 - }, - "Convert to async function": { - "category": "Message", - "code": 95065 - }, - "Convert all to async functions": { - "category": "Message", - "code": 95066 - }, - "Add missing call parentheses": { - "category": "Message", - "code": 95067 - }, - "Add all missing call parentheses": { - "category": "Message", - "code": 95068 - }, - "Add 'unknown' conversion for non-overlapping types": { - "category": "Message", - "code": 95069 - }, - "Add 'unknown' to all conversions of non-overlapping types": { - "category": "Message", - "code": 95070 - }, - "Add missing 'new' operator to call": { - "category": "Message", - "code": 95071 - }, - "Add missing 'new' operator to all calls": { - "category": "Message", - "code": 95072 - }, - "Add names to all parameters without names": { - "category": "Message", - "code": 95073 - }, - "Enable the 'experimentalDecorators' option in your configuration file": { - "category": "Message", - "code": 95074 - }, - "Convert parameters to destructured object": { - "category": "Message", - "code": 95075 - }, - "Extract type": { - "category": "Message", - "code": 95077 - }, - "Extract to type alias": { - "category": "Message", - "code": 95078 - }, - "Extract to typedef": { - "category": "Message", - "code": 95079 - }, - "Infer 'this' type of '{0}' from usage": { - "category": "Message", - "code": 95080 - }, - "Add 'const' to unresolved variable": { - "category": "Message", - "code": 95081 - }, - "Add 'const' to all unresolved variables": { - "category": "Message", - "code": 95082 - }, - "Add 'await'": { - "category": "Message", - "code": 95083 - }, - "Add 'await' to initializer for '{0}'": { - "category": "Message", - "code": 95084 - }, - "Fix all expressions possibly missing 'await'": { - "category": "Message", - "code": 95085 - }, - "Remove unnecessary 'await'": { - "category": "Message", - "code": 95086 - }, - "Remove all unnecessary uses of 'await'": { - "category": "Message", - "code": 95087 - }, - "Enable the '--jsx' flag in your configuration file": { - "category": "Message", - "code": 95088 - }, - "Add 'await' to initializers": { - "category": "Message", - "code": 95089 - }, - "Extract to interface": { - "category": "Message", - "code": 95090 - }, - "Convert to a bigint numeric literal": { - "category": "Message", - "code": 95091 - }, - "Convert all to bigint numeric literals": { - "category": "Message", - "code": 95092 - }, - "Convert 'const' to 'let'": { - "category": "Message", - "code": 95093 - }, - "Prefix with 'declare'": { - "category": "Message", - "code": 95094 - }, - "Prefix all incorrect property declarations with 'declare'": { - "category": "Message", - "code": 95095 - }, - "Convert to template string": { - "category": "Message", - "code": 95096 - }, - "Add 'export {}' to make this file into a module": { - "category": "Message", - "code": 95097 - }, - "Set the 'target' option in your configuration file to '{0}'": { - "category": "Message", - "code": 95098 - }, - "Set the 'module' option in your configuration file to '{0}'": { - "category": "Message", - "code": 95099 - }, - "Convert invalid character to its html entity code": { - "category": "Message", - "code": 95100 - }, - "Convert all invalid characters to HTML entity code": { - "category": "Message", - "code": 95101 - }, - "Convert all 'const' to 'let'": { - "category": "Message", - "code": 95102 - }, - "Convert function expression '{0}' to arrow function": { - "category": "Message", - "code": 95105 - }, - "Convert function declaration '{0}' to arrow function": { - "category": "Message", - "code": 95106 - }, - "Fix all implicit-'this' errors": { - "category": "Message", - "code": 95107 - }, - "Wrap invalid character in an expression container": { - "category": "Message", - "code": 95108 - }, - "Wrap all invalid characters in an expression container": { - "category": "Message", - "code": 95109 - }, - "Visit https://aka.ms/tsconfig to read more about this file": { - "category": "Message", - "code": 95110 - }, - "Add a return statement": { - "category": "Message", - "code": 95111 - }, - "Remove braces from arrow function body": { - "category": "Message", - "code": 95112 - }, - "Wrap the following body with parentheses which should be an object literal": { - "category": "Message", - "code": 95113 - }, - "Add all missing return statement": { - "category": "Message", - "code": 95114 - }, - "Remove braces from all arrow function bodies with relevant issues": { - "category": "Message", - "code": 95115 - }, - "Wrap all object literal with parentheses": { - "category": "Message", - "code": 95116 - }, - "Move labeled tuple element modifiers to labels": { - "category": "Message", - "code": 95117 - }, - "Convert overload list to single signature": { - "category": "Message", - "code": 95118 - }, - "Generate 'get' and 'set' accessors for all overriding properties": { - "category": "Message", - "code": 95119 - }, - "Wrap in JSX fragment": { - "category": "Message", - "code": 95120 - }, - "Wrap all unparented JSX in JSX fragment": { - "category": "Message", - "code": 95121 - }, - "Convert arrow function or function expression": { - "category": "Message", - "code": 95122 - }, - "Convert to anonymous function": { - "category": "Message", - "code": 95123 - }, - "Convert to named function": { - "category": "Message", - "code": 95124 - }, - "Convert to arrow function": { - "category": "Message", - "code": 95125 - }, - "Remove parentheses": { - "category": "Message", - "code": 95126 - }, - "Could not find a containing arrow function": { - "category": "Message", - "code": 95127 - }, - "Containing function is not an arrow function": { - "category": "Message", - "code": 95128 - }, - "Could not find export statement": { - "category": "Message", - "code": 95129 - }, - "This file already has a default export": { - "category": "Message", - "code": 95130 - }, - "Could not find import clause": { - "category": "Message", - "code": 95131 - }, - "Could not find namespace import or named imports": { - "category": "Message", - "code": 95132 - }, - "Selection is not a valid type node": { - "category": "Message", - "code": 95133 - }, - "No type could be extracted from this type node": { - "category": "Message", - "code": 95134 - }, - "Could not find property for which to generate accessor": { - "category": "Message", - "code": 95135 - }, - "Name is not valid": { - "category": "Message", - "code": 95136 - }, - "Can only convert property with modifier": { - "category": "Message", - "code": 95137 - }, - "Switch each misused '{0}' to '{1}'": { - "category": "Message", - "code": 95138 - }, - "Convert to optional chain expression": { - "category": "Message", - "code": 95139 - }, - "Could not find convertible access expression": { - "category": "Message", - "code": 95140 - }, - "Could not find matching access expressions": { - "category": "Message", - "code": 95141 - }, - "Can only convert logical AND access chains": { - "category": "Message", - "code": 95142 - }, - "Add 'void' to Promise resolved without a value": { - "category": "Message", - "code": 95143 - }, - "Add 'void' to all Promises resolved without a value": { - "category": "Message", - "code": 95144 - }, - "Use element access for '{0}'": { - "category": "Message", - "code": 95145 - }, - "Use element access for all undeclared properties.": { - "category": "Message", - "code": 95146 - }, - "Delete all unused imports": { - "category": "Message", - "code": 95147 - }, - "Infer function return type": { - "category": "Message", - "code": 95148 - }, - "Return type must be inferred from a function": { - "category": "Message", - "code": 95149 - }, - "Could not determine function return type": { - "category": "Message", - "code": 95150 - }, - "Could not convert to arrow function": { - "category": "Message", - "code": 95151 - }, - "Could not convert to named function": { - "category": "Message", - "code": 95152 - }, - "Could not convert to anonymous function": { - "category": "Message", - "code": 95153 - }, - "Can only convert string concatenations and string literals": { - "category": "Message", - "code": 95154 - }, - "Selection is not a valid statement or statements": { - "category": "Message", - "code": 95155 - }, - "Add missing function declaration '{0}'": { - "category": "Message", - "code": 95156 - }, - "Add all missing function declarations": { - "category": "Message", - "code": 95157 - }, - "Method not implemented.": { - "category": "Message", - "code": 95158 - }, - "Function not implemented.": { - "category": "Message", - "code": 95159 - }, - "Add 'override' modifier": { - "category": "Message", - "code": 95160 - }, - "Remove 'override' modifier": { - "category": "Message", - "code": 95161 - }, - "Add all missing 'override' modifiers": { - "category": "Message", - "code": 95162 - }, - "Remove all unnecessary 'override' modifiers": { - "category": "Message", - "code": 95163 - }, - "Can only convert named export": { - "category": "Message", - "code": 95164 - }, - "Add missing properties": { - "category": "Message", - "code": 95165 - }, - "Add all missing properties": { - "category": "Message", - "code": 95166 - }, - "Add missing attributes": { - "category": "Message", - "code": 95167 - }, - "Add all missing attributes": { - "category": "Message", - "code": 95168 - }, - "Add 'undefined' to optional property type": { - "category": "Message", - "code": 95169 - }, - "Convert named imports to default import": { - "category": "Message", - "code": 95170 - }, - "Delete unused '@param' tag '{0}'": { - "category": "Message", - "code": 95171 - }, - "Delete all unused '@param' tags": { - "category": "Message", - "code": 95172 - }, - "Rename '@param' tag name '{0}' to '{1}'": { - "category": "Message", - "code": 95173 - }, - "Use `{0}`.": { - "category": "Message", - "code": 95174 - }, - "Use `Number.isNaN` in all conditions.": { - "category": "Message", - "code": 95175 - }, - "Convert typedef to TypeScript type.": { - "category": "Message", - "code": 95176 - }, - "Convert all typedef to TypeScript types.": { - "category": "Message", - "code": 95177 - }, - "Move to file": { - "category": "Message", - "code": 95178 - }, - "Cannot move to file, selected file is invalid": { - "category": "Message", - "code": 95179 - }, - "Use 'import type'": { - "category": "Message", - "code": 95180 - }, - "Use 'type {0}'": { - "category": "Message", - "code": 95181 - }, - "Fix all with type-only imports": { - "category": "Message", - "code": 95182 - }, - "Cannot move statements to the selected file": { - "category": "Message", - "code": 95183 - }, - "Inline variable": { - "category": "Message", - "code": 95184 - }, - "Could not find variable to inline.": { - "category": "Message", - "code": 95185 - }, - "Variables with multiple declarations cannot be inlined.": { - "category": "Message", - "code": 95186 - }, - "Add missing comma for object member completion '{0}'.": { - "category": "Message", - "code": 95187 - }, - "Add missing parameter to '{0}'": { - "category": "Message", - "code": 95188 - }, - "Add missing parameters to '{0}'": { - "category": "Message", - "code": 95189 - }, - "Add all missing parameters": { - "category": "Message", - "code": 95190 - }, - "Add optional parameter to '{0}'": { - "category": "Message", - "code": 95191 - }, - "Add optional parameters to '{0}'": { - "category": "Message", - "code": 95192 - }, - "Add all optional parameters": { - "category": "Message", - "code": 95193 - }, - "Wrap in parentheses": { - "category": "Message", - "code": 95194 - }, - "Wrap all invalid decorator expressions in parentheses": { - "category": "Message", - "code": 95195 - }, - "Add 'resolution-mode' import attribute": { - "category": "Message", - "code": 95196 - }, - "Add 'resolution-mode' import attribute to all type-only imports that need it": { - "category": "Message", - "code": 95197 - }, - - "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": { - "category": "Error", - "code": 18004 - }, - "Classes may not have a field named 'constructor'.": { - "category": "Error", - "code": 18006 - }, - "JSX expressions may not use the comma operator. Did you mean to write an array?": { - "category": "Error", - "code": 18007 - }, - "Private identifiers cannot be used as parameters.": { - "category": "Error", - "code": 18009 - }, - "An accessibility modifier cannot be used with a private identifier.": { - "category": "Error", - "code": 18010 - }, - "The operand of a 'delete' operator cannot be a private identifier.": { - "category": "Error", - "code": 18011 - }, - "'#constructor' is a reserved word.": { - "category": "Error", - "code": 18012 - }, - "Property '{0}' is not accessible outside class '{1}' because it has a private identifier.": { - "category": "Error", - "code": 18013 - }, - "The property '{0}' cannot be accessed on type '{1}' within this class because it is shadowed by another private identifier with the same spelling.": { - "category": "Error", - "code": 18014 - }, - "Property '{0}' in type '{1}' refers to a different member that cannot be accessed from within type '{2}'.": { - "category": "Error", - "code": 18015 - }, - "Private identifiers are not allowed outside class bodies.": { - "category": "Error", - "code": 18016 - }, - "The shadowing declaration of '{0}' is defined here": { - "category": "Error", - "code": 18017 - }, - "The declaration of '{0}' that you probably intended to use is defined here": { - "category": "Error", - "code": 18018 - }, - "'{0}' modifier cannot be used with a private identifier.": { - "category": "Error", - "code": 18019 - }, - "An enum member cannot be named with a private identifier.": { - "category": "Error", - "code": 18024 - }, - "'#!' can only be used at the start of a file.": { - "category": "Error", - "code": 18026 - }, - "Compiler reserves name '{0}' when emitting private identifier downlevel.": { - "category": "Error", - "code": 18027 - }, - "Private identifiers are only available when targeting ECMAScript 2015 and higher.": { - "category": "Error", - "code": 18028 - }, - "Private identifiers are not allowed in variable declarations.": { - "category": "Error", - "code": 18029 - }, - "An optional chain cannot contain private identifiers.": { - "category": "Error", - "code": 18030 - }, - "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents.": { - "category": "Error", - "code": 18031 - }, - "The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some.": { - "category": "Error", - "code": 18032 - }, - "Type '{0}' is not assignable to type '{1}' as required for computed enum member values.": { - "category": "Error", - "code": 18033 - }, - "Specify the JSX fragment factory function to use when targeting 'react' JSX emit with 'jsxFactory' compiler option is specified, e.g. 'Fragment'.": { - "category": "Message", - "code": 18034 - }, - "Invalid value for 'jsxFragmentFactory'. '{0}' is not a valid identifier or qualified-name.": { - "category": "Error", - "code": 18035 - }, - "Class decorators can't be used with static private identifier. Consider removing the experimental decorator.": { - "category": "Error", - "code": 18036 - }, - "'await' expression cannot be used inside a class static block.": { - "category": "Error", - "code": 18037 - }, - "'for await' loops cannot be used inside a class static block.": { - "category": "Error", - "code": 18038 - }, - "Invalid use of '{0}'. It cannot be used inside a class static block.": { - "category": "Error", - "code": 18039 - }, - "A 'return' statement cannot be used inside a class static block.": { - "category": "Error", - "code": 18041 - }, - "'{0}' is a type and cannot be imported in JavaScript files. Use '{1}' in a JSDoc type annotation.": { - "category": "Error", - "code": 18042 - }, - "Types cannot appear in export declarations in JavaScript files.": { - "category": "Error", - "code": 18043 - }, - "'{0}' is automatically exported here.": { - "category": "Message", - "code": 18044 - }, - "Properties with the 'accessor' modifier are only available when targeting ECMAScript 2015 and higher.": { - "category": "Error", - "code": 18045 - }, - "'{0}' is of type 'unknown'.": { - "category": "Error", - "code": 18046 - }, - "'{0}' is possibly 'null'.": { - "category": "Error", - "code": 18047 - }, - "'{0}' is possibly 'undefined'.": { - "category": "Error", - "code": 18048 - }, - "'{0}' is possibly 'null' or 'undefined'.": { - "category": "Error", - "code": 18049 - }, - "The value '{0}' cannot be used here.": { - "category": "Error", - "code": 18050 - }, - "Compiler option '{0}' cannot be given an empty string.": { - "category": "Error", - "code": 18051 - }, - "Its type '{0}' is not a valid JSX element type.": { - "category": "Error", - "code": 18053 - }, - "'await using' statements cannot be used inside a class static block.": { - "category": "Error", - "code": 18054 - }, - "'{0}' has a string type, but must have syntactically recognizable string syntax when 'isolatedModules' is enabled.": { - "category": "Error", - "code": 18055 - }, - "Enum member following a non-literal numeric member must have an initializer when 'isolatedModules' is enabled.": { - "category": "Error", - "code": 18056 - }, - "String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.": { - "category": "Error", - "code": 18057 - }, - "Default imports are not allowed in a deferred import.": { - "category": "Error", - "code": 18058 - }, - "Named imports are not allowed in a deferred import.": { - "category": "Error", - "code": 18059 - }, - "Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'preserve'.": { - "category": "Error", - "code": 18060 - }, - "'{0}' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'?": { - "category": "Error", - "code": 18061 - } -} +{ + "Unterminated string literal.": { + "category": "Error", + "code": 1002 + }, + "Identifier expected.": { + "category": "Error", + "code": 1003 + }, + "'{0}' expected.": { + "category": "Error", + "code": 1005 + }, + "A file cannot have a reference to itself.": { + "category": "Error", + "code": 1006 + }, + "The parser expected to find a '{1}' to match the '{0}' token here.": { + "category": "Error", + "code": 1007 + }, + "Trailing comma not allowed.": { + "category": "Error", + "code": 1009 + }, + "'*/' expected.": { + "category": "Error", + "code": 1010 + }, + "An element access expression should take an argument.": { + "category": "Error", + "code": 1011 + }, + "Unexpected token.": { + "category": "Error", + "code": 1012 + }, + "A rest parameter or binding pattern may not have a trailing comma.": { + "category": "Error", + "code": 1013 + }, + "A rest parameter must be last in a parameter list.": { + "category": "Error", + "code": 1014 + }, + "Parameter cannot have question mark and initializer.": { + "category": "Error", + "code": 1015 + }, + "A required parameter cannot follow an optional parameter.": { + "category": "Error", + "code": 1016 + }, + "An index signature cannot have a rest parameter.": { + "category": "Error", + "code": 1017 + }, + "An index signature parameter cannot have an accessibility modifier.": { + "category": "Error", + "code": 1018 + }, + "An index signature parameter cannot have a question mark.": { + "category": "Error", + "code": 1019 + }, + "An index signature parameter cannot have an initializer.": { + "category": "Error", + "code": 1020 + }, + "An index signature must have a type annotation.": { + "category": "Error", + "code": 1021 + }, + "An index signature parameter must have a type annotation.": { + "category": "Error", + "code": 1022 + }, + "'readonly' modifier can only appear on a property declaration or index signature.": { + "category": "Error", + "code": 1024 + }, + "An index signature cannot have a trailing comma.": { + "category": "Error", + "code": 1025 + }, + "Accessibility modifier already seen.": { + "category": "Error", + "code": 1028 + }, + "'{0}' modifier must precede '{1}' modifier.": { + "category": "Error", + "code": 1029 + }, + "'{0}' modifier already seen.": { + "category": "Error", + "code": 1030 + }, + "'{0}' modifier cannot appear on class elements of this kind.": { + "category": "Error", + "code": 1031 + }, + "'super' must be followed by an argument list or member access.": { + "category": "Error", + "code": 1034 + }, + "Only ambient modules can use quoted names.": { + "category": "Error", + "code": 1035 + }, + "Statements are not allowed in ambient contexts.": { + "category": "Error", + "code": 1036 + }, + "A 'declare' modifier cannot be used in an already ambient context.": { + "category": "Error", + "code": 1038 + }, + "Initializers are not allowed in ambient contexts.": { + "category": "Error", + "code": 1039 + }, + "'{0}' modifier cannot be used in an ambient context.": { + "category": "Error", + "code": 1040 + }, + "'{0}' modifier cannot be used here.": { + "category": "Error", + "code": 1042 + }, + "'{0}' modifier cannot appear on a module or namespace element.": { + "category": "Error", + "code": 1044 + }, + "Top-level declarations in .d.ts files must start with either a 'declare' or 'export' modifier.": { + "category": "Error", + "code": 1046 + }, + "A rest parameter cannot be optional.": { + "category": "Error", + "code": 1047 + }, + "A rest parameter cannot have an initializer.": { + "category": "Error", + "code": 1048 + }, + "A 'set' accessor must have exactly one parameter.": { + "category": "Error", + "code": 1049 + }, + "A 'set' accessor cannot have an optional parameter.": { + "category": "Error", + "code": 1051 + }, + "A 'set' accessor parameter cannot have an initializer.": { + "category": "Error", + "code": 1052 + }, + "A 'set' accessor cannot have rest parameter.": { + "category": "Error", + "code": 1053 + }, + "A 'get' accessor cannot have parameters.": { + "category": "Error", + "code": 1054 + }, + "Type '{0}' is not a valid async function return type in ES5 because it does not refer to a Promise-compatible constructor value.": { + "category": "Error", + "code": 1055 + }, + "Accessors are only available when targeting ECMAScript 5 and higher.": { + "category": "Error", + "code": 1056 + }, + "The return type of an async function must either be a valid promise or must not contain a callable 'then' member.": { + "category": "Error", + "code": 1058 + }, + "A promise must have a 'then' method.": { + "category": "Error", + "code": 1059 + }, + "The first parameter of the 'then' method of a promise must be a callback.": { + "category": "Error", + "code": 1060 + }, + "Enum member must have initializer.": { + "category": "Error", + "code": 1061 + }, + "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": { + "category": "Error", + "code": 1062 + }, + "An export assignment cannot be used in a namespace.": { + "category": "Error", + "code": 1063 + }, + "The return type of an async function or method must be the global Promise type. Did you mean to write 'Promise<{0}>'?": { + "category": "Error", + "code": 1064 + }, + "The return type of an async function or method must be the global Promise type.": { + "category": "Error", + "code": 1065 + }, + "In ambient enum declarations member initializer must be constant expression.": { + "category": "Error", + "code": 1066 + }, + "Unexpected token. A constructor, method, accessor, or property was expected.": { + "category": "Error", + "code": 1068 + }, + "Unexpected token. A type parameter name was expected without curly braces.": { + "category": "Error", + "code": 1069 + }, + "'{0}' modifier cannot appear on a type member.": { + "category": "Error", + "code": 1070 + }, + "'{0}' modifier cannot appear on an index signature.": { + "category": "Error", + "code": 1071 + }, + "A '{0}' modifier cannot be used with an import declaration.": { + "category": "Error", + "code": 1079 + }, + "Invalid 'reference' directive syntax.": { + "category": "Error", + "code": 1084 + }, + "'{0}' modifier cannot appear on a constructor declaration.": { + "category": "Error", + "code": 1089 + }, + "'{0}' modifier cannot appear on a parameter.": { + "category": "Error", + "code": 1090 + }, + "Only a single variable declaration is allowed in a 'for...in' statement.": { + "category": "Error", + "code": 1091 + }, + "Type parameters cannot appear on a constructor declaration.": { + "category": "Error", + "code": 1092 + }, + "Type annotation cannot appear on a constructor declaration.": { + "category": "Error", + "code": 1093 + }, + "An accessor cannot have type parameters.": { + "category": "Error", + "code": 1094 + }, + "A 'set' accessor cannot have a return type annotation.": { + "category": "Error", + "code": 1095 + }, + "An index signature must have exactly one parameter.": { + "category": "Error", + "code": 1096 + }, + "'{0}' list cannot be empty.": { + "category": "Error", + "code": 1097 + }, + "Type parameter list cannot be empty.": { + "category": "Error", + "code": 1098 + }, + "Type argument list cannot be empty.": { + "category": "Error", + "code": 1099 + }, + "Invalid use of '{0}' in strict mode.": { + "category": "Error", + "code": 1100 + }, + "'with' statements are not allowed in strict mode.": { + "category": "Error", + "code": 1101 + }, + "'delete' cannot be called on an identifier in strict mode.": { + "category": "Error", + "code": 1102 + }, + "'for await' loops are only allowed within async functions and at the top levels of modules.": { + "category": "Error", + "code": 1103 + }, + "A 'continue' statement can only be used within an enclosing iteration statement.": { + "category": "Error", + "code": 1104 + }, + "A 'break' statement can only be used within an enclosing iteration or switch statement.": { + "category": "Error", + "code": 1105 + }, + "The left-hand side of a 'for...of' statement may not be 'async'.": { + "category": "Error", + "code": 1106 + }, + "Jump target cannot cross function boundary.": { + "category": "Error", + "code": 1107 + }, + "A 'return' statement can only be used within a function body.": { + "category": "Error", + "code": 1108 + }, + "Expression expected.": { + "category": "Error", + "code": 1109 + }, + "Type expected.": { + "category": "Error", + "code": 1110 + }, + "Private field '{0}' must be declared in an enclosing class.": { + "category": "Error", + "code": 1111 + }, + "A 'default' clause cannot appear more than once in a 'switch' statement.": { + "category": "Error", + "code": 1113 + }, + "Duplicate label '{0}'.": { + "category": "Error", + "code": 1114 + }, + "A 'continue' statement can only jump to a label of an enclosing iteration statement.": { + "category": "Error", + "code": 1115 + }, + "A 'break' statement can only jump to a label of an enclosing statement.": { + "category": "Error", + "code": 1116 + }, + "An object literal cannot have multiple properties with the same name.": { + "category": "Error", + "code": 1117 + }, + "An object literal cannot have multiple get/set accessors with the same name.": { + "category": "Error", + "code": 1118 + }, + "An object literal cannot have property and accessor with the same name.": { + "category": "Error", + "code": 1119 + }, + "An export assignment cannot have modifiers.": { + "category": "Error", + "code": 1120 + }, + "Octal literals are not allowed. Use the syntax '{0}'.": { + "category": "Error", + "code": 1121 + }, + "Variable declaration list cannot be empty.": { + "category": "Error", + "code": 1123 + }, + "Digit expected.": { + "category": "Error", + "code": 1124 + }, + "Hexadecimal digit expected.": { + "category": "Error", + "code": 1125 + }, + "Unexpected end of text.": { + "category": "Error", + "code": 1126 + }, + "Invalid character.": { + "category": "Error", + "code": 1127 + }, + "Declaration or statement expected.": { + "category": "Error", + "code": 1128 + }, + "Statement expected.": { + "category": "Error", + "code": 1129 + }, + "'case' or 'default' expected.": { + "category": "Error", + "code": 1130 + }, + "Property or signature expected.": { + "category": "Error", + "code": 1131 + }, + "Enum member expected.": { + "category": "Error", + "code": 1132 + }, + "Variable declaration expected.": { + "category": "Error", + "code": 1134 + }, + "Argument expression expected.": { + "category": "Error", + "code": 1135 + }, + "Property assignment expected.": { + "category": "Error", + "code": 1136 + }, + "Expression or comma expected.": { + "category": "Error", + "code": 1137 + }, + "Parameter declaration expected.": { + "category": "Error", + "code": 1138 + }, + "Type parameter declaration expected.": { + "category": "Error", + "code": 1139 + }, + "Type argument expected.": { + "category": "Error", + "code": 1140 + }, + "String literal expected.": { + "category": "Error", + "code": 1141 + }, + "Line break not permitted here.": { + "category": "Error", + "code": 1142 + }, + "'{' or ';' expected.": { + "category": "Error", + "code": 1144 + }, + "'{' or JSX element expected.": { + "category": "Error", + "code": 1145 + }, + "Declaration expected.": { + "category": "Error", + "code": 1146 + }, + "Import declarations in a namespace cannot reference a module.": { + "category": "Error", + "code": 1147 + }, + "Cannot use imports, exports, or module augmentations when '--module' is 'none'.": { + "category": "Error", + "code": 1148 + }, + "File name '{0}' differs from already included file name '{1}' only in casing.": { + "category": "Error", + "code": 1149 + }, + "'{0}' declarations must be initialized.": { + "category": "Error", + "code": 1155 + }, + "'{0}' declarations can only be declared inside a block.": { + "category": "Error", + "code": 1156 + }, + "Unterminated template literal.": { + "category": "Error", + "code": 1160 + }, + "Unterminated regular expression literal.": { + "category": "Error", + "code": 1161 + }, + "An object member cannot be declared optional.": { + "category": "Error", + "code": 1162 + }, + "A 'yield' expression is only allowed in a generator body.": { + "category": "Error", + "code": 1163 + }, + "Computed property names are not allowed in enums.": { + "category": "Error", + "code": 1164 + }, + "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type.": { + "category": "Error", + "code": 1165 + }, + "A computed property name in a class property declaration must have a simple literal type or a 'unique symbol' type.": { + "category": "Error", + "code": 1166 + }, + "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type.": { + "category": "Error", + "code": 1168 + }, + "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.": { + "category": "Error", + "code": 1169 + }, + "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.": { + "category": "Error", + "code": 1170 + }, + "A comma expression is not allowed in a computed property name.": { + "category": "Error", + "code": 1171 + }, + "'extends' clause already seen.": { + "category": "Error", + "code": 1172 + }, + "'extends' clause must precede 'implements' clause.": { + "category": "Error", + "code": 1173 + }, + "Classes can only extend a single class.": { + "category": "Error", + "code": 1174 + }, + "'implements' clause already seen.": { + "category": "Error", + "code": 1175 + }, + "Interface declaration cannot have 'implements' clause.": { + "category": "Error", + "code": 1176 + }, + "Binary digit expected.": { + "category": "Error", + "code": 1177 + }, + "Octal digit expected.": { + "category": "Error", + "code": 1178 + }, + "Unexpected token. '{' expected.": { + "category": "Error", + "code": 1179 + }, + "Property destructuring pattern expected.": { + "category": "Error", + "code": 1180 + }, + "Array element destructuring pattern expected.": { + "category": "Error", + "code": 1181 + }, + "A destructuring declaration must have an initializer.": { + "category": "Error", + "code": 1182 + }, + "An implementation cannot be declared in ambient contexts.": { + "category": "Error", + "code": 1183 + }, + "Modifiers cannot appear here.": { + "category": "Error", + "code": 1184 + }, + "Merge conflict marker encountered.": { + "category": "Error", + "code": 1185 + }, + "A rest element cannot have an initializer.": { + "category": "Error", + "code": 1186 + }, + "A parameter property may not be declared using a binding pattern.": { + "category": "Error", + "code": 1187 + }, + "Only a single variable declaration is allowed in a 'for...of' statement.": { + "category": "Error", + "code": 1188 + }, + "The variable declaration of a 'for...in' statement cannot have an initializer.": { + "category": "Error", + "code": 1189 + }, + "The variable declaration of a 'for...of' statement cannot have an initializer.": { + "category": "Error", + "code": 1190 + }, + "An import declaration cannot have modifiers.": { + "category": "Error", + "code": 1191 + }, + "Module '{0}' has no default export.": { + "category": "Error", + "code": 1192 + }, + "An export declaration cannot have modifiers.": { + "category": "Error", + "code": 1193 + }, + "Export declarations are not permitted in a namespace.": { + "category": "Error", + "code": 1194 + }, + "'export *' does not re-export a default.": { + "category": "Error", + "code": 1195 + }, + "Catch clause variable type annotation must be 'any' or 'unknown' if specified.": { + "category": "Error", + "code": 1196 + }, + "Catch clause variable cannot have an initializer.": { + "category": "Error", + "code": 1197 + }, + "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive.": { + "category": "Error", + "code": 1198 + }, + "Unterminated Unicode escape sequence.": { + "category": "Error", + "code": 1199 + }, + "Line terminator not permitted before arrow.": { + "category": "Error", + "code": 1200 + }, + "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead.": { + "category": "Error", + "code": 1202 + }, + "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.": { + "category": "Error", + "code": 1203 + }, + "Re-exporting a type when '{0}' is enabled requires using 'export type'.": { + "category": "Error", + "code": 1205 + }, + "Decorators are not valid here.": { + "category": "Error", + "code": 1206 + }, + "Decorators cannot be applied to multiple get/set accessors of the same name.": { + "category": "Error", + "code": 1207 + }, + "Invalid optional chain from new expression. Did you mean to call '{0}()'?": { + "category": "Error", + "code": 1209 + }, + "Code contained in a class is evaluated in JavaScript's strict mode which does not allow this use of '{0}'. For more information, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode.": { + "category": "Error", + "code": 1210 + }, + "A class declaration without the 'default' modifier must have a name.": { + "category": "Error", + "code": 1211 + }, + "Identifier expected. '{0}' is a reserved word in strict mode.": { + "category": "Error", + "code": 1212 + }, + "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode.": { + "category": "Error", + "code": 1213 + }, + "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode.": { + "category": "Error", + "code": 1214 + }, + "Invalid use of '{0}'. Modules are automatically in strict mode.": { + "category": "Error", + "code": 1215 + }, + "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules.": { + "category": "Error", + "code": 1216 + }, + "Export assignment is not supported when '--module' flag is 'system'.": { + "category": "Error", + "code": 1218 + }, + "Generators are not allowed in an ambient context.": { + "category": "Error", + "code": 1221 + }, + "An overload signature cannot be declared as a generator.": { + "category": "Error", + "code": 1222 + }, + "'{0}' tag already specified.": { + "category": "Error", + "code": 1223 + }, + "Signature '{0}' must be a type predicate.": { + "category": "Error", + "code": 1224 + }, + "Cannot find parameter '{0}'.": { + "category": "Error", + "code": 1225 + }, + "Type predicate '{0}' is not assignable to '{1}'.": { + "category": "Error", + "code": 1226 + }, + "Parameter '{0}' is not in the same position as parameter '{1}'.": { + "category": "Error", + "code": 1227 + }, + "A type predicate is only allowed in return type position for functions and methods.": { + "category": "Error", + "code": 1228 + }, + "A type predicate cannot reference a rest parameter.": { + "category": "Error", + "code": 1229 + }, + "A type predicate cannot reference element '{0}' in a binding pattern.": { + "category": "Error", + "code": 1230 + }, + "An export assignment must be at the top level of a file or module declaration.": { + "category": "Error", + "code": 1231 + }, + "An import declaration can only be used at the top level of a namespace or module.": { + "category": "Error", + "code": 1232 + }, + "An export declaration can only be used at the top level of a namespace or module.": { + "category": "Error", + "code": 1233 + }, + "An ambient module declaration is only allowed at the top level in a file.": { + "category": "Error", + "code": 1234 + }, + "A namespace declaration is only allowed at the top level of a namespace or module.": { + "category": "Error", + "code": 1235 + }, + "The return type of a property decorator function must be either 'void' or 'any'.": { + "category": "Error", + "code": 1236 + }, + "The return type of a parameter decorator function must be either 'void' or 'any'.": { + "category": "Error", + "code": 1237 + }, + "Unable to resolve signature of class decorator when called as an expression.": { + "category": "Error", + "code": 1238 + }, + "Unable to resolve signature of parameter decorator when called as an expression.": { + "category": "Error", + "code": 1239 + }, + "Unable to resolve signature of property decorator when called as an expression.": { + "category": "Error", + "code": 1240 + }, + "Unable to resolve signature of method decorator when called as an expression.": { + "category": "Error", + "code": 1241 + }, + "'abstract' modifier can only appear on a class, method, or property declaration.": { + "category": "Error", + "code": 1242 + }, + "'{0}' modifier cannot be used with '{1}' modifier.": { + "category": "Error", + "code": 1243 + }, + "Abstract methods can only appear within an abstract class.": { + "category": "Error", + "code": 1244 + }, + "Method '{0}' cannot have an implementation because it is marked abstract.": { + "category": "Error", + "code": 1245 + }, + "An interface property cannot have an initializer.": { + "category": "Error", + "code": 1246 + }, + "A type literal property cannot have an initializer.": { + "category": "Error", + "code": 1247 + }, + "A class member cannot have the '{0}' keyword.": { + "category": "Error", + "code": 1248 + }, + "A decorator can only decorate a method implementation, not an overload.": { + "category": "Error", + "code": 1249 + }, + "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'.": { + "category": "Error", + "code": 1250 + }, + "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'. Class definitions are automatically in strict mode.": { + "category": "Error", + "code": 1251 + }, + "Function declarations are not allowed inside blocks in strict mode when targeting 'ES5'. Modules are automatically in strict mode.": { + "category": "Error", + "code": 1252 + }, + "Abstract properties can only appear within an abstract class.": { + "category": "Error", + "code": 1253 + }, + "A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.": { + "category": "Error", + "code": 1254 + }, + "A definite assignment assertion '!' is not permitted in this context.": { + "category": "Error", + "code": 1255 + }, + "A required element cannot follow an optional element.": { + "category": "Error", + "code": 1257 + }, + "A default export must be at the top level of a file or module declaration.": { + "category": "Error", + "code": 1258 + }, + "Module '{0}' can only be default-imported using the '{1}' flag": { + "category": "Error", + "code": 1259 + }, + "Keywords cannot contain escape characters.": { + "category": "Error", + "code": 1260 + }, + "Already included file name '{0}' differs from file name '{1}' only in casing.": { + "category": "Error", + "code": 1261 + }, + "Identifier expected. '{0}' is a reserved word at the top-level of a module.": { + "category": "Error", + "code": 1262 + }, + "Declarations with initializers cannot also have definite assignment assertions.": { + "category": "Error", + "code": 1263 + }, + "Declarations with definite assignment assertions must also have type annotations.": { + "category": "Error", + "code": 1264 + }, + "A rest element cannot follow another rest element.": { + "category": "Error", + "code": 1265 + }, + "An optional element cannot follow a rest element.": { + "category": "Error", + "code": 1266 + }, + "Property '{0}' cannot have an initializer because it is marked abstract.": { + "category": "Error", + "code": 1267 + }, + "An index signature parameter type must be 'string', 'number', 'symbol', or a template literal type.": { + "category": "Error", + "code": 1268 + }, + "Cannot use 'export import' on a type or type-only namespace when '{0}' is enabled.": { + "category": "Error", + "code": 1269 + }, + "Decorator function return type '{0}' is not assignable to type '{1}'.": { + "category": "Error", + "code": 1270 + }, + "Decorator function return type is '{0}' but is expected to be 'void' or 'any'.": { + "category": "Error", + "code": 1271 + }, + "A type referenced in a decorated signature must be imported with 'import type' or a namespace import when 'isolatedModules' and 'emitDecoratorMetadata' are enabled.": { + "category": "Error", + "code": 1272 + }, + "'{0}' modifier cannot appear on a type parameter": { + "category": "Error", + "code": 1273 + }, + "'{0}' modifier can only appear on a type parameter of a class, interface or type alias": { + "category": "Error", + "code": 1274 + }, + "'accessor' modifier can only appear on a property declaration.": { + "category": "Error", + "code": 1275 + }, + "An 'accessor' property cannot be declared optional.": { + "category": "Error", + "code": 1276 + }, + "'{0}' modifier can only appear on a type parameter of a function, method or class": { + "category": "Error", + "code": 1277 + }, + "The runtime will invoke the decorator with {1} arguments, but the decorator expects {0}.": { + "category": "Error", + "code": 1278 + }, + "The runtime will invoke the decorator with {1} arguments, but the decorator expects at least {0}.": { + "category": "Error", + "code": 1279 + }, + "Namespaces are not allowed in global script files when '{0}' is enabled. If this file is not intended to be a global script, set 'moduleDetection' to 'force' or add an empty 'export {}' statement.": { + "category": "Error", + "code": 1280 + }, + "Cannot access '{0}' from another file without qualification when '{1}' is enabled. Use '{2}' instead.": { + "category": "Error", + "code": 1281 + }, + "An 'export =' declaration must reference a value when 'verbatimModuleSyntax' is enabled, but '{0}' only refers to a type.": { + "category": "Error", + "code": 1282 + }, + "An 'export =' declaration must reference a real value when 'verbatimModuleSyntax' is enabled, but '{0}' resolves to a type-only declaration.": { + "category": "Error", + "code": 1283 + }, + "An 'export default' must reference a value when 'verbatimModuleSyntax' is enabled, but '{0}' only refers to a type.": { + "category": "Error", + "code": 1284 + }, + "An 'export default' must reference a real value when 'verbatimModuleSyntax' is enabled, but '{0}' resolves to a type-only declaration.": { + "category": "Error", + "code": 1285 + }, + "ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.": { + "category": "Error", + "code": 1286 + }, + "A top-level 'export' modifier cannot be used on value declarations in a CommonJS module when 'verbatimModuleSyntax' is enabled.": { + "category": "Error", + "code": 1287 + }, + "An import alias cannot resolve to a type or type-only declaration when 'verbatimModuleSyntax' is enabled.": { + "category": "Error", + "code": 1288 + }, + "'{0}' resolves to a type-only declaration and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'import type' where '{0}' is imported.": { + "category": "Error", + "code": 1289 + }, + "'{0}' resolves to a type-only declaration and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'export type { {0} as default }'.": { + "category": "Error", + "code": 1290 + }, + "'{0}' resolves to a type and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'import type' where '{0}' is imported.": { + "category": "Error", + "code": 1291 + }, + "'{0}' resolves to a type and must be marked type-only in this file before re-exporting when '{1}' is enabled. Consider using 'export type { {0} as default }'.": { + "category": "Error", + "code": 1292 + }, + "ECMAScript module syntax is not allowed in a CommonJS module when 'module' is set to 'preserve'.": { + "category": "Error", + "code": 1293 + }, + "This syntax is not allowed when 'erasableSyntaxOnly' is enabled.": { + "category": "Error", + "code": 1294 + }, + "ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'. Adjust the 'type' field in the nearest 'package.json' to make this file an ECMAScript module, or adjust your 'verbatimModuleSyntax', 'module', and 'moduleResolution' settings in TypeScript.": { + "category": "Error", + "code": 1295 + }, + "'with' statements are not allowed in an async function block.": { + "category": "Error", + "code": 1300 + }, + "'await' expressions are only allowed within async functions and at the top levels of modules.": { + "category": "Error", + "code": 1308 + }, + "The current file is a CommonJS module and cannot use 'await' at the top level.": { + "category": "Error", + "code": 1309 + }, + "Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern.": { + "category": "Error", + "code": 1312 + }, + "The body of an 'if' statement cannot be the empty statement.": { + "category": "Error", + "code": 1313 + }, + "Global module exports may only appear in module files.": { + "category": "Error", + "code": 1314 + }, + "Global module exports may only appear in declaration files.": { + "category": "Error", + "code": 1315 + }, + "Global module exports may only appear at top level.": { + "category": "Error", + "code": 1316 + }, + "A parameter property cannot be declared using a rest parameter.": { + "category": "Error", + "code": 1317 + }, + "An abstract accessor cannot have an implementation.": { + "category": "Error", + "code": 1318 + }, + "A default export can only be used in an ECMAScript-style module.": { + "category": "Error", + "code": 1319 + }, + "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member.": { + "category": "Error", + "code": 1320 + }, + "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member.": { + "category": "Error", + "code": 1321 + }, + "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member.": { + "category": "Error", + "code": 1322 + }, + "Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', 'node18', 'node20', or 'nodenext'.": { + "category": "Error", + "code": 1323 + }, + "Dynamic imports only support a second argument when the '--module' option is set to 'esnext', 'node16', 'node18', 'node20', 'nodenext', or 'preserve'.": { + "category": "Error", + "code": 1324 + }, + "Argument of dynamic import cannot be spread element.": { + "category": "Error", + "code": 1325 + }, + "This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.": { + "category": "Error", + "code": 1326 + }, + "String literal with double quotes expected.": { + "category": "Error", + "code": 1327 + }, + "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.": { + "category": "Error", + "code": 1328 + }, + "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?": { + "category": "Error", + "code": 1329 + }, + "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'.": { + "category": "Error", + "code": 1330 + }, + "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'.": { + "category": "Error", + "code": 1331 + }, + "A variable whose type is a 'unique symbol' type must be 'const'.": { + "category": "Error", + "code": 1332 + }, + "'unique symbol' types may not be used on a variable declaration with a binding name.": { + "category": "Error", + "code": 1333 + }, + "'unique symbol' types are only allowed on variables in a variable statement.": { + "category": "Error", + "code": 1334 + }, + "'unique symbol' types are not allowed here.": { + "category": "Error", + "code": 1335 + }, + "An index signature parameter type cannot be a literal type or generic type. Consider using a mapped object type instead.": { + "category": "Error", + "code": 1337 + }, + "'infer' declarations are only permitted in the 'extends' clause of a conditional type.": { + "category": "Error", + "code": 1338 + }, + "Module '{0}' does not refer to a value, but is used as a value here.": { + "category": "Error", + "code": 1339 + }, + "Module '{0}' does not refer to a type, but is used as a type here. Did you mean 'typeof import('{0}')'?": { + "category": "Error", + "code": 1340 + }, + "Class constructor may not be an accessor.": { + "category": "Error", + "code": 1341 + }, + "The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', or 'nodenext'.": { + "category": "Error", + "code": 1343 + }, + "A label is not allowed here.": { + "category": "Error", + "code": 1344 + }, + "An expression of type 'void' cannot be tested for truthiness.": { + "category": "Error", + "code": 1345 + }, + "This parameter is not allowed with 'use strict' directive.": { + "category": "Error", + "code": 1346 + }, + "'use strict' directive cannot be used with non-simple parameter list.": { + "category": "Error", + "code": 1347 + }, + "Non-simple parameter declared here.": { + "category": "Error", + "code": 1348 + }, + "'use strict' directive used here.": { + "category": "Error", + "code": 1349 + }, + "Print the final configuration instead of building.": { + "category": "Message", + "code": 1350 + }, + "An identifier or keyword cannot immediately follow a numeric literal.": { + "category": "Error", + "code": 1351 + }, + "A bigint literal cannot use exponential notation.": { + "category": "Error", + "code": 1352 + }, + "A bigint literal must be an integer.": { + "category": "Error", + "code": 1353 + }, + "'readonly' type modifier is only permitted on array and tuple literal types.": { + "category": "Error", + "code": 1354 + }, + "A 'const' assertion can only be applied to references to enum members, or string, number, boolean, array, or object literals.": { + "category": "Error", + "code": 1355 + }, + "Did you mean to mark this function as 'async'?": { + "category": "Error", + "code": 1356 + }, + "An enum member name must be followed by a ',', '=', or '}'.": { + "category": "Error", + "code": 1357 + }, + "Tagged template expressions are not permitted in an optional chain.": { + "category": "Error", + "code": 1358 + }, + "Identifier expected. '{0}' is a reserved word that cannot be used here.": { + "category": "Error", + "code": 1359 + }, + "Type '{0}' does not satisfy the expected type '{1}'.": { + "category": "Error", + "code": 1360 + }, + "'{0}' cannot be used as a value because it was imported using 'import type'.": { + "category": "Error", + "code": 1361 + }, + "'{0}' cannot be used as a value because it was exported using 'export type'.": { + "category": "Error", + "code": 1362 + }, + "A type-only import can specify a default import or named bindings, but not both.": { + "category": "Error", + "code": 1363 + }, + "Convert to type-only export": { + "category": "Message", + "code": 1364 + }, + "Convert all re-exported types to type-only exports": { + "category": "Message", + "code": 1365 + }, + "Split into two separate import declarations": { + "category": "Message", + "code": 1366 + }, + "Split all invalid type-only imports": { + "category": "Message", + "code": 1367 + }, + "Class constructor may not be a generator.": { + "category": "Error", + "code": 1368 + }, + "Did you mean '{0}'?": { + "category": "Message", + "code": 1369 + }, + "'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { + "category": "Error", + "code": 1375 + }, + "'{0}' was imported here.": { + "category": "Message", + "code": 1376 + }, + "'{0}' was exported here.": { + "category": "Message", + "code": 1377 + }, + "Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.": { + "category": "Error", + "code": 1378 + }, + "An import alias cannot reference a declaration that was exported using 'export type'.": { + "category": "Error", + "code": 1379 + }, + "An import alias cannot reference a declaration that was imported using 'import type'.": { + "category": "Error", + "code": 1380 + }, + "Unexpected token. Did you mean `{'}'}` or `}`?": { + "category": "Error", + "code": 1381 + }, + "Unexpected token. Did you mean `{'>'}` or `>`?": { + "category": "Error", + "code": 1382 + }, + "Function type notation must be parenthesized when used in a union type.": { + "category": "Error", + "code": 1385 + }, + "Constructor type notation must be parenthesized when used in a union type.": { + "category": "Error", + "code": 1386 + }, + "Function type notation must be parenthesized when used in an intersection type.": { + "category": "Error", + "code": 1387 + }, + "Constructor type notation must be parenthesized when used in an intersection type.": { + "category": "Error", + "code": 1388 + }, + "'{0}' is not allowed as a variable declaration name.": { + "category": "Error", + "code": 1389 + }, + "'{0}' is not allowed as a parameter name.": { + "category": "Error", + "code": 1390 + }, + "An import alias cannot use 'import type'": { + "category": "Error", + "code": 1392 + }, + "Imported via {0} from file '{1}'": { + "category": "Message", + "code": 1393 + }, + "Imported via {0} from file '{1}' with packageId '{2}'": { + "category": "Message", + "code": 1394 + }, + "Imported via {0} from file '{1}' to import 'importHelpers' as specified in compilerOptions": { + "category": "Message", + "code": 1395 + }, + "Imported via {0} from file '{1}' with packageId '{2}' to import 'importHelpers' as specified in compilerOptions": { + "category": "Message", + "code": 1396 + }, + "Imported via {0} from file '{1}' to import 'jsx' and 'jsxs' factory functions": { + "category": "Message", + "code": 1397 + }, + "Imported via {0} from file '{1}' with packageId '{2}' to import 'jsx' and 'jsxs' factory functions": { + "category": "Message", + "code": 1398 + }, + "File is included via import here.": { + "category": "Message", + "code": 1399 + }, + "Referenced via '{0}' from file '{1}'": { + "category": "Message", + "code": 1400 + }, + "File is included via reference here.": { + "category": "Message", + "code": 1401 + }, + "Type library referenced via '{0}' from file '{1}'": { + "category": "Message", + "code": 1402 + }, + "Type library referenced via '{0}' from file '{1}' with packageId '{2}'": { + "category": "Message", + "code": 1403 + }, + "File is included via type library reference here.": { + "category": "Message", + "code": 1404 + }, + "Library referenced via '{0}' from file '{1}'": { + "category": "Message", + "code": 1405 + }, + "File is included via library reference here.": { + "category": "Message", + "code": 1406 + }, + "Matched by include pattern '{0}' in '{1}'": { + "category": "Message", + "code": 1407 + }, + "File is matched by include pattern specified here.": { + "category": "Message", + "code": 1408 + }, + "Part of 'files' list in tsconfig.json": { + "category": "Message", + "code": 1409 + }, + "File is matched by 'files' list specified here.": { + "category": "Message", + "code": 1410 + }, + "Output from referenced project '{0}' included because '{1}' specified": { + "category": "Message", + "code": 1411 + }, + "Output from referenced project '{0}' included because '--module' is specified as 'none'": { + "category": "Message", + "code": 1412 + }, + "File is output from referenced project specified here.": { + "category": "Message", + "code": 1413 + }, + "Source from referenced project '{0}' included because '{1}' specified": { + "category": "Message", + "code": 1414 + }, + "Source from referenced project '{0}' included because '--module' is specified as 'none'": { + "category": "Message", + "code": 1415 + }, + "File is source from referenced project specified here.": { + "category": "Message", + "code": 1416 + }, + "Entry point of type library '{0}' specified in compilerOptions": { + "category": "Message", + "code": 1417 + }, + "Entry point of type library '{0}' specified in compilerOptions with packageId '{1}'": { + "category": "Message", + "code": 1418 + }, + "File is entry point of type library specified here.": { + "category": "Message", + "code": 1419 + }, + "Entry point for implicit type library '{0}'": { + "category": "Message", + "code": 1420 + }, + "Entry point for implicit type library '{0}' with packageId '{1}'": { + "category": "Message", + "code": 1421 + }, + "Library '{0}' specified in compilerOptions": { + "category": "Message", + "code": 1422 + }, + "File is library specified here.": { + "category": "Message", + "code": 1423 + }, + "Default library": { + "category": "Message", + "code": 1424 + }, + "Default library for target '{0}'": { + "category": "Message", + "code": 1425 + }, + "File is default library for target specified here.": { + "category": "Message", + "code": 1426 + }, + "Root file specified for compilation": { + "category": "Message", + "code": 1427 + }, + "File is output of project reference source '{0}'": { + "category": "Message", + "code": 1428 + }, + "File redirects to file '{0}'": { + "category": "Message", + "code": 1429 + }, + "The file is in the program because:": { + "category": "Message", + "code": 1430 + }, + "'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { + "category": "Error", + "code": 1431 + }, + "Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.": { + "category": "Error", + "code": 1432 + }, + "Neither decorators nor modifiers may be applied to 'this' parameters.": { + "category": "Error", + "code": 1433 + }, + "Unexpected keyword or identifier.": { + "category": "Error", + "code": 1434 + }, + "Unknown keyword or identifier. Did you mean '{0}'?": { + "category": "Error", + "code": 1435 + }, + "Decorators must precede the name and all keywords of property declarations.": { + "category": "Error", + "code": 1436 + }, + "Namespace must be given a name.": { + "category": "Error", + "code": 1437 + }, + "Interface must be given a name.": { + "category": "Error", + "code": 1438 + }, + "Type alias must be given a name.": { + "category": "Error", + "code": 1439 + }, + "Variable declaration not allowed at this location.": { + "category": "Error", + "code": 1440 + }, + "Cannot start a function call in a type annotation.": { + "category": "Error", + "code": 1441 + }, + "Expected '=' for property initializer.": { + "category": "Error", + "code": 1442 + }, + "Module declaration names may only use ' or \" quoted strings.": { + "category": "Error", + "code": 1443 + }, + "'{0}' resolves to a type-only declaration and must be re-exported using a type-only re-export when '{1}' is enabled.": { + "category": "Error", + "code": 1448 + }, + "Preserve unused imported values in the JavaScript output that would otherwise be removed.": { + "category": "Message", + "code": 1449 + }, + "Dynamic imports can only accept a module specifier and an optional set of attributes as arguments": { + "category": "Message", + "code": 1450 + }, + "Private identifiers are only allowed in class bodies and may only be used as part of a class member declaration, property access, or on the left-hand-side of an 'in' expression": { + "category": "Error", + "code": 1451 + }, + "`resolution-mode` should be either `require` or `import`.": { + "category": "Error", + "code": 1453 + }, + "`resolution-mode` can only be set for type-only imports.": { + "category": "Error", + "code": 1454 + }, + "`resolution-mode` is the only valid key for type import assertions.": { + "category": "Error", + "code": 1455 + }, + "Type import assertions should have exactly one key - `resolution-mode` - with value `import` or `require`.": { + "category": "Error", + "code": 1456 + }, + "Matched by default include pattern '**/*'": { + "category": "Message", + "code": 1457 + }, + "File is ECMAScript module because '{0}' has field \"type\" with value \"module\"": { + "category": "Message", + "code": 1458 + }, + "File is CommonJS module because '{0}' has field \"type\" whose value is not \"module\"": { + "category": "Message", + "code": 1459 + }, + "File is CommonJS module because '{0}' does not have field \"type\"": { + "category": "Message", + "code": 1460 + }, + "File is CommonJS module because 'package.json' was not found": { + "category": "Message", + "code": 1461 + }, + "'resolution-mode' is the only valid key for type import attributes.": { + "category": "Error", + "code": 1463 + }, + "Type import attributes should have exactly one key - 'resolution-mode' - with value 'import' or 'require'.": { + "category": "Error", + "code": 1464 + }, + + "The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.": { + "category": "Error", + "code": 1470 + }, + "Module '{0}' cannot be imported using this construct. The specifier only resolves to an ES module, which cannot be imported with 'require'. Use an ECMAScript import instead.": { + "category": "Error", + "code": 1471 + }, + "'catch' or 'finally' expected.": { + "category": "Error", + "code": 1472 + }, + "An import declaration can only be used at the top level of a module.": { + "category": "Error", + "code": 1473 + }, + "An export declaration can only be used at the top level of a module.": { + "category": "Error", + "code": 1474 + }, + "Control what method is used to detect module-format JS files.": { + "category": "Message", + "code": 1475 + }, + "\"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.": { + "category": "Message", + "code": 1476 + }, + "An instantiation expression cannot be followed by a property access.": { + "category": "Error", + "code": 1477 + }, + "Identifier or string literal expected.": { + "category": "Error", + "code": 1478 + }, + "The current file is a CommonJS module whose imports will produce 'require' calls; however, the referenced file is an ECMAScript module and cannot be imported with 'require'. Consider writing a dynamic 'import(\"{0}\")' call instead.": { + "category": "Error", + "code": 1479 + }, + "To convert this file to an ECMAScript module, change its file extension to '{0}' or create a local package.json file with `{ \"type\": \"module\" }`.": { + "category": "Message", + "code": 1480 + }, + "To convert this file to an ECMAScript module, change its file extension to '{0}', or add the field `\"type\": \"module\"` to '{1}'.": { + "category": "Message", + "code": 1481 + }, + "To convert this file to an ECMAScript module, add the field `\"type\": \"module\"` to '{0}'.": { + "category": "Message", + "code": 1482 + }, + "To convert this file to an ECMAScript module, create a local package.json file with `{ \"type\": \"module\" }`.": { + "category": "Message", + "code": 1483 + }, + "'{0}' is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled.": { + "category": "Error", + "code": 1484 + }, + "'{0}' resolves to a type-only declaration and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled.": { + "category": "Error", + "code": 1485 + }, + "Decorator used before 'export' here.": { + "category": "Error", + "code": 1486 + }, + "Octal escape sequences are not allowed. Use the syntax '{0}'.": { + "category": "Error", + "code": 1487 + }, + "Escape sequence '{0}' is not allowed.": { + "category": "Error", + "code": 1488 + }, + "Decimals with leading zeros are not allowed.": { + "category": "Error", + "code": 1489 + }, + "File appears to be binary.": { + "category": "Error", + "code": 1490 + }, + "'{0}' modifier cannot appear on a 'using' declaration.": { + "category": "Error", + "code": 1491 + }, + "'{0}' declarations may not have binding patterns.": { + "category": "Error", + "code": 1492 + }, + "The left-hand side of a 'for...in' statement cannot be a 'using' declaration.": { + "category": "Error", + "code": 1493 + }, + "The left-hand side of a 'for...in' statement cannot be an 'await using' declaration.": { + "category": "Error", + "code": 1494 + }, + "'{0}' modifier cannot appear on an 'await using' declaration.": { + "category": "Error", + "code": 1495 + }, + "Identifier, string literal, or number literal expected.": { + "category": "Error", + "code": 1496 + }, + "Expression must be enclosed in parentheses to be used as a decorator.": { + "category": "Error", + "code": 1497 + }, + "Invalid syntax in decorator.": { + "category": "Error", + "code": 1498 + }, + "Unknown regular expression flag.": { + "category": "Error", + "code": 1499 + }, + "Duplicate regular expression flag.": { + "category": "Error", + "code": 1500 + }, + "This regular expression flag is only available when targeting '{0}' or later.": { + "category": "Error", + "code": 1501 + }, + "The Unicode (u) flag and the Unicode Sets (v) flag cannot be set simultaneously.": { + "category": "Error", + "code": 1502 + }, + "Named capturing groups are only available when targeting 'ES2018' or later.": { + "category": "Error", + "code": 1503 + }, + "Subpattern flags must be present when there is a minus sign.": { + "category": "Error", + "code": 1504 + }, + "Incomplete quantifier. Digit expected.": { + "category": "Error", + "code": 1505 + }, + "Numbers out of order in quantifier.": { + "category": "Error", + "code": 1506 + }, + "There is nothing available for repetition.": { + "category": "Error", + "code": 1507 + }, + "Unexpected '{0}'. Did you mean to escape it with backslash?": { + "category": "Error", + "code": 1508 + }, + "This regular expression flag cannot be toggled within a subpattern.": { + "category": "Error", + "code": 1509 + }, + "'\\k' must be followed by a capturing group name enclosed in angle brackets.": { + "category": "Error", + "code": 1510 + }, + "'\\q' is only available inside character class.": { + "category": "Error", + "code": 1511 + }, + "'\\c' must be followed by an ASCII letter.": { + "category": "Error", + "code": 1512 + }, + "Undetermined character escape.": { + "category": "Error", + "code": 1513 + }, + "Expected a capturing group name.": { + "category": "Error", + "code": 1514 + }, + "Named capturing groups with the same name must be mutually exclusive to each other.": { + "category": "Error", + "code": 1515 + }, + "A character class range must not be bounded by another character class.": { + "category": "Error", + "code": 1516 + }, + "Range out of order in character class.": { + "category": "Error", + "code": 1517 + }, + "Anything that would possibly match more than a single character is invalid inside a negated character class.": { + "category": "Error", + "code": 1518 + }, + "Operators must not be mixed within a character class. Wrap it in a nested class instead.": { + "category": "Error", + "code": 1519 + }, + "Expected a class set operand.": { + "category": "Error", + "code": 1520 + }, + "'\\q' must be followed by string alternatives enclosed in braces.": { + "category": "Error", + "code": 1521 + }, + "A character class must not contain a reserved double punctuator. Did you mean to escape it with backslash?": { + "category": "Error", + "code": 1522 + }, + "Expected a Unicode property name.": { + "category": "Error", + "code": 1523 + }, + "Unknown Unicode property name.": { + "category": "Error", + "code": 1524 + }, + "Expected a Unicode property value.": { + "category": "Error", + "code": 1525 + }, + "Unknown Unicode property value.": { + "category": "Error", + "code": 1526 + }, + "Expected a Unicode property name or value.": { + "category": "Error", + "code": 1527 + }, + "Any Unicode property that would possibly match more than a single character is only available when the Unicode Sets (v) flag is set.": { + "category": "Error", + "code": 1528 + }, + "Unknown Unicode property name or value.": { + "category": "Error", + "code": 1529 + }, + "Unicode property value expressions are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.": { + "category": "Error", + "code": 1530 + }, + "'\\{0}' must be followed by a Unicode property value expression enclosed in braces.": { + "category": "Error", + "code": 1531 + }, + "There is no capturing group named '{0}' in this regular expression.": { + "category": "Error", + "code": 1532 + }, + "This backreference refers to a group that does not exist. There are only {0} capturing groups in this regular expression.": { + "category": "Error", + "code": 1533 + }, + "This backreference refers to a group that does not exist. There are no capturing groups in this regular expression.": { + "category": "Error", + "code": 1534 + }, + "This character cannot be escaped in a regular expression.": { + "category": "Error", + "code": 1535 + }, + "Octal escape sequences and backreferences are not allowed in a character class. If this was intended as an escape sequence, use the syntax '{0}' instead.": { + "category": "Error", + "code": 1536 + }, + "Decimal escape sequences and backreferences are not allowed in a character class.": { + "category": "Error", + "code": 1537 + }, + "Unicode escape sequences are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.": { + "category": "Error", + "code": 1538 + }, + "A 'bigint' literal cannot be used as a property name.": { + "category": "Error", + "code": 1539 + }, + "A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.": { + "category": "Error", + "code": 1540 + }, + "Type-only import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.": { + "category": "Error", + "code": 1541 + }, + "Type import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.": { + "category": "Error", + "code": 1542 + }, + "Importing a JSON file into an ECMAScript module requires a 'type: \"json\"' import attribute when 'module' is set to '{0}'.": { + "category": "Error", + "code": 1543 + }, + "Named imports from a JSON file into an ECMAScript module are not allowed when 'module' is set to '{0}'.": { + "category": "Error", + "code": 1544 + }, + "'using' declarations are not allowed in ambient contexts.": { + "category": "Error", + "code": 1545 + }, + "'await using' declarations are not allowed in ambient contexts.": { + "category": "Error", + "code": 1546 + }, + "'using' declarations are not allowed in 'case' or 'default' clauses unless contained within a block.": { + "category": "Error", + "code": 1547 + }, + "'await using' declarations are not allowed in 'case' or 'default' clauses unless contained within a block.": { + "category": "Error", + "code": 1548 + }, + "Ignore the tsconfig found and build with commandline options and files.": { + "category": "Message", + "code": 1549 + }, + + "The types of '{0}' are incompatible between these types.": { + "category": "Error", + "code": 2200 + }, + "The types returned by '{0}' are incompatible between these types.": { + "category": "Error", + "code": 2201 + }, + "Call signature return types '{0}' and '{1}' are incompatible.": { + "category": "Error", + "code": 2202, + "elidedInCompatabilityPyramid": true + }, + "Construct signature return types '{0}' and '{1}' are incompatible.": { + "category": "Error", + "code": 2203, + "elidedInCompatabilityPyramid": true + }, + "Call signatures with no arguments have incompatible return types '{0}' and '{1}'.": { + "category": "Error", + "code": 2204, + "elidedInCompatabilityPyramid": true + }, + "Construct signatures with no arguments have incompatible return types '{0}' and '{1}'.": { + "category": "Error", + "code": 2205, + "elidedInCompatabilityPyramid": true + }, + "The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement.": { + "category": "Error", + "code": 2206 + }, + "The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement.": { + "category": "Error", + "code": 2207 + }, + "This type parameter might need an `extends {0}` constraint.": { + "category": "Error", + "code": 2208 + }, + + "The project root is ambiguous, but is required to resolve export map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": { + "category": "Error", + "code": 2209 + }, + "The project root is ambiguous, but is required to resolve import map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": { + "category": "Error", + "code": 2210 + }, + "Add `extends` constraint.": { + "category": "Message", + "code": 2211 + }, + "Add `extends` constraint to all type parameters": { + "category": "Message", + "code": 2212 + }, + + "Duplicate identifier '{0}'.": { + "category": "Error", + "code": 2300 + }, + "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": { + "category": "Error", + "code": 2301 + }, + "Static members cannot reference class type parameters.": { + "category": "Error", + "code": 2302 + }, + "Circular definition of import alias '{0}'.": { + "category": "Error", + "code": 2303 + }, + "Cannot find name '{0}'.": { + "category": "Error", + "code": 2304 + }, + "Module '{0}' has no exported member '{1}'.": { + "category": "Error", + "code": 2305 + }, + "File '{0}' is not a module.": { + "category": "Error", + "code": 2306 + }, + "Cannot find module '{0}' or its corresponding type declarations.": { + "category": "Error", + "code": 2307 + }, + "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity.": { + "category": "Error", + "code": 2308 + }, + "An export assignment cannot be used in a module with other exported elements.": { + "category": "Error", + "code": 2309 + }, + "Type '{0}' recursively references itself as a base type.": { + "category": "Error", + "code": 2310 + }, + "Cannot find name '{0}'. Did you mean to write this in an async function?": { + "category": "Error", + "code": 2311 + }, + "An interface can only extend an object type or intersection of object types with statically known members.": { + "category": "Error", + "code": 2312 + }, + "Type parameter '{0}' has a circular constraint.": { + "category": "Error", + "code": 2313 + }, + "Generic type '{0}' requires {1} type argument(s).": { + "category": "Error", + "code": 2314 + }, + "Type '{0}' is not generic.": { + "category": "Error", + "code": 2315 + }, + "Global type '{0}' must be a class or interface type.": { + "category": "Error", + "code": 2316 + }, + "Global type '{0}' must have {1} type parameter(s).": { + "category": "Error", + "code": 2317 + }, + "Cannot find global type '{0}'.": { + "category": "Error", + "code": 2318 + }, + "Named property '{0}' of types '{1}' and '{2}' are not identical.": { + "category": "Error", + "code": 2319 + }, + "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'.": { + "category": "Error", + "code": 2320 + }, + "Excessive stack depth comparing types '{0}' and '{1}'.": { + "category": "Error", + "code": 2321 + }, + "Type '{0}' is not assignable to type '{1}'.": { + "category": "Error", + "code": 2322 + }, + "Cannot redeclare exported variable '{0}'.": { + "category": "Error", + "code": 2323 + }, + "Property '{0}' is missing in type '{1}'.": { + "category": "Error", + "code": 2324 + }, + "Property '{0}' is private in type '{1}' but not in type '{2}'.": { + "category": "Error", + "code": 2325 + }, + "Types of property '{0}' are incompatible.": { + "category": "Error", + "code": 2326 + }, + "Property '{0}' is optional in type '{1}' but required in type '{2}'.": { + "category": "Error", + "code": 2327 + }, + "Types of parameters '{0}' and '{1}' are incompatible.": { + "category": "Error", + "code": 2328 + }, + "Index signature for type '{0}' is missing in type '{1}'.": { + "category": "Error", + "code": 2329 + }, + "'{0}' and '{1}' index signatures are incompatible.": { + "category": "Error", + "code": 2330 + }, + "'this' cannot be referenced in a module or namespace body.": { + "category": "Error", + "code": 2331 + }, + "'this' cannot be referenced in current location.": { + "category": "Error", + "code": 2332 + }, + "'this' cannot be referenced in a static property initializer.": { + "category": "Error", + "code": 2334 + }, + "'super' can only be referenced in a derived class.": { + "category": "Error", + "code": 2335 + }, + "'super' cannot be referenced in constructor arguments.": { + "category": "Error", + "code": 2336 + }, + "Super calls are not permitted outside constructors or in nested functions inside constructors.": { + "category": "Error", + "code": 2337 + }, + "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.": { + "category": "Error", + "code": 2338 + }, + "Property '{0}' does not exist on type '{1}'.": { + "category": "Error", + "code": 2339 + }, + "Only public and protected methods of the base class are accessible via the 'super' keyword.": { + "category": "Error", + "code": 2340 + }, + "Property '{0}' is private and only accessible within class '{1}'.": { + "category": "Error", + "code": 2341 + }, + "This syntax requires an imported helper named '{1}' which does not exist in '{0}'. Consider upgrading your version of '{0}'.": { + "category": "Error", + "code": 2343 + }, + "Type '{0}' does not satisfy the constraint '{1}'.": { + "category": "Error", + "code": 2344 + }, + "Argument of type '{0}' is not assignable to parameter of type '{1}'.": { + "category": "Error", + "code": 2345 + }, + "Call target does not contain any signatures.": { + "category": "Error", + "code": 2346 + }, + "Untyped function calls may not accept type arguments.": { + "category": "Error", + "code": 2347 + }, + "Value of type '{0}' is not callable. Did you mean to include 'new'?": { + "category": "Error", + "code": 2348 + }, + "This expression is not callable.": { + "category": "Error", + "code": 2349 + }, + "Only a void function can be called with the 'new' keyword.": { + "category": "Error", + "code": 2350 + }, + "This expression is not constructable.": { + "category": "Error", + "code": 2351 + }, + "Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.": { + "category": "Error", + "code": 2352 + }, + "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'.": { + "category": "Error", + "code": 2353 + }, + "This syntax requires an imported helper but module '{0}' cannot be found.": { + "category": "Error", + "code": 2354 + }, + "A function whose declared type is neither 'undefined', 'void', nor 'any' must return a value.": { + "category": "Error", + "code": 2355 + }, + "An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.": { + "category": "Error", + "code": 2356 + }, + "The operand of an increment or decrement operator must be a variable or a property access.": { + "category": "Error", + "code": 2357 + }, + "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter.": { + "category": "Error", + "code": 2358 + }, + "The right-hand side of an 'instanceof' expression must be either of type 'any', a class, function, or other type assignable to the 'Function' interface type, or an object type with a 'Symbol.hasInstance' method.": { + "category": "Error", + "code": 2359 + }, + "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": { + "category": "Error", + "code": 2362 + }, + "The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": { + "category": "Error", + "code": 2363 + }, + "The left-hand side of an assignment expression must be a variable or a property access.": { + "category": "Error", + "code": 2364 + }, + "Operator '{0}' cannot be applied to types '{1}' and '{2}'.": { + "category": "Error", + "code": 2365 + }, + "Function lacks ending return statement and return type does not include 'undefined'.": { + "category": "Error", + "code": 2366 + }, + "This comparison appears to be unintentional because the types '{0}' and '{1}' have no overlap.": { + "category": "Error", + "code": 2367 + }, + "Type parameter name cannot be '{0}'.": { + "category": "Error", + "code": 2368 + }, + "A parameter property is only allowed in a constructor implementation.": { + "category": "Error", + "code": 2369 + }, + "A rest parameter must be of an array type.": { + "category": "Error", + "code": 2370 + }, + "A parameter initializer is only allowed in a function or constructor implementation.": { + "category": "Error", + "code": 2371 + }, + "Parameter '{0}' cannot reference itself.": { + "category": "Error", + "code": 2372 + }, + "Parameter '{0}' cannot reference identifier '{1}' declared after it.": { + "category": "Error", + "code": 2373 + }, + "Duplicate index signature for type '{0}'.": { + "category": "Error", + "code": 2374 + }, + "Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.": { + "category": "Error", + "code": 2375 + }, + "A 'super' call must be the first statement in the constructor to refer to 'super' or 'this' when a derived class contains initialized properties, parameter properties, or private identifiers.": { + "category": "Error", + "code": 2376 + }, + "Constructors for derived classes must contain a 'super' call.": { + "category": "Error", + "code": 2377 + }, + "A 'get' accessor must return a value.": { + "category": "Error", + "code": 2378 + }, + "Argument of type '{0}' is not assignable to parameter of type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.": { + "category": "Error", + "code": 2379 + }, + "Overload signatures must all be exported or non-exported.": { + "category": "Error", + "code": 2383 + }, + "Overload signatures must all be ambient or non-ambient.": { + "category": "Error", + "code": 2384 + }, + "Overload signatures must all be public, private or protected.": { + "category": "Error", + "code": 2385 + }, + "Overload signatures must all be optional or required.": { + "category": "Error", + "code": 2386 + }, + "Function overload must be static.": { + "category": "Error", + "code": 2387 + }, + "Function overload must not be static.": { + "category": "Error", + "code": 2388 + }, + "Function implementation name must be '{0}'.": { + "category": "Error", + "code": 2389 + }, + "Constructor implementation is missing.": { + "category": "Error", + "code": 2390 + }, + "Function implementation is missing or not immediately following the declaration.": { + "category": "Error", + "code": 2391 + }, + "Multiple constructor implementations are not allowed.": { + "category": "Error", + "code": 2392 + }, + "Duplicate function implementation.": { + "category": "Error", + "code": 2393 + }, + "This overload signature is not compatible with its implementation signature.": { + "category": "Error", + "code": 2394 + }, + "Individual declarations in merged declaration '{0}' must be all exported or all local.": { + "category": "Error", + "code": 2395 + }, + "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters.": { + "category": "Error", + "code": 2396 + }, + "Declaration name conflicts with built-in global identifier '{0}'.": { + "category": "Error", + "code": 2397 + }, + "'constructor' cannot be used as a parameter property name.": { + "category": "Error", + "code": 2398 + }, + "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference.": { + "category": "Error", + "code": 2399 + }, + "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference.": { + "category": "Error", + "code": 2400 + }, + "A 'super' call must be a root-level statement within a constructor of a derived class that contains initialized properties, parameter properties, or private identifiers.": { + "category": "Error", + "code": 2401 + }, + "Expression resolves to '_super' that compiler uses to capture base class reference.": { + "category": "Error", + "code": 2402 + }, + "Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.": { + "category": "Error", + "code": 2403 + }, + "The left-hand side of a 'for...in' statement cannot use a type annotation.": { + "category": "Error", + "code": 2404 + }, + "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'.": { + "category": "Error", + "code": 2405 + }, + "The left-hand side of a 'for...in' statement must be a variable or a property access.": { + "category": "Error", + "code": 2406 + }, + "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter, but here has type '{0}'.": { + "category": "Error", + "code": 2407 + }, + "Setters cannot return a value.": { + "category": "Error", + "code": 2408 + }, + "Return type of constructor signature must be assignable to the instance type of the class.": { + "category": "Error", + "code": 2409 + }, + "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'.": { + "category": "Error", + "code": 2410 + }, + "Type '{0}' is not assignable to type '{1}' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.": { + "category": "Error", + "code": 2412 + }, + "Property '{0}' of type '{1}' is not assignable to '{2}' index type '{3}'.": { + "category": "Error", + "code": 2411 + }, + "'{0}' index type '{1}' is not assignable to '{2}' index type '{3}'.": { + "category": "Error", + "code": 2413 + }, + "Class name cannot be '{0}'.": { + "category": "Error", + "code": 2414 + }, + "Class '{0}' incorrectly extends base class '{1}'.": { + "category": "Error", + "code": 2415 + }, + "Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.": { + "category": "Error", + "code": 2416 + }, + "Class static side '{0}' incorrectly extends base class static side '{1}'.": { + "category": "Error", + "code": 2417 + }, + "Type of computed property's value is '{0}', which is not assignable to type '{1}'.": { + "category": "Error", + "code": 2418 + }, + "Types of construct signatures are incompatible.": { + "category": "Error", + "code": 2419 + }, + "Class '{0}' incorrectly implements interface '{1}'.": { + "category": "Error", + "code": 2420 + }, + "A class can only implement an object type or intersection of object types with statically known members.": { + "category": "Error", + "code": 2422 + }, + "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor.": { + "category": "Error", + "code": 2423 + }, + "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function.": { + "category": "Error", + "code": 2425 + }, + "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function.": { + "category": "Error", + "code": 2426 + }, + "Interface name cannot be '{0}'.": { + "category": "Error", + "code": 2427 + }, + "All declarations of '{0}' must have identical type parameters.": { + "category": "Error", + "code": 2428 + }, + "Interface '{0}' incorrectly extends interface '{1}'.": { + "category": "Error", + "code": 2430 + }, + "Enum name cannot be '{0}'.": { + "category": "Error", + "code": 2431 + }, + "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.": { + "category": "Error", + "code": 2432 + }, + "A namespace declaration cannot be in a different file from a class or function with which it is merged.": { + "category": "Error", + "code": 2433 + }, + "A namespace declaration cannot be located prior to a class or function with which it is merged.": { + "category": "Error", + "code": 2434 + }, + "Ambient modules cannot be nested in other modules or namespaces.": { + "category": "Error", + "code": 2435 + }, + "Ambient module declaration cannot specify relative module name.": { + "category": "Error", + "code": 2436 + }, + "Module '{0}' is hidden by a local declaration with the same name.": { + "category": "Error", + "code": 2437 + }, + "Import name cannot be '{0}'.": { + "category": "Error", + "code": 2438 + }, + "Import or export declaration in an ambient module declaration cannot reference module through relative module name.": { + "category": "Error", + "code": 2439 + }, + "Import declaration conflicts with local declaration of '{0}'.": { + "category": "Error", + "code": 2440 + }, + "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module.": { + "category": "Error", + "code": 2441 + }, + "Types have separate declarations of a private property '{0}'.": { + "category": "Error", + "code": 2442 + }, + "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'.": { + "category": "Error", + "code": 2443 + }, + "Property '{0}' is protected in type '{1}' but public in type '{2}'.": { + "category": "Error", + "code": 2444 + }, + "Property '{0}' is protected and only accessible within class '{1}' and its subclasses.": { + "category": "Error", + "code": 2445 + }, + "Property '{0}' is protected and only accessible through an instance of class '{1}'. This is an instance of class '{2}'.": { + "category": "Error", + "code": 2446 + }, + "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead.": { + "category": "Error", + "code": 2447 + }, + "Block-scoped variable '{0}' used before its declaration.": { + "category": "Error", + "code": 2448 + }, + "Class '{0}' used before its declaration.": { + "category": "Error", + "code": 2449 + }, + "Enum '{0}' used before its declaration.": { + "category": "Error", + "code": 2450 + }, + "Cannot redeclare block-scoped variable '{0}'.": { + "category": "Error", + "code": 2451 + }, + "An enum member cannot have a numeric name.": { + "category": "Error", + "code": 2452 + }, + "Variable '{0}' is used before being assigned.": { + "category": "Error", + "code": 2454 + }, + "Type alias '{0}' circularly references itself.": { + "category": "Error", + "code": 2456 + }, + "Type alias name cannot be '{0}'.": { + "category": "Error", + "code": 2457 + }, + "An AMD module cannot have multiple name assignments.": { + "category": "Error", + "code": 2458 + }, + "Module '{0}' declares '{1}' locally, but it is not exported.": { + "category": "Error", + "code": 2459 + }, + "Module '{0}' declares '{1}' locally, but it is exported as '{2}'.": { + "category": "Error", + "code": 2460 + }, + "Type '{0}' is not an array type.": { + "category": "Error", + "code": 2461 + }, + "A rest element must be last in a destructuring pattern.": { + "category": "Error", + "code": 2462 + }, + "A binding pattern parameter cannot be optional in an implementation signature.": { + "category": "Error", + "code": 2463 + }, + "A computed property name must be of type 'string', 'number', 'symbol', or 'any'.": { + "category": "Error", + "code": 2464 + }, + "'this' cannot be referenced in a computed property name.": { + "category": "Error", + "code": 2465 + }, + "'super' cannot be referenced in a computed property name.": { + "category": "Error", + "code": 2466 + }, + "A computed property name cannot reference a type parameter from its containing type.": { + "category": "Error", + "code": 2467 + }, + "Cannot find global value '{0}'.": { + "category": "Error", + "code": 2468 + }, + "The '{0}' operator cannot be applied to type 'symbol'.": { + "category": "Error", + "code": 2469 + }, + "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher.": { + "category": "Error", + "code": 2472 + }, + "Enum declarations must all be const or non-const.": { + "category": "Error", + "code": 2473 + }, + "const enum member initializers must be constant expressions.": { + "category": "Error", + "code": 2474 + }, + "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.": { + "category": "Error", + "code": 2475 + }, + "A const enum member can only be accessed using a string literal.": { + "category": "Error", + "code": 2476 + }, + "'const' enum member initializer was evaluated to a non-finite value.": { + "category": "Error", + "code": 2477 + }, + "'const' enum member initializer was evaluated to disallowed value 'NaN'.": { + "category": "Error", + "code": 2478 + }, + "'let' is not allowed to be used as a name in 'let' or 'const' declarations.": { + "category": "Error", + "code": 2480 + }, + "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": { + "category": "Error", + "code": 2481 + }, + "The left-hand side of a 'for...of' statement cannot use a type annotation.": { + "category": "Error", + "code": 2483 + }, + "Export declaration conflicts with exported declaration of '{0}'.": { + "category": "Error", + "code": 2484 + }, + "The left-hand side of a 'for...of' statement must be a variable or a property access.": { + "category": "Error", + "code": 2487 + }, + "Type '{0}' must have a '[Symbol.iterator]()' method that returns an iterator.": { + "category": "Error", + "code": 2488 + }, + "An iterator must have a 'next()' method.": { + "category": "Error", + "code": 2489 + }, + "The type returned by the '{0}()' method of an iterator must have a 'value' property.": { + "category": "Error", + "code": 2490 + }, + "The left-hand side of a 'for...in' statement cannot be a destructuring pattern.": { + "category": "Error", + "code": 2491 + }, + "Cannot redeclare identifier '{0}' in catch clause.": { + "category": "Error", + "code": 2492 + }, + "Tuple type '{0}' of length '{1}' has no element at index '{2}'.": { + "category": "Error", + "code": 2493 + }, + "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher.": { + "category": "Error", + "code": 2494 + }, + "Type '{0}' is not an array type or a string type.": { + "category": "Error", + "code": 2495 + }, + "The 'arguments' object cannot be referenced in an arrow function in ES5. Consider using a standard function expression.": { + "category": "Error", + "code": 2496 + }, + "This module can only be referenced with ECMAScript imports/exports by turning on the '{0}' flag and referencing its default export.": { + "category": "Error", + "code": 2497 + }, + "Module '{0}' uses 'export =' and cannot be used with 'export *'.": { + "category": "Error", + "code": 2498 + }, + "An interface can only extend an identifier/qualified-name with optional type arguments.": { + "category": "Error", + "code": 2499 + }, + "A class can only implement an identifier/qualified-name with optional type arguments.": { + "category": "Error", + "code": 2500 + }, + "A rest element cannot contain a binding pattern.": { + "category": "Error", + "code": 2501 + }, + "'{0}' is referenced directly or indirectly in its own type annotation.": { + "category": "Error", + "code": 2502 + }, + "Cannot find namespace '{0}'.": { + "category": "Error", + "code": 2503 + }, + "Type '{0}' must have a '[Symbol.asyncIterator]()' method that returns an async iterator.": { + "category": "Error", + "code": 2504 + }, + "A generator cannot have a 'void' type annotation.": { + "category": "Error", + "code": 2505 + }, + "'{0}' is referenced directly or indirectly in its own base expression.": { + "category": "Error", + "code": 2506 + }, + "Type '{0}' is not a constructor function type.": { + "category": "Error", + "code": 2507 + }, + "No base constructor has the specified number of type arguments.": { + "category": "Error", + "code": 2508 + }, + "Base constructor return type '{0}' is not an object type or intersection of object types with statically known members.": { + "category": "Error", + "code": 2509 + }, + "Base constructors must all have the same return type.": { + "category": "Error", + "code": 2510 + }, + "Cannot create an instance of an abstract class.": { + "category": "Error", + "code": 2511 + }, + "Overload signatures must all be abstract or non-abstract.": { + "category": "Error", + "code": 2512 + }, + "Abstract method '{0}' in class '{1}' cannot be accessed via super expression.": { + "category": "Error", + "code": 2513 + }, + "A tuple type cannot be indexed with a negative value.": { + "category": "Error", + "code": 2514 + }, + "Non-abstract class '{0}' does not implement inherited abstract member {1} from class '{2}'.": { + "category": "Error", + "code": 2515 + }, + "All declarations of an abstract method must be consecutive.": { + "category": "Error", + "code": 2516 + }, + "Cannot assign an abstract constructor type to a non-abstract constructor type.": { + "category": "Error", + "code": 2517 + }, + "A 'this'-based type guard is not compatible with a parameter-based type guard.": { + "category": "Error", + "code": 2518 + }, + "An async iterator must have a 'next()' method.": { + "category": "Error", + "code": 2519 + }, + "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": { + "category": "Error", + "code": 2520 + }, + "The 'arguments' object cannot be referenced in an async function or method in ES5. Consider using a standard function or method.": { + "category": "Error", + "code": 2522 + }, + "'yield' expressions cannot be used in a parameter initializer.": { + "category": "Error", + "code": 2523 + }, + "'await' expressions cannot be used in a parameter initializer.": { + "category": "Error", + "code": 2524 + }, + "A 'this' type is available only in a non-static member of a class or interface.": { + "category": "Error", + "code": 2526 + }, + "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.": { + "category": "Error", + "code": 2527 + }, + "A module cannot have multiple default exports.": { + "category": "Error", + "code": 2528 + }, + "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions.": { + "category": "Error", + "code": 2529 + }, + "Property '{0}' is incompatible with index signature.": { + "category": "Error", + "code": 2530 + }, + "Object is possibly 'null'.": { + "category": "Error", + "code": 2531 + }, + "Object is possibly 'undefined'.": { + "category": "Error", + "code": 2532 + }, + "Object is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 2533 + }, + "A function returning 'never' cannot have a reachable end point.": { + "category": "Error", + "code": 2534 + }, + "Type '{0}' cannot be used to index type '{1}'.": { + "category": "Error", + "code": 2536 + }, + "Type '{0}' has no matching index signature for type '{1}'.": { + "category": "Error", + "code": 2537 + }, + "Type '{0}' cannot be used as an index type.": { + "category": "Error", + "code": 2538 + }, + "Cannot assign to '{0}' because it is not a variable.": { + "category": "Error", + "code": 2539 + }, + "Cannot assign to '{0}' because it is a read-only property.": { + "category": "Error", + "code": 2540 + }, + "Index signature in type '{0}' only permits reading.": { + "category": "Error", + "code": 2542 + }, + "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference.": { + "category": "Error", + "code": 2543 + }, + "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference.": { + "category": "Error", + "code": 2544 + }, + "A mixin class must have a constructor with a single rest parameter of type 'any[]'.": { + "category": "Error", + "code": 2545 + }, + "The type returned by the '{0}()' method of an async iterator must be a promise for a type with a 'value' property.": { + "category": "Error", + "code": 2547 + }, + "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { + "category": "Error", + "code": 2548 + }, + "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": { + "category": "Error", + "code": 2549 + }, + "Property '{0}' does not exist on type '{1}'. Do you need to change your target library? Try changing the 'lib' compiler option to '{2}' or later.": { + "category": "Error", + "code": 2550 + }, + "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?": { + "category": "Error", + "code": 2551 + }, + "Cannot find name '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 2552 + }, + "Computed values are not permitted in an enum with string valued members.": { + "category": "Error", + "code": 2553 + }, + "Expected {0} arguments, but got {1}.": { + "category": "Error", + "code": 2554 + }, + "Expected at least {0} arguments, but got {1}.": { + "category": "Error", + "code": 2555 + }, + "A spread argument must either have a tuple type or be passed to a rest parameter.": { + "category": "Error", + "code": 2556 + }, + "Expected {0} type arguments, but got {1}.": { + "category": "Error", + "code": 2558 + }, + "Type '{0}' has no properties in common with type '{1}'.": { + "category": "Error", + "code": 2559 + }, + "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?": { + "category": "Error", + "code": 2560 + }, + "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?": { + "category": "Error", + "code": 2561 + }, + "Base class expressions cannot reference class type parameters.": { + "category": "Error", + "code": 2562 + }, + "The containing function or module body is too large for control flow analysis.": { + "category": "Error", + "code": 2563 + }, + "Property '{0}' has no initializer and is not definitely assigned in the constructor.": { + "category": "Error", + "code": 2564 + }, + "Property '{0}' is used before being assigned.": { + "category": "Error", + "code": 2565 + }, + "A rest element cannot have a property name.": { + "category": "Error", + "code": 2566 + }, + "Enum declarations can only merge with namespace or other enum declarations.": { + "category": "Error", + "code": 2567 + }, + "Property '{0}' may not exist on type '{1}'. Did you mean '{2}'?": { + "category": "Error", + "code": 2568 + }, + + "Could not find name '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 2570 + }, + "Object is of type 'unknown'.": { + "category": "Error", + "code": 2571 + }, + "A rest element type must be an array type.": { + "category": "Error", + "code": 2574 + }, + "No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments.": { + "category": "Error", + "code": 2575 + }, + "Property '{0}' does not exist on type '{1}'. Did you mean to access the static member '{2}' instead?": { + "category": "Error", + "code": 2576 + }, + "Return type annotation circularly references itself.": { + "category": "Error", + "code": 2577 + }, + "Unused '@ts-expect-error' directive.": { + "category": "Error", + "code": 2578 + }, + "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.": { + "category": "Error", + "code": 2580 + }, + "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery`.": { + "category": "Error", + "code": 2581 + }, + "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha`.": { + "category": "Error", + "code": 2582 + }, + "Cannot find name '{0}'. Do you need to change your target library? Try changing the 'lib' compiler option to '{1}' or later.": { + "category": "Error", + "code": 2583 + }, + "Cannot find name '{0}'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.": { + "category": "Error", + "code": 2584 + }, + "'{0}' only refers to a type, but is being used as a value here. Do you need to change your target library? Try changing the 'lib' compiler option to es2015 or later.": { + "category": "Error", + "code": 2585 + }, + "Cannot assign to '{0}' because it is a constant.": { + "category": "Error", + "code": 2588 + }, + "Type instantiation is excessively deep and possibly infinite.": { + "category": "Error", + "code": 2589 + }, + "Expression produces a union type that is too complex to represent.": { + "category": "Error", + "code": 2590 + }, + "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.": { + "category": "Error", + "code": 2591 + }, + "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig.": { + "category": "Error", + "code": 2592 + }, + "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig.": { + "category": "Error", + "code": 2593 + }, + "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag.": { + "category": "Error", + "code": 2594 + }, + "'{0}' can only be imported by using a default import.": { + "category": "Error", + "code": 2595 + }, + "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import.": { + "category": "Error", + "code": 2596 + }, + "'{0}' can only be imported by using a 'require' call or by using a default import.": { + "category": "Error", + "code": 2597 + }, + "'{0}' can only be imported by using a 'require' call or by turning on the 'esModuleInterop' flag and using a default import.": { + "category": "Error", + "code": 2598 + }, + "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.": { + "category": "Error", + "code": 2602 + }, + "Property '{0}' in type '{1}' is not assignable to type '{2}'.": { + "category": "Error", + "code": 2603 + }, + "JSX element type '{0}' does not have any construct or call signatures.": { + "category": "Error", + "code": 2604 + }, + "Property '{0}' of JSX spread attribute is not assignable to target property.": { + "category": "Error", + "code": 2606 + }, + "JSX element class does not support attributes because it does not have a '{0}' property.": { + "category": "Error", + "code": 2607 + }, + "The global type 'JSX.{0}' may not have more than one property.": { + "category": "Error", + "code": 2608 + }, + "JSX spread child must be an array type.": { + "category": "Error", + "code": 2609 + }, + "'{0}' is defined as an accessor in class '{1}', but is overridden here in '{2}' as an instance property.": { + "category": "Error", + "code": 2610 + }, + "'{0}' is defined as a property in class '{1}', but is overridden here in '{2}' as an accessor.": { + "category": "Error", + "code": 2611 + }, + "Property '{0}' will overwrite the base property in '{1}'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration.": { + "category": "Error", + "code": 2612 + }, + "Module '{0}' has no default export. Did you mean to use 'import { {1} } from {0}' instead?": { + "category": "Error", + "code": 2613 + }, + "Module '{0}' has no exported member '{1}'. Did you mean to use 'import {1} from {0}' instead?": { + "category": "Error", + "code": 2614 + }, + "Type of property '{0}' circularly references itself in mapped type '{1}'.": { + "category": "Error", + "code": 2615 + }, + "'{0}' can only be imported by using 'import {1} = require({2})' or a default import.": { + "category": "Error", + "code": 2616 + }, + "'{0}' can only be imported by using 'import {1} = require({2})' or by turning on the 'esModuleInterop' flag and using a default import.": { + "category": "Error", + "code": 2617 + }, + "Source has {0} element(s) but target requires {1}.": { + "category": "Error", + "code": 2618 + }, + "Source has {0} element(s) but target allows only {1}.": { + "category": "Error", + "code": 2619 + }, + "Target requires {0} element(s) but source may have fewer.": { + "category": "Error", + "code": 2620 + }, + "Target allows only {0} element(s) but source may have more.": { + "category": "Error", + "code": 2621 + }, + "Source provides no match for required element at position {0} in target.": { + "category": "Error", + "code": 2623 + }, + "Source provides no match for variadic element at position {0} in target.": { + "category": "Error", + "code": 2624 + }, + "Variadic element at position {0} in source does not match element at position {1} in target.": { + "category": "Error", + "code": 2625 + }, + "Type at position {0} in source is not compatible with type at position {1} in target.": { + "category": "Error", + "code": 2626 + }, + "Type at positions {0} through {1} in source is not compatible with type at position {2} in target.": { + "category": "Error", + "code": 2627 + }, + "Cannot assign to '{0}' because it is an enum.": { + "category": "Error", + "code": 2628 + }, + "Cannot assign to '{0}' because it is a class.": { + "category": "Error", + "code": 2629 + }, + "Cannot assign to '{0}' because it is a function.": { + "category": "Error", + "code": 2630 + }, + "Cannot assign to '{0}' because it is a namespace.": { + "category": "Error", + "code": 2631 + }, + "Cannot assign to '{0}' because it is an import.": { + "category": "Error", + "code": 2632 + }, + "JSX property access expressions cannot include JSX namespace names": { + "category": "Error", + "code": 2633 + }, + "'{0}' index signatures are incompatible.": { + "category": "Error", + "code": 2634 + }, + "Type '{0}' has no signatures for which the type argument list is applicable.": { + "category": "Error", + "code": 2635 + }, + "Type '{0}' is not assignable to type '{1}' as implied by variance annotation.": { + "category": "Error", + "code": 2636 + }, + "Variance annotations are only supported in type aliases for object, function, constructor, and mapped types.": { + "category": "Error", + "code": 2637 + }, + "Type '{0}' may represent a primitive value, which is not permitted as the right operand of the 'in' operator.": { + "category": "Error", + "code": 2638 + }, + "React components cannot include JSX namespace names": { + "category": "Error", + "code": 2639 + }, + + "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { + "category": "Error", + "code": 2649 + }, + "Non-abstract class expression is missing implementations for the following members of '{0}': {1} and {2} more.": { + "category": "Error", + "code": 2650 + }, + "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.": { + "category": "Error", + "code": 2651 + }, + "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": { + "category": "Error", + "code": 2652 + }, + "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'.": { + "category": "Error", + "code": 2653 + }, + "Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2}.": { + "category": "Error", + "code": 2654 + }, + "Non-abstract class '{0}' is missing implementations for the following members of '{1}': {2} and {3} more.": { + "category": "Error", + "code": 2655 + }, + "Non-abstract class expression is missing implementations for the following members of '{0}': {1}.": { + "category": "Error", + "code": 2656 + }, + "JSX expressions must have one parent element.": { + "category": "Error", + "code": 2657 + }, + "Type '{0}' provides no match for the signature '{1}'.": { + "category": "Error", + "code": 2658 + }, + "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher.": { + "category": "Error", + "code": 2659 + }, + "'super' can only be referenced in members of derived classes or object literal expressions.": { + "category": "Error", + "code": 2660 + }, + "Cannot export '{0}'. Only local declarations can be exported from a module.": { + "category": "Error", + "code": 2661 + }, + "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?": { + "category": "Error", + "code": 2662 + }, + "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?": { + "category": "Error", + "code": 2663 + }, + "Invalid module name in augmentation, module '{0}' cannot be found.": { + "category": "Error", + "code": 2664 + }, + "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented.": { + "category": "Error", + "code": 2665 + }, + "Exports and export assignments are not permitted in module augmentations.": { + "category": "Error", + "code": 2666 + }, + "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module.": { + "category": "Error", + "code": 2667 + }, + "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible.": { + "category": "Error", + "code": 2668 + }, + "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.": { + "category": "Error", + "code": 2669 + }, + "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.": { + "category": "Error", + "code": 2670 + }, + "Cannot augment module '{0}' because it resolves to a non-module entity.": { + "category": "Error", + "code": 2671 + }, + "Cannot assign a '{0}' constructor type to a '{1}' constructor type.": { + "category": "Error", + "code": 2672 + }, + "Constructor of class '{0}' is private and only accessible within the class declaration.": { + "category": "Error", + "code": 2673 + }, + "Constructor of class '{0}' is protected and only accessible within the class declaration.": { + "category": "Error", + "code": 2674 + }, + "Cannot extend a class '{0}'. Class constructor is marked as private.": { + "category": "Error", + "code": 2675 + }, + "Accessors must both be abstract or non-abstract.": { + "category": "Error", + "code": 2676 + }, + "A type predicate's type must be assignable to its parameter's type.": { + "category": "Error", + "code": 2677 + }, + "Type '{0}' is not comparable to type '{1}'.": { + "category": "Error", + "code": 2678 + }, + "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'.": { + "category": "Error", + "code": 2679 + }, + "A '{0}' parameter must be the first parameter.": { + "category": "Error", + "code": 2680 + }, + "A constructor cannot have a 'this' parameter.": { + "category": "Error", + "code": 2681 + }, + "'this' implicitly has type 'any' because it does not have a type annotation.": { + "category": "Error", + "code": 2683 + }, + "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'.": { + "category": "Error", + "code": 2684 + }, + "The 'this' types of each signature are incompatible.": { + "category": "Error", + "code": 2685 + }, + "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead.": { + "category": "Error", + "code": 2686 + }, + "All declarations of '{0}' must have identical modifiers.": { + "category": "Error", + "code": 2687 + }, + "Cannot find type definition file for '{0}'.": { + "category": "Error", + "code": 2688 + }, + "Cannot extend an interface '{0}'. Did you mean 'implements'?": { + "category": "Error", + "code": 2689 + }, + "'{0}' only refers to a type, but is being used as a value here. Did you mean to use '{1} in {0}'?": { + "category": "Error", + "code": 2690 + }, + "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible.": { + "category": "Error", + "code": 2692 + }, + "'{0}' only refers to a type, but is being used as a value here.": { + "category": "Error", + "code": 2693 + }, + "Namespace '{0}' has no exported member '{1}'.": { + "category": "Error", + "code": 2694 + }, + "Left side of comma operator is unused and has no side effects.": { + "category": "Error", + "code": 2695, + "reportsUnnecessary": true + }, + "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?": { + "category": "Error", + "code": 2696 + }, + "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your '--lib' option.": { + "category": "Error", + "code": 2697 + }, + "Spread types may only be created from object types.": { + "category": "Error", + "code": 2698 + }, + "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'.": { + "category": "Error", + "code": 2699 + }, + "Rest types may only be created from object types.": { + "category": "Error", + "code": 2700 + }, + "The target of an object rest assignment must be a variable or a property access.": { + "category": "Error", + "code": 2701 + }, + "'{0}' only refers to a type, but is being used as a namespace here.": { + "category": "Error", + "code": 2702 + }, + "The operand of a 'delete' operator must be a property reference.": { + "category": "Error", + "code": 2703 + }, + "The operand of a 'delete' operator cannot be a read-only property.": { + "category": "Error", + "code": 2704 + }, + "An async function or method in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.": { + "category": "Error", + "code": 2705 + }, + "Required type parameters may not follow optional type parameters.": { + "category": "Error", + "code": 2706 + }, + "Generic type '{0}' requires between {1} and {2} type arguments.": { + "category": "Error", + "code": 2707 + }, + "Cannot use namespace '{0}' as a value.": { + "category": "Error", + "code": 2708 + }, + "Cannot use namespace '{0}' as a type.": { + "category": "Error", + "code": 2709 + }, + "'{0}' are specified twice. The attribute named '{0}' will be overwritten.": { + "category": "Error", + "code": 2710 + }, + "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your '--lib' option.": { + "category": "Error", + "code": 2711 + }, + "A dynamic import call in ES5 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your '--lib' option.": { + "category": "Error", + "code": 2712 + }, + "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?": { + "category": "Error", + "code": 2713 + }, + "The expression of an export assignment must be an identifier or qualified name in an ambient context.": { + "category": "Error", + "code": 2714 + }, + "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.": { + "category": "Error", + "code": 2715 + }, + "Type parameter '{0}' has a circular default.": { + "category": "Error", + "code": 2716 + }, + "Subsequent property declarations must have the same type. Property '{0}' must be of type '{1}', but here has type '{2}'.": { + "category": "Error", + "code": 2717 + }, + "Duplicate property '{0}'.": { + "category": "Error", + "code": 2718 + }, + "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated.": { + "category": "Error", + "code": 2719 + }, + "Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?": { + "category": "Error", + "code": 2720 + }, + "Cannot invoke an object which is possibly 'null'.": { + "category": "Error", + "code": 2721 + }, + "Cannot invoke an object which is possibly 'undefined'.": { + "category": "Error", + "code": 2722 + }, + "Cannot invoke an object which is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 2723 + }, + "'{0}' has no exported member named '{1}'. Did you mean '{2}'?": { + "category": "Error", + "code": 2724 + }, + "Class name cannot be 'Object' when targeting ES5 and above with module {0}.": { + "category": "Error", + "code": 2725 + }, + "Cannot find lib definition for '{0}'.": { + "category": "Error", + "code": 2726 + }, + "Cannot find lib definition for '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 2727 + }, + "'{0}' is declared here.": { + "category": "Message", + "code": 2728 + }, + "Property '{0}' is used before its initialization.": { + "category": "Error", + "code": 2729 + }, + "An arrow function cannot have a 'this' parameter.": { + "category": "Error", + "code": 2730 + }, + "Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.": { + "category": "Error", + "code": 2731 + }, + "Cannot find module '{0}'. Consider using '--resolveJsonModule' to import module with '.json' extension.": { + "category": "Error", + "code": 2732 + }, + "Property '{0}' was also declared here.": { + "category": "Error", + "code": 2733 + }, + "Are you missing a semicolon?": { + "category": "Error", + "code": 2734 + }, + "Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?": { + "category": "Error", + "code": 2735 + }, + "Operator '{0}' cannot be applied to type '{1}'.": { + "category": "Error", + "code": 2736 + }, + "BigInt literals are not available when targeting lower than ES2020.": { + "category": "Error", + "code": 2737 + }, + "An outer value of 'this' is shadowed by this container.": { + "category": "Message", + "code": 2738 + }, + "Type '{0}' is missing the following properties from type '{1}': {2}": { + "category": "Error", + "code": 2739 + }, + "Type '{0}' is missing the following properties from type '{1}': {2}, and {3} more.": { + "category": "Error", + "code": 2740 + }, + "Property '{0}' is missing in type '{1}' but required in type '{2}'.": { + "category": "Error", + "code": 2741 + }, + "The inferred type of '{0}' cannot be named without a reference to '{1}'. This is likely not portable. A type annotation is necessary.": { + "category": "Error", + "code": 2742 + }, + "No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments.": { + "category": "Error", + "code": 2743 + }, + "Type parameter defaults can only reference previously declared type parameters.": { + "category": "Error", + "code": 2744 + }, + "This JSX tag's '{0}' prop expects type '{1}' which requires multiple children, but only a single child was provided.": { + "category": "Error", + "code": 2745 + }, + "This JSX tag's '{0}' prop expects a single child of type '{1}', but multiple children were provided.": { + "category": "Error", + "code": 2746 + }, + "'{0}' components don't accept text as child elements. Text in JSX has the type 'string', but the expected type of '{1}' is '{2}'.": { + "category": "Error", + "code": 2747 + }, + "Cannot access ambient const enums when '{0}' is enabled.": { + "category": "Error", + "code": 2748 + }, + "'{0}' refers to a value, but is being used as a type here. Did you mean 'typeof {0}'?": { + "category": "Error", + "code": 2749 + }, + "The implementation signature is declared here.": { + "category": "Error", + "code": 2750 + }, + "Circularity originates in type at this location.": { + "category": "Error", + "code": 2751 + }, + "The first export default is here.": { + "category": "Error", + "code": 2752 + }, + "Another export default is here.": { + "category": "Error", + "code": 2753 + }, + "'super' may not use type arguments.": { + "category": "Error", + "code": 2754 + }, + "No constituent of type '{0}' is callable.": { + "category": "Error", + "code": 2755 + }, + "Not all constituents of type '{0}' are callable.": { + "category": "Error", + "code": 2756 + }, + "Type '{0}' has no call signatures.": { + "category": "Error", + "code": 2757 + }, + "Each member of the union type '{0}' has signatures, but none of those signatures are compatible with each other.": { + "category": "Error", + "code": 2758 + }, + "No constituent of type '{0}' is constructable.": { + "category": "Error", + "code": 2759 + }, + "Not all constituents of type '{0}' are constructable.": { + "category": "Error", + "code": 2760 + }, + "Type '{0}' has no construct signatures.": { + "category": "Error", + "code": 2761 + }, + "Each member of the union type '{0}' has construct signatures, but none of those signatures are compatible with each other.": { + "category": "Error", + "code": 2762 + }, + "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but for-of will always send '{0}'.": { + "category": "Error", + "code": 2763 + }, + "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array spread will always send '{0}'.": { + "category": "Error", + "code": 2764 + }, + "Cannot iterate value because the 'next' method of its iterator expects type '{1}', but array destructuring will always send '{0}'.": { + "category": "Error", + "code": 2765 + }, + "Cannot delegate iteration to value because the 'next' method of its iterator expects type '{1}', but the containing generator will always send '{0}'.": { + "category": "Error", + "code": 2766 + }, + "The '{0}' property of an iterator must be a method.": { + "category": "Error", + "code": 2767 + }, + "The '{0}' property of an async iterator must be a method.": { + "category": "Error", + "code": 2768 + }, + "No overload matches this call.": { + "category": "Error", + "code": 2769 + }, + "The last overload gave the following error.": { + "category": "Error", + "code": 2770 + }, + "The last overload is declared here.": { + "category": "Error", + "code": 2771 + }, + "Overload {0} of {1}, '{2}', gave the following error.": { + "category": "Error", + "code": 2772 + }, + "Did you forget to use 'await'?": { + "category": "Error", + "code": 2773 + }, + "This condition will always return true since this function is always defined. Did you mean to call it instead?": { + "category": "Error", + "code": 2774 + }, + "Assertions require every name in the call target to be declared with an explicit type annotation.": { + "category": "Error", + "code": 2775 + }, + "Assertions require the call target to be an identifier or qualified name.": { + "category": "Error", + "code": 2776 + }, + "The operand of an increment or decrement operator may not be an optional property access.": { + "category": "Error", + "code": 2777 + }, + "The target of an object rest assignment may not be an optional property access.": { + "category": "Error", + "code": 2778 + }, + "The left-hand side of an assignment expression may not be an optional property access.": { + "category": "Error", + "code": 2779 + }, + "The left-hand side of a 'for...in' statement may not be an optional property access.": { + "category": "Error", + "code": 2780 + }, + "The left-hand side of a 'for...of' statement may not be an optional property access.": { + "category": "Error", + "code": 2781 + }, + "'{0}' needs an explicit type annotation.": { + "category": "Message", + "code": 2782 + }, + "'{0}' is specified more than once, so this usage will be overwritten.": { + "category": "Error", + "code": 2783 + }, + "'get' and 'set' accessors cannot declare 'this' parameters.": { + "category": "Error", + "code": 2784 + }, + "This spread always overwrites this property.": { + "category": "Error", + "code": 2785 + }, + "'{0}' cannot be used as a JSX component.": { + "category": "Error", + "code": 2786 + }, + "Its return type '{0}' is not a valid JSX element.": { + "category": "Error", + "code": 2787 + }, + "Its instance type '{0}' is not a valid JSX element.": { + "category": "Error", + "code": 2788 + }, + "Its element type '{0}' is not a valid JSX element.": { + "category": "Error", + "code": 2789 + }, + "The operand of a 'delete' operator must be optional.": { + "category": "Error", + "code": 2790 + }, + "Exponentiation cannot be performed on 'bigint' values unless the 'target' option is set to 'es2016' or later.": { + "category": "Error", + "code": 2791 + }, + "Cannot find module '{0}'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?": { + "category": "Error", + "code": 2792 + }, + "The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.": { + "category": "Error", + "code": 2793 + }, + "Expected {0} arguments, but got {1}. Did you forget to include 'void' in your type argument to 'Promise'?": { + "category": "Error", + "code": 2794 + }, + "The 'intrinsic' keyword can only be used to declare compiler provided intrinsic types.": { + "category": "Error", + "code": 2795 + }, + "It is likely that you are missing a comma to separate these two template expressions. They form a tagged template expression which cannot be invoked.": { + "category": "Error", + "code": 2796 + }, + "A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'.": { + "category": "Error", + "code": 2797 + }, + "The declaration was marked as deprecated here.": { + "category": "Error", + "code": 2798 + }, + "Type produces a tuple type that is too large to represent.": { + "category": "Error", + "code": 2799 + }, + "Expression produces a tuple type that is too large to represent.": { + "category": "Error", + "code": 2800 + }, + "This condition will always return true since this '{0}' is always defined.": { + "category": "Error", + "code": 2801 + }, + "Type '{0}' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.": { + "category": "Error", + "code": 2802 + }, + "Cannot assign to private method '{0}'. Private methods are not writable.": { + "category": "Error", + "code": 2803 + }, + "Duplicate identifier '{0}'. Static and instance elements cannot share the same private name.": { + "category": "Error", + "code": 2804 + }, + "Private accessor was defined without a getter.": { + "category": "Error", + "code": 2806 + }, + "This syntax requires an imported helper named '{1}' with {2} parameters, which is not compatible with the one in '{0}'. Consider upgrading your version of '{0}'.": { + "category": "Error", + "code": 2807 + }, + "A get accessor must be at least as accessible as the setter": { + "category": "Error", + "code": 2808 + }, + "Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the whole assignment in parentheses.": { + "category": "Error", + "code": 2809 + }, + "Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.": { + "category": "Error", + "code": 2810 + }, + "Initializer for property '{0}'": { + "category": "Error", + "code": 2811 + }, + "Property '{0}' does not exist on type '{1}'. Try changing the 'lib' compiler option to include 'dom'.": { + "category": "Error", + "code": 2812 + }, + "Class declaration cannot implement overload list for '{0}'.": { + "category": "Error", + "code": 2813 + }, + "Function with bodies can only merge with classes that are ambient.": { + "category": "Error", + "code": 2814 + }, + "'arguments' cannot be referenced in property initializers or class static initialization blocks.": { + "category": "Error", + "code": 2815 + }, + "Cannot use 'this' in a static property initializer of a decorated class.": { + "category": "Error", + "code": 2816 + }, + "Property '{0}' has no initializer and is not definitely assigned in a class static block.": { + "category": "Error", + "code": 2817 + }, + "Duplicate identifier '{0}'. Compiler reserves name '{1}' when emitting 'super' references in static initializers.": { + "category": "Error", + "code": 2818 + }, + "Namespace name cannot be '{0}'.": { + "category": "Error", + "code": 2819 + }, + "Type '{0}' is not assignable to type '{1}'. Did you mean '{2}'?": { + "category": "Error", + "code": 2820 + }, + "Import assertions are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'.": { + "category": "Error", + "code": 2821 + }, + "Import assertions cannot be used with type-only imports or exports.": { + "category": "Error", + "code": 2822 + }, + "Import attributes are only supported when the '--module' option is set to 'esnext', 'node18', 'node20', 'nodenext', or 'preserve'.": { + "category": "Error", + "code": 2823 + }, + "Cannot find namespace '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 2833 + }, + "Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path.": { + "category": "Error", + "code": 2834 + }, + "Relative import paths need explicit file extensions in ECMAScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '{0}'?": { + "category": "Error", + "code": 2835 + }, + "Import assertions are not allowed on statements that compile to CommonJS 'require' calls.": { + "category": "Error", + "code": 2836 + }, + "Import assertion values must be string literal expressions.": { + "category": "Error", + "code": 2837 + }, + "All declarations of '{0}' must have identical constraints.": { + "category": "Error", + "code": 2838 + }, + "This condition will always return '{0}' since JavaScript compares objects by reference, not value.": { + "category": "Error", + "code": 2839 + }, + "An interface cannot extend a primitive type like '{0}'. It can only extend other named object types.": { + "category": "Error", + "code": 2840 + }, + "'{0}' is an unused renaming of '{1}'. Did you intend to use it as a type annotation?": { + "category": "Error", + "code": 2842 + }, + "We can only write a type for '{0}' by adding a type for the entire parameter here.": { + "category": "Error", + "code": 2843 + }, + "Type of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor.": { + "category": "Error", + "code": 2844 + }, + "This condition will always return '{0}'.": { + "category": "Error", + "code": 2845 + }, + "A declaration file cannot be imported without 'import type'. Did you mean to import an implementation file '{0}' instead?": { + "category": "Error", + "code": 2846 + }, + "The right-hand side of an 'instanceof' expression must not be an instantiation expression.": { + "category": "Error", + "code": 2848 + }, + "Target signature provides too few arguments. Expected {0} or more, but got {1}.": { + "category": "Error", + "code": 2849 + }, + "The initializer of a 'using' declaration must be either an object with a '[Symbol.dispose]()' method, or be 'null' or 'undefined'.": { + "category": "Error", + "code": 2850 + }, + "The initializer of an 'await using' declaration must be either an object with a '[Symbol.asyncDispose]()' or '[Symbol.dispose]()' method, or be 'null' or 'undefined'.": { + "category": "Error", + "code": 2851 + }, + "'await using' statements are only allowed within async functions and at the top levels of modules.": { + "category": "Error", + "code": 2852 + }, + "'await using' statements are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": { + "category": "Error", + "code": 2853 + }, + "Top-level 'await using' statements are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.": { + "category": "Error", + "code": 2854 + }, + "Class field '{0}' defined by the parent class is not accessible in the child class via super.": { + "category": "Error", + "code": 2855 + }, + "Import attributes are not allowed on statements that compile to CommonJS 'require' calls.": { + "category": "Error", + "code": 2856 + }, + "Import attributes cannot be used with type-only imports or exports.": { + "category": "Error", + "code": 2857 + }, + "Import attribute values must be string literal expressions.": { + "category": "Error", + "code": 2858 + }, + "Excessive complexity comparing types '{0}' and '{1}'.": { + "category": "Error", + "code": 2859 + }, + "The left-hand side of an 'instanceof' expression must be assignable to the first argument of the right-hand side's '[Symbol.hasInstance]' method.": { + "category": "Error", + "code": 2860 + }, + "An object's '[Symbol.hasInstance]' method must return a boolean value for it to be used on the right-hand side of an 'instanceof' expression.": { + "category": "Error", + "code": 2861 + }, + "Type '{0}' is generic and can only be indexed for reading.": { + "category": "Error", + "code": 2862 + }, + "A class cannot extend a primitive type like '{0}'. Classes can only extend constructable values.": { + "category": "Error", + "code": 2863 + }, + "A class cannot implement a primitive type like '{0}'. It can only implement other named object types.": { + "category": "Error", + "code": 2864 + }, + "Import '{0}' conflicts with local value, so must be declared with a type-only import when 'isolatedModules' is enabled.": { + "category": "Error", + "code": 2865 + }, + "Import '{0}' conflicts with global value used in this file, so must be declared with a type-only import when 'isolatedModules' is enabled.": { + "category": "Error", + "code": 2866 + }, + "Cannot find name '{0}'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun`.": { + "category": "Error", + "code": 2867 + }, + "Cannot find name '{0}'. Do you need to install type definitions for Bun? Try `npm i --save-dev @types/bun` and then add 'bun' to the types field in your tsconfig.": { + "category": "Error", + "code": 2868 + }, + "Right operand of ?? is unreachable because the left operand is never nullish.": { + "category": "Error", + "code": 2869 + }, + "This binary expression is never nullish. Are you missing parentheses?": { + "category": "Error", + "code": 2870 + }, + "This expression is always nullish.": { + "category": "Error", + "code": 2871 + }, + "This kind of expression is always truthy.": { + "category": "Error", + "code": 2872 + }, + "This kind of expression is always falsy.": { + "category": "Error", + "code": 2873 + }, + "This JSX tag requires '{0}' to be in scope, but it could not be found.": { + "category": "Error", + "code": 2874 + }, + "This JSX tag requires the module path '{0}' to exist, but none could be found. Make sure you have types for the appropriate package installed.": { + "category": "Error", + "code": 2875 + }, + "This relative import path is unsafe to rewrite because it looks like a file name, but actually resolves to \"{0}\".": { + "category": "Error", + "code": 2876 + }, + "This import uses a '{0}' extension to resolve to an input TypeScript file, but will not be rewritten during emit because it is not a relative path.": { + "category": "Error", + "code": 2877 + }, + "This import path is unsafe to rewrite because it resolves to another project, and the relative path between the projects' output files is not the same as the relative path between its input files.": { + "category": "Error", + "code": 2878 + }, + "Using JSX fragments requires fragment factory '{0}' to be in scope, but it could not be found.": { + "category": "Error", + "code": 2879 + }, + "Import assertions have been replaced by import attributes. Use 'with' instead of 'assert'.": { + "category": "Error", + "code": 2880 + }, + "This expression is never nullish.": { + "category": "Error", + "code": 2881 + }, + "Cannot find module or type declarations for side-effect import of '{0}'.": { + "category": "Error", + "code": 2882 + }, + "The inferred type of '{0}' cannot be named without a reference to '{2}' from '{1}'. This is likely not portable. A type annotation is necessary.": { + "category": "Error", + "code": 2883 + }, + + "Import declaration '{0}' is using private name '{1}'.": { + "category": "Error", + "code": 4000 + }, + "Type parameter '{0}' of exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4002 + }, + "Type parameter '{0}' of exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4004 + }, + "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4006 + }, + "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4008 + }, + "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4010 + }, + "Type parameter '{0}' of public method from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4012 + }, + "Type parameter '{0}' of method from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4014 + }, + "Type parameter '{0}' of exported function has or is using private name '{1}'.": { + "category": "Error", + "code": 4016 + }, + "Implements clause of exported class '{0}' has or is using private name '{1}'.": { + "category": "Error", + "code": 4019 + }, + "'extends' clause of exported class '{0}' has or is using private name '{1}'.": { + "category": "Error", + "code": 4020 + }, + "'extends' clause of exported class has or is using private name '{0}'.": { + "category": "Error", + "code": 4021 + }, + "'extends' clause of exported interface '{0}' has or is using private name '{1}'.": { + "category": "Error", + "code": 4022 + }, + "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4023 + }, + "Exported variable '{0}' has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4024 + }, + "Exported variable '{0}' has or is using private name '{1}'.": { + "category": "Error", + "code": 4025 + }, + "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4026 + }, + "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4027 + }, + "Public static property '{0}' of exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4028 + }, + "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4029 + }, + "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4030 + }, + "Public property '{0}' of exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4031 + }, + "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4032 + }, + "Property '{0}' of exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4033 + }, + "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4034 + }, + "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4035 + }, + "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4036 + }, + "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4037 + }, + "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4038 + }, + "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4039 + }, + "Return type of public static getter '{0}' from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4040 + }, + "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4041 + }, + "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4042 + }, + "Return type of public getter '{0}' from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4043 + }, + "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4044 + }, + "Return type of constructor signature from exported interface has or is using private name '{0}'.": { + "category": "Error", + "code": 4045 + }, + "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4046 + }, + "Return type of call signature from exported interface has or is using private name '{0}'.": { + "category": "Error", + "code": 4047 + }, + "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4048 + }, + "Return type of index signature from exported interface has or is using private name '{0}'.": { + "category": "Error", + "code": 4049 + }, + "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named.": { + "category": "Error", + "code": 4050 + }, + "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4051 + }, + "Return type of public static method from exported class has or is using private name '{0}'.": { + "category": "Error", + "code": 4052 + }, + "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named.": { + "category": "Error", + "code": 4053 + }, + "Return type of public method from exported class has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4054 + }, + "Return type of public method from exported class has or is using private name '{0}'.": { + "category": "Error", + "code": 4055 + }, + "Return type of method from exported interface has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4056 + }, + "Return type of method from exported interface has or is using private name '{0}'.": { + "category": "Error", + "code": 4057 + }, + "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named.": { + "category": "Error", + "code": 4058 + }, + "Return type of exported function has or is using name '{0}' from private module '{1}'.": { + "category": "Error", + "code": 4059 + }, + "Return type of exported function has or is using private name '{0}'.": { + "category": "Error", + "code": 4060 + }, + "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4061 + }, + "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4062 + }, + "Parameter '{0}' of constructor from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4063 + }, + "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4064 + }, + "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4065 + }, + "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4066 + }, + "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4067 + }, + "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4068 + }, + "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4069 + }, + "Parameter '{0}' of public static method from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4070 + }, + "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4071 + }, + "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4072 + }, + "Parameter '{0}' of public method from exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4073 + }, + "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4074 + }, + "Parameter '{0}' of method from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4075 + }, + "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4076 + }, + "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4077 + }, + "Parameter '{0}' of exported function has or is using private name '{1}'.": { + "category": "Error", + "code": 4078 + }, + "Exported type alias '{0}' has or is using private name '{1}'.": { + "category": "Error", + "code": 4081 + }, + "Default export of the module has or is using private name '{0}'.": { + "category": "Error", + "code": 4082 + }, + "Type parameter '{0}' of exported type alias has or is using private name '{1}'.": { + "category": "Error", + "code": 4083 + }, + "Exported type alias '{0}' has or is using private name '{1}' from module {2}.": { + "category": "Error", + "code": 4084 + }, + "Extends clause for inferred type '{0}' has or is using private name '{1}'.": { + "category": "Error", + "code": 4085 + }, + "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4091 + }, + "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4092 + }, + "Property '{0}' of exported anonymous class type may not be private or protected.": { + "category": "Error", + "code": 4094 + }, + "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4095 + }, + "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4096 + }, + "Public static method '{0}' of exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4097 + }, + "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named.": { + "category": "Error", + "code": 4098 + }, + "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4099 + }, + "Public method '{0}' of exported class has or is using private name '{1}'.": { + "category": "Error", + "code": 4100 + }, + "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4101 + }, + "Method '{0}' of exported interface has or is using private name '{1}'.": { + "category": "Error", + "code": 4102 + }, + "Type parameter '{0}' of exported mapped object type is using private name '{1}'.": { + "category": "Error", + "code": 4103 + }, + "The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'.": { + "category": "Error", + "code": 4104 + }, + "Private or protected member '{0}' cannot be accessed on a type parameter.": { + "category": "Error", + "code": 4105 + }, + "Parameter '{0}' of accessor has or is using private name '{1}'.": { + "category": "Error", + "code": 4106 + }, + "Parameter '{0}' of accessor has or is using name '{1}' from private module '{2}'.": { + "category": "Error", + "code": 4107 + }, + "Parameter '{0}' of accessor has or is using name '{1}' from external module '{2}' but cannot be named.": { + "category": "Error", + "code": 4108 + }, + "Type arguments for '{0}' circularly reference themselves.": { + "category": "Error", + "code": 4109 + }, + "Tuple type arguments circularly reference themselves.": { + "category": "Error", + "code": 4110 + }, + "Property '{0}' comes from an index signature, so it must be accessed with ['{0}'].": { + "category": "Error", + "code": 4111 + }, + "This member cannot have an 'override' modifier because its containing class '{0}' does not extend another class.": { + "category": "Error", + "code": 4112 + }, + "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'.": { + "category": "Error", + "code": 4113 + }, + "This member must have an 'override' modifier because it overrides a member in the base class '{0}'.": { + "category": "Error", + "code": 4114 + }, + "This parameter property must have an 'override' modifier because it overrides a member in base class '{0}'.": { + "category": "Error", + "code": 4115 + }, + "This member must have an 'override' modifier because it overrides an abstract method that is declared in the base class '{0}'.": { + "category": "Error", + "code": 4116 + }, + "This member cannot have an 'override' modifier because it is not declared in the base class '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 4117 + }, + "The type of this node cannot be serialized because its property '{0}' cannot be serialized.": { + "category": "Error", + "code": 4118 + }, + "This member must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'.": { + "category": "Error", + "code": 4119 + }, + "This parameter property must have a JSDoc comment with an '@override' tag because it overrides a member in the base class '{0}'.": { + "category": "Error", + "code": 4120 + }, + "This member cannot have a JSDoc comment with an '@override' tag because its containing class '{0}' does not extend another class.": { + "category": "Error", + "code": 4121 + }, + "This member cannot have a JSDoc comment with an '@override' tag because it is not declared in the base class '{0}'.": { + "category": "Error", + "code": 4122 + }, + "This member cannot have a JSDoc comment with an 'override' tag because it is not declared in the base class '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 4123 + }, + "Compiler option '{0}' of value '{1}' is unstable. Use nightly TypeScript to silence this error. Try updating with 'npm install -D typescript@next'.": { + "category": "Error", + "code": 4124 + }, + "Each declaration of '{0}.{1}' differs in its value, where '{2}' was expected but '{3}' was given.": { + "category": "Error", + "code": 4125 + }, + "One value of '{0}.{1}' is the string '{2}', and the other is assumed to be an unknown numeric value.": { + "category": "Error", + "code": 4126 + }, + "This member cannot have an 'override' modifier because its name is dynamic.": { + "category": "Error", + "code": 4127 + }, + "This member cannot have a JSDoc comment with an '@override' tag because its name is dynamic.": { + "category": "Error", + "code": 4128 + }, + + "The current host does not support the '{0}' option.": { + "category": "Error", + "code": 5001 + }, + "Cannot find the common subdirectory path for the input files.": { + "category": "Error", + "code": 5009 + }, + "File specification cannot end in a recursive directory wildcard ('**'): '{0}'.": { + "category": "Error", + "code": 5010 + }, + "The common source directory of '{0}' is '{1}'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.": { + "category": "Error", + "code": 5011 + }, + "Cannot read file '{0}': {1}.": { + "category": "Error", + "code": 5012 + }, + "Unknown compiler option '{0}'.": { + "category": "Error", + "code": 5023 + }, + "Compiler option '{0}' requires a value of type {1}.": { + "category": "Error", + "code": 5024 + }, + "Unknown compiler option '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 5025 + }, + "Could not write file '{0}': {1}.": { + "category": "Error", + "code": 5033 + }, + "Option 'project' cannot be mixed with source files on a command line.": { + "category": "Error", + "code": 5042 + }, + "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher.": { + "category": "Error", + "code": 5047 + }, + "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided.": { + "category": "Error", + "code": 5051 + }, + "Option '{0}' cannot be specified without specifying option '{1}'.": { + "category": "Error", + "code": 5052 + }, + "Option '{0}' cannot be specified with option '{1}'.": { + "category": "Error", + "code": 5053 + }, + "A 'tsconfig.json' file is already defined at: '{0}'.": { + "category": "Error", + "code": 5054 + }, + "Cannot write file '{0}' because it would overwrite input file.": { + "category": "Error", + "code": 5055 + }, + "Cannot write file '{0}' because it would be overwritten by multiple input files.": { + "category": "Error", + "code": 5056 + }, + "Cannot find a tsconfig.json file at the specified directory: '{0}'.": { + "category": "Error", + "code": 5057 + }, + "The specified path does not exist: '{0}'.": { + "category": "Error", + "code": 5058 + }, + "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier.": { + "category": "Error", + "code": 5059 + }, + "Pattern '{0}' can have at most one '*' character.": { + "category": "Error", + "code": 5061 + }, + "Substitution '{0}' in pattern '{1}' can have at most one '*' character.": { + "category": "Error", + "code": 5062 + }, + "Substitutions for pattern '{0}' should be an array.": { + "category": "Error", + "code": 5063 + }, + "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'.": { + "category": "Error", + "code": 5064 + }, + "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'.": { + "category": "Error", + "code": 5065 + }, + "Substitutions for pattern '{0}' shouldn't be an empty array.": { + "category": "Error", + "code": 5066 + }, + "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name.": { + "category": "Error", + "code": 5067 + }, + "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.": { + "category": "Error", + "code": 5068 + }, + "Option '{0}' cannot be specified without specifying option '{1}' or option '{2}'.": { + "category": "Error", + "code": 5069 + }, + "Option '--resolveJsonModule' cannot be specified when 'moduleResolution' is set to 'classic'.": { + "category": "Error", + "code": 5070 + }, + "Option '--resolveJsonModule' cannot be specified when 'module' is set to 'none', 'system', or 'umd'.": { + "category": "Error", + "code": 5071 + }, + "Unknown build option '{0}'.": { + "category": "Error", + "code": 5072 + }, + "Build option '{0}' requires a value of type {1}.": { + "category": "Error", + "code": 5073 + }, + "Option '--incremental' can only be specified using tsconfig, emitting to single file or when option '--tsBuildInfoFile' is specified.": { + "category": "Error", + "code": 5074 + }, + "'{0}' is assignable to the constraint of type '{1}', but '{1}' could be instantiated with a different subtype of constraint '{2}'.": { + "category": "Error", + "code": 5075 + }, + "'{0}' and '{1}' operations cannot be mixed without parentheses.": { + "category": "Error", + "code": 5076 + }, + "Unknown build option '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 5077 + }, + "Unknown watch option '{0}'.": { + "category": "Error", + "code": 5078 + }, + "Unknown watch option '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 5079 + }, + "Watch option '{0}' requires a value of type {1}.": { + "category": "Error", + "code": 5080 + }, + "Cannot find a tsconfig.json file at the current directory: {0}.": { + "category": "Error", + "code": 5081 + }, + "'{0}' could be instantiated with an arbitrary type which could be unrelated to '{1}'.": { + "category": "Error", + "code": 5082 + }, + "Cannot read file '{0}'.": { + "category": "Error", + "code": 5083 + }, + "A tuple member cannot be both optional and rest.": { + "category": "Error", + "code": 5085 + }, + "A labeled tuple element is declared as optional with a question mark after the name and before the colon, rather than after the type.": { + "category": "Error", + "code": 5086 + }, + "A labeled tuple element is declared as rest with a '...' before the name, rather than before the type.": { + "category": "Error", + "code": 5087 + }, + "The inferred type of '{0}' references a type with a cyclic structure which cannot be trivially serialized. A type annotation is necessary.": { + "category": "Error", + "code": 5088 + }, + "Option '{0}' cannot be specified when option 'jsx' is '{1}'.": { + "category": "Error", + "code": 5089 + }, + "Non-relative paths are not allowed when 'baseUrl' is not set. Did you forget a leading './'?": { + "category": "Error", + "code": 5090 + }, + "Option 'preserveConstEnums' cannot be disabled when '{0}' is enabled.": { + "category": "Error", + "code": 5091 + }, + "The root value of a '{0}' file must be an object.": { + "category": "Error", + "code": 5092 + }, + "Compiler option '--{0}' may only be used with '--build'.": { + "category": "Error", + "code": 5093 + }, + "Compiler option '--{0}' may not be used with '--build'.": { + "category": "Error", + "code": 5094 + }, + "Option '{0}' can only be used when 'module' is set to 'preserve', 'commonjs', or 'es2015' or later.": { + "category": "Error", + "code": 5095 + }, + "Option 'allowImportingTsExtensions' can only be used when one of 'noEmit', 'emitDeclarationOnly', or 'rewriteRelativeImportExtensions' is set.": { + "category": "Error", + "code": 5096 + }, + "An import path can only end with a '{0}' extension when 'allowImportingTsExtensions' is enabled.": { + "category": "Error", + "code": 5097 + }, + "Option '{0}' can only be used when 'moduleResolution' is set to 'node16', 'nodenext', or 'bundler'.": { + "category": "Error", + "code": 5098 + }, + "Option '{0}' is deprecated and will stop functioning in TypeScript {1}. Specify compilerOption '\"ignoreDeprecations\": \"{2}\"' to silence this error.": { + "category": "Error", + "code": 5101 + }, + "Option '{0}' has been removed. Please remove it from your configuration.": { + "category": "Error", + "code": 5102 + }, + "Invalid value for '--ignoreDeprecations'.": { + "category": "Error", + "code": 5103 + }, + "Option '{0}' is redundant and cannot be specified with option '{1}'.": { + "category": "Error", + "code": 5104 + }, + "Option 'verbatimModuleSyntax' cannot be used when 'module' is set to 'UMD', 'AMD', or 'System'.": { + "category": "Error", + "code": 5105 + }, + "Use '{0}' instead.": { + "category": "Message", + "code": 5106 + }, + "Option '{0}={1}' is deprecated and will stop functioning in TypeScript {2}. Specify compilerOption '\"ignoreDeprecations\": \"{3}\"' to silence this error.": { + "category": "Error", + "code": 5107 + }, + "Option '{0}={1}' has been removed. Please remove it from your configuration.": { + "category": "Error", + "code": 5108 + }, + "Option 'moduleResolution' must be set to '{0}' (or left unspecified) when option 'module' is set to '{1}'.": { + "category": "Error", + "code": 5109 + }, + "Option 'module' must be set to '{0}' when option 'moduleResolution' is set to '{1}'.": { + "category": "Error", + "code": 5110 + }, + "Visit https://aka.ms/ts6 for migration information.": { + "category": "Message", + "code": 5111 + }, + "tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.": { + "category": "Error", + "code": 5112 + }, + + "Generates a sourcemap for each corresponding '.d.ts' file.": { + "category": "Message", + "code": 6000 + }, + "Concatenate and emit output to single file.": { + "category": "Message", + "code": 6001 + }, + "Generates corresponding '.d.ts' file.": { + "category": "Message", + "code": 6002 + }, + "Specify the location where debugger should locate TypeScript files instead of source locations.": { + "category": "Message", + "code": 6004 + }, + "Watch input files.": { + "category": "Message", + "code": 6005 + }, + "Redirect output structure to the directory.": { + "category": "Message", + "code": 6006 + }, + "Do not erase const enum declarations in generated code.": { + "category": "Message", + "code": 6007 + }, + "Do not emit outputs if any errors were reported.": { + "category": "Message", + "code": 6008 + }, + "Do not emit comments to output.": { + "category": "Message", + "code": 6009 + }, + "Do not emit outputs.": { + "category": "Message", + "code": 6010 + }, + "Allow default imports from modules with no default export. This does not affect code emit, just typechecking.": { + "category": "Message", + "code": 6011 + }, + "Skip type checking of declaration files.": { + "category": "Message", + "code": 6012 + }, + "Do not resolve the real path of symlinks.": { + "category": "Message", + "code": 6013 + }, + "Only emit '.d.ts' declaration files.": { + "category": "Message", + "code": 6014 + }, + "Specify ECMAScript target version.": { + "category": "Message", + "code": 6015 + }, + "Specify module code generation.": { + "category": "Message", + "code": 6016 + }, + "Print this message.": { + "category": "Message", + "code": 6017 + }, + "Print the compiler's version.": { + "category": "Message", + "code": 6019 + }, + "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.": { + "category": "Message", + "code": 6020 + }, + "Syntax: {0}": { + "category": "Message", + "code": 6023 + }, + "options": { + "category": "Message", + "code": 6024 + }, + "file": { + "category": "Message", + "code": 6025 + }, + "Examples: {0}": { + "category": "Message", + "code": 6026 + }, + "Options:": { + "category": "Message", + "code": 6027 + }, + "Version {0}": { + "category": "Message", + "code": 6029 + }, + "Insert command line options and files from a file.": { + "category": "Message", + "code": 6030 + }, + "Starting compilation in watch mode...": { + "category": "Message", + "code": 6031 + }, + "File change detected. Starting incremental compilation...": { + "category": "Message", + "code": 6032 + }, + "KIND": { + "category": "Message", + "code": 6034 + }, + "FILE": { + "category": "Message", + "code": 6035 + }, + "VERSION": { + "category": "Message", + "code": 6036 + }, + "LOCATION": { + "category": "Message", + "code": 6037 + }, + "DIRECTORY": { + "category": "Message", + "code": 6038 + }, + "STRATEGY": { + "category": "Message", + "code": 6039 + }, + "FILE OR DIRECTORY": { + "category": "Message", + "code": 6040 + }, + "Errors Files": { + "_locale_notes": "There is a double space, and the order cannot be changed (they're table headings) ^", + "category": "Message", + "code": 6041 + }, + "Generates corresponding '.map' file.": { + "category": "Message", + "code": 6043 + }, + "Compiler option '{0}' expects an argument.": { + "category": "Error", + "code": 6044 + }, + "Unterminated quoted string in response file '{0}'.": { + "category": "Error", + "code": 6045 + }, + "Argument for '{0}' option must be: {1}.": { + "category": "Error", + "code": 6046 + }, + "Locale must be of the form or -. For example '{0}' or '{1}'.": { + "category": "Error", + "code": 6048 + }, + "Unable to open file '{0}'.": { + "category": "Error", + "code": 6050 + }, + "Corrupted locale file {0}.": { + "category": "Error", + "code": 6051 + }, + "Raise error on expressions and declarations with an implied 'any' type.": { + "category": "Message", + "code": 6052 + }, + "File '{0}' not found.": { + "category": "Error", + "code": 6053 + }, + "File '{0}' has an unsupported extension. The only supported extensions are {1}.": { + "category": "Error", + "code": 6054 + }, + "Suppress noImplicitAny errors for indexing objects lacking index signatures.": { + "category": "Message", + "code": 6055 + }, + "Do not emit declarations for code that has an '@internal' annotation.": { + "category": "Message", + "code": 6056 + }, + "Specify the root directory of input files. Use to control the output directory structure with --outDir.": { + "category": "Message", + "code": 6058 + }, + "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files.": { + "category": "Error", + "code": 6059 + }, + "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).": { + "category": "Message", + "code": 6060 + }, + "NEWLINE": { + "category": "Message", + "code": 6061 + }, + "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line.": { + "category": "Error", + "code": 6064 + }, + "Enables experimental support for ES7 decorators.": { + "category": "Message", + "code": 6065 + }, + "Enables experimental support for emitting type metadata for decorators.": { + "category": "Message", + "code": 6066 + }, + "Initializes a TypeScript project and creates a tsconfig.json file.": { + "category": "Message", + "code": 6070 + }, + "Successfully created a tsconfig.json file.": { + "category": "Message", + "code": 6071 + }, + "Suppress excess property checks for object literals.": { + "category": "Message", + "code": 6072 + }, + "Stylize errors and messages using color and context (experimental).": { + "category": "Message", + "code": 6073 + }, + "Do not report errors on unused labels.": { + "category": "Message", + "code": 6074 + }, + "Report error when not all code paths in function return a value.": { + "category": "Message", + "code": 6075 + }, + "Report errors for fallthrough cases in switch statement.": { + "category": "Message", + "code": 6076 + }, + "Do not report errors on unreachable code.": { + "category": "Message", + "code": 6077 + }, + "Disallow inconsistently-cased references to the same file.": { + "category": "Message", + "code": 6078 + }, + "Specify library files to be included in the compilation.": { + "category": "Message", + "code": 6079 + }, + "Specify JSX code generation.": { + "category": "Message", + "code": 6080 + }, + "Only 'amd' and 'system' modules are supported alongside --{0}.": { + "category": "Error", + "code": 6082 + }, + "Base directory to resolve non-absolute module names.": { + "category": "Message", + "code": 6083 + }, + "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit": { + "category": "Message", + "code": 6084 + }, + "Enable tracing of the name resolution process.": { + "category": "Message", + "code": 6085 + }, + "======== Resolving module '{0}' from '{1}'. ========": { + "category": "Message", + "code": 6086 + }, + "Explicitly specified module resolution kind: '{0}'.": { + "category": "Message", + "code": 6087 + }, + "Module resolution kind is not specified, using '{0}'.": { + "category": "Message", + "code": 6088 + }, + "======== Module name '{0}' was successfully resolved to '{1}'. ========": { + "category": "Message", + "code": 6089 + }, + "======== Module name '{0}' was not resolved. ========": { + "category": "Message", + "code": 6090 + }, + "'paths' option is specified, looking for a pattern to match module name '{0}'.": { + "category": "Message", + "code": 6091 + }, + "Module name '{0}', matched pattern '{1}'.": { + "category": "Message", + "code": 6092 + }, + "Trying substitution '{0}', candidate module location: '{1}'.": { + "category": "Message", + "code": 6093 + }, + "Resolving module name '{0}' relative to base url '{1}' - '{2}'.": { + "category": "Message", + "code": 6094 + }, + "Loading module as file / folder, candidate module location '{0}', target file types: {1}.": { + "category": "Message", + "code": 6095 + }, + "File '{0}' does not exist.": { + "category": "Message", + "code": 6096 + }, + "File '{0}' exists - use it as a name resolution result.": { + "category": "Message", + "code": 6097 + }, + "Loading module '{0}' from 'node_modules' folder, target file types: {1}.": { + "category": "Message", + "code": 6098 + }, + "Found 'package.json' at '{0}'.": { + "category": "Message", + "code": 6099 + }, + "'package.json' does not have a '{0}' field.": { + "category": "Message", + "code": 6100 + }, + "'package.json' has '{0}' field '{1}' that references '{2}'.": { + "category": "Message", + "code": 6101 + }, + "Allow javascript files to be compiled.": { + "category": "Message", + "code": 6102 + }, + "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'.": { + "category": "Message", + "code": 6104 + }, + "Expected type of '{0}' field in 'package.json' to be '{1}', got '{2}'.": { + "category": "Message", + "code": 6105 + }, + "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'.": { + "category": "Message", + "code": 6106 + }, + "'rootDirs' option is set, using it to resolve relative module name '{0}'.": { + "category": "Message", + "code": 6107 + }, + "Longest matching prefix for '{0}' is '{1}'.": { + "category": "Message", + "code": 6108 + }, + "Loading '{0}' from the root dir '{1}', candidate location '{2}'.": { + "category": "Message", + "code": 6109 + }, + "Trying other entries in 'rootDirs'.": { + "category": "Message", + "code": 6110 + }, + "Module resolution using 'rootDirs' has failed.": { + "category": "Message", + "code": 6111 + }, + "Do not emit 'use strict' directives in module output.": { + "category": "Message", + "code": 6112 + }, + "Enable strict null checks.": { + "category": "Message", + "code": 6113 + }, + "Unknown option 'excludes'. Did you mean 'exclude'?": { + "category": "Error", + "code": 6114 + }, + "Raise error on 'this' expressions with an implied 'any' type.": { + "category": "Message", + "code": 6115 + }, + "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========": { + "category": "Message", + "code": 6116 + }, + "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========": { + "category": "Message", + "code": 6119 + }, + "======== Type reference directive '{0}' was not resolved. ========": { + "category": "Message", + "code": 6120 + }, + "Resolving with primary search path '{0}'.": { + "category": "Message", + "code": 6121 + }, + "Root directory cannot be determined, skipping primary search paths.": { + "category": "Message", + "code": 6122 + }, + "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========": { + "category": "Message", + "code": 6123 + }, + "Type declaration files to be included in compilation.": { + "category": "Message", + "code": 6124 + }, + "Looking up in 'node_modules' folder, initial location '{0}'.": { + "category": "Message", + "code": 6125 + }, + "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder.": { + "category": "Message", + "code": 6126 + }, + "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========": { + "category": "Message", + "code": 6127 + }, + "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========": { + "category": "Message", + "code": 6128 + }, + "Resolving real path for '{0}', result '{1}'.": { + "category": "Message", + "code": 6130 + }, + "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'.": { + "category": "Error", + "code": 6131 + }, + "File name '{0}' has a '{1}' extension - stripping it.": { + "category": "Message", + "code": 6132 + }, + "'{0}' is declared but its value is never read.": { + "category": "Error", + "code": 6133, + "reportsUnnecessary": true + }, + "Report errors on unused locals.": { + "category": "Message", + "code": 6134 + }, + "Report errors on unused parameters.": { + "category": "Message", + "code": 6135 + }, + "The maximum dependency depth to search under node_modules and load JavaScript files.": { + "category": "Message", + "code": 6136 + }, + "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'.": { + "category": "Error", + "code": 6137 + }, + "Property '{0}' is declared but its value is never read.": { + "category": "Error", + "code": 6138, + "reportsUnnecessary": true + }, + "Import emit helpers from 'tslib'.": { + "category": "Message", + "code": 6139 + }, + "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'.": { + "category": "Error", + "code": 6140 + }, + "Parse in strict mode and emit \"use strict\" for each source file.": { + "category": "Message", + "code": 6141 + }, + "Module '{0}' was resolved to '{1}', but '--jsx' is not set.": { + "category": "Error", + "code": 6142 + }, + "Module '{0}' was resolved as locally declared ambient module in file '{1}'.": { + "category": "Message", + "code": 6144 + }, + "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'.": { + "category": "Message", + "code": 6146 + }, + "Resolution for module '{0}' was found in cache from location '{1}'.": { + "category": "Message", + "code": 6147 + }, + "Directory '{0}' does not exist, skipping all lookups in it.": { + "category": "Message", + "code": 6148 + }, + "Show diagnostic information.": { + "category": "Message", + "code": 6149 + }, + "Show verbose diagnostic information.": { + "category": "Message", + "code": 6150 + }, + "Emit a single file with source maps instead of having a separate file.": { + "category": "Message", + "code": 6151 + }, + "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set.": { + "category": "Message", + "code": 6152 + }, + "Transpile each file as a separate module (similar to 'ts.transpileModule').": { + "category": "Message", + "code": 6153 + }, + "Print names of generated files part of the compilation.": { + "category": "Message", + "code": 6154 + }, + "Print names of files part of the compilation.": { + "category": "Message", + "code": 6155 + }, + "The locale used when displaying messages to the user (e.g. 'en-us')": { + "category": "Message", + "code": 6156 + }, + "Do not generate custom helper functions like '__extends' in compiled output.": { + "category": "Message", + "code": 6157 + }, + "Do not include the default library file (lib.d.ts).": { + "category": "Message", + "code": 6158 + }, + "Do not add triple-slash references or imported modules to the list of compiled files.": { + "category": "Message", + "code": 6159 + }, + "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files.": { + "category": "Message", + "code": 6160 + }, + "List of folders to include type definitions from.": { + "category": "Message", + "code": 6161 + }, + "Disable size limitations on JavaScript projects.": { + "category": "Message", + "code": 6162 + }, + "The character set of the input files.": { + "category": "Message", + "code": 6163 + }, + "Skipping module '{0}' that looks like an absolute URI, target file types: {1}.": { + "category": "Message", + "code": 6164 + }, + "Do not truncate error messages.": { + "category": "Message", + "code": 6165 + }, + "Output directory for generated declaration files.": { + "category": "Message", + "code": 6166 + }, + "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'.": { + "category": "Message", + "code": 6167 + }, + "List of root folders whose combined content represents the structure of the project at runtime.": { + "category": "Message", + "code": 6168 + }, + "Show all compiler options.": { + "category": "Message", + "code": 6169 + }, + "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file": { + "category": "Message", + "code": 6170 + }, + "Command-line Options": { + "category": "Message", + "code": 6171 + }, + "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5'.": { + "category": "Message", + "code": 6179 + }, + "Enable all strict type-checking options.": { + "category": "Message", + "code": 6180 + }, + "Scoped package detected, looking in '{0}'": { + "category": "Message", + "code": 6182 + }, + "Reusing resolution of module '{0}' from '{1}' of old program, it was successfully resolved to '{2}'.": { + "category": "Message", + "code": 6183 + }, + "Reusing resolution of module '{0}' from '{1}' of old program, it was successfully resolved to '{2}' with Package ID '{3}'.": { + "category": "Message", + "code": 6184 + }, + "Enable strict checking of function types.": { + "category": "Message", + "code": 6186 + }, + "Enable strict checking of property initialization in classes.": { + "category": "Message", + "code": 6187 + }, + "Numeric separators are not allowed here.": { + "category": "Error", + "code": 6188 + }, + "Multiple consecutive numeric separators are not permitted.": { + "category": "Error", + "code": 6189 + }, + "Whether to keep outdated console output in watch mode instead of clearing the screen.": { + "category": "Message", + "code": 6191 + }, + "All imports in import declaration are unused.": { + "category": "Error", + "code": 6192, + "reportsUnnecessary": true + }, + "Found 1 error. Watching for file changes.": { + "category": "Message", + "code": 6193 + }, + "Found {0} errors. Watching for file changes.": { + "category": "Message", + "code": 6194 + }, + "Resolve 'keyof' to string valued property names only (no numbers or symbols).": { + "category": "Message", + "code": 6195 + }, + "'{0}' is declared but never used.": { + "category": "Error", + "code": 6196, + "reportsUnnecessary": true + }, + "Include modules imported with '.json' extension": { + "category": "Message", + "code": 6197 + }, + "All destructured elements are unused.": { + "category": "Error", + "code": 6198, + "reportsUnnecessary": true + }, + "All variables are unused.": { + "category": "Error", + "code": 6199, + "reportsUnnecessary": true + }, + "Definitions of the following identifiers conflict with those in another file: {0}": { + "category": "Error", + "code": 6200 + }, + "Conflicts are in this file.": { + "category": "Message", + "code": 6201 + }, + "Project references may not form a circular graph. Cycle detected: {0}": { + "category": "Error", + "code": 6202 + }, + "'{0}' was also declared here.": { + "category": "Message", + "code": 6203 + }, + "and here.": { + "category": "Message", + "code": 6204 + }, + "All type parameters are unused.": { + "category": "Error", + "code": 6205 + }, + "'package.json' has a 'typesVersions' field with version-specific path mappings.": { + "category": "Message", + "code": 6206 + }, + "'package.json' does not have a 'typesVersions' entry that matches version '{0}'.": { + "category": "Message", + "code": 6207 + }, + "'package.json' has a 'typesVersions' entry '{0}' that matches compiler version '{1}', looking for a pattern to match module name '{2}'.": { + "category": "Message", + "code": 6208 + }, + "'package.json' has a 'typesVersions' entry '{0}' that is not a valid semver range.": { + "category": "Message", + "code": 6209 + }, + "An argument for '{0}' was not provided.": { + "category": "Message", + "code": 6210 + }, + "An argument matching this binding pattern was not provided.": { + "category": "Message", + "code": 6211 + }, + "Did you mean to call this expression?": { + "category": "Message", + "code": 6212 + }, + "Did you mean to use 'new' with this expression?": { + "category": "Message", + "code": 6213 + }, + "Enable strict 'bind', 'call', and 'apply' methods on functions.": { + "category": "Message", + "code": 6214 + }, + "Using compiler options of project reference redirect '{0}'.": { + "category": "Message", + "code": 6215 + }, + "Found 1 error.": { + "category": "Message", + "code": 6216 + }, + "Found {0} errors.": { + "category": "Message", + "code": 6217 + }, + "======== Module name '{0}' was successfully resolved to '{1}' with Package ID '{2}'. ========": { + "category": "Message", + "code": 6218 + }, + "======== Type reference directive '{0}' was successfully resolved to '{1}' with Package ID '{2}', primary: {3}. ========": { + "category": "Message", + "code": 6219 + }, + "'package.json' had a falsy '{0}' field.": { + "category": "Message", + "code": 6220 + }, + "Disable use of source files instead of declaration files from referenced projects.": { + "category": "Message", + "code": 6221 + }, + "Emit class fields with Define instead of Set.": { + "category": "Message", + "code": 6222 + }, + "Generates a CPU profile.": { + "category": "Message", + "code": 6223 + }, + "Disable solution searching for this project.": { + "category": "Message", + "code": 6224 + }, + "Specify strategy for watching file: 'FixedPollingInterval' (default), 'PriorityPollingInterval', 'DynamicPriorityPolling', 'FixedChunkSizePolling', 'UseFsEvents', 'UseFsEventsOnParentDirectory'.": { + "category": "Message", + "code": 6225 + }, + "Specify strategy for watching directory on platforms that don't support recursive watching natively: 'UseFsEvents' (default), 'FixedPollingInterval', 'DynamicPriorityPolling', 'FixedChunkSizePolling'.": { + "category": "Message", + "code": 6226 + }, + "Specify strategy for creating a polling watch when it fails to create using file system events: 'FixedInterval' (default), 'PriorityInterval', 'DynamicPriority', 'FixedChunkSize'.": { + "category": "Message", + "code": 6227 + }, + "Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'.": { + "category": "Error", + "code": 6229 + }, + "Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line.": { + "category": "Error", + "code": 6230 + }, + "Could not resolve the path '{0}' with the extensions: {1}.": { + "category": "Error", + "code": 6231 + }, + "Declaration augments declaration in another file. This cannot be serialized.": { + "category": "Error", + "code": 6232 + }, + "This is the declaration being augmented. Consider moving the augmenting declaration into the same file.": { + "category": "Error", + "code": 6233 + }, + "This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?": { + "category": "Error", + "code": 6234 + }, + "Disable loading referenced projects.": { + "category": "Message", + "code": 6235 + }, + "Arguments for the rest parameter '{0}' were not provided.": { + "category": "Error", + "code": 6236 + }, + "Generates an event trace and a list of types.": { + "category": "Message", + "code": 6237 + }, + "Specify the module specifier to be used to import the 'jsx' and 'jsxs' factory functions from. eg, react": { + "category": "Error", + "code": 6238 + }, + "File '{0}' exists according to earlier cached lookups.": { + "category": "Message", + "code": 6239 + }, + "File '{0}' does not exist according to earlier cached lookups.": { + "category": "Message", + "code": 6240 + }, + "Resolution for type reference directive '{0}' was found in cache from location '{1}'.": { + "category": "Message", + "code": 6241 + }, + "======== Resolving type reference directive '{0}', containing file '{1}'. ========": { + "category": "Message", + "code": 6242 + }, + "Interpret optional property types as written, rather than adding 'undefined'.": { + "category": "Message", + "code": 6243 + }, + "Modules": { + "category": "Message", + "code": 6244 + }, + "File Management": { + "category": "Message", + "code": 6245 + }, + "Emit": { + "category": "Message", + "code": 6246 + }, + "JavaScript Support": { + "category": "Message", + "code": 6247 + }, + "Type Checking": { + "category": "Message", + "code": 6248 + }, + "Editor Support": { + "category": "Message", + "code": 6249 + }, + "Watch and Build Modes": { + "category": "Message", + "code": 6250 + }, + "Compiler Diagnostics": { + "category": "Message", + "code": 6251 + }, + "Interop Constraints": { + "category": "Message", + "code": 6252 + }, + "Backwards Compatibility": { + "category": "Message", + "code": 6253 + }, + "Language and Environment": { + "category": "Message", + "code": 6254 + }, + "Projects": { + "category": "Message", + "code": 6255 + }, + "Output Formatting": { + "category": "Message", + "code": 6256 + }, + "Completeness": { + "category": "Message", + "code": 6257 + }, + "'{0}' should be set inside the 'compilerOptions' object of the config json file": { + "category": "Error", + "code": 6258 + }, + "Found 1 error in {0}": { + "category": "Message", + "code": 6259 + }, + "Found {0} errors in the same file, starting at: {1}": { + "category": "Message", + "code": 6260 + }, + "Found {0} errors in {1} files.": { + "category": "Message", + "code": 6261 + }, + "File name '{0}' has a '{1}' extension - looking up '{2}' instead.": { + "category": "Message", + "code": 6262 + }, + "Module '{0}' was resolved to '{1}', but '--allowArbitraryExtensions' is not set.": { + "category": "Error", + "code": 6263 + }, + "Enable importing files with any extension, provided a declaration file is present.": { + "category": "Message", + "code": 6264 + }, + "Resolving type reference directive for program that specifies custom typeRoots, skipping lookup in 'node_modules' folder.": { + "category": "Message", + "code": 6265 + }, + "Option '{0}' can only be specified on command line.": { + "category": "Error", + "code": 6266 + }, + + "Directory '{0}' has no containing package.json scope. Imports will not resolve.": { + "category": "Message", + "code": 6270 + }, + "Import specifier '{0}' does not exist in package.json scope at path '{1}'.": { + "category": "Message", + "code": 6271 + }, + "Invalid import specifier '{0}' has no possible resolutions.": { + "category": "Message", + "code": 6272 + }, + "package.json scope '{0}' has no imports defined.": { + "category": "Message", + "code": 6273 + }, + "package.json scope '{0}' explicitly maps specifier '{1}' to null.": { + "category": "Message", + "code": 6274 + }, + "package.json scope '{0}' has invalid type for target of specifier '{1}'": { + "category": "Message", + "code": 6275 + }, + "Export specifier '{0}' does not exist in package.json scope at path '{1}'.": { + "category": "Message", + "code": 6276 + }, + "Resolution of non-relative name failed; trying with modern Node resolution features disabled to see if npm library needs configuration update.": { + "category": "Message", + "code": 6277 + }, + "There are types at '{0}', but this result could not be resolved when respecting package.json \"exports\". The '{1}' library may need to update its package.json or typings.": { + "category": "Message", + "code": 6278 + }, + "Resolution of non-relative name failed; trying with '--moduleResolution bundler' to see if project may need configuration update.": { + "category": "Message", + "code": 6279 + }, + "There are types at '{0}', but this result could not be resolved under your current 'moduleResolution' setting. Consider updating to 'node16', 'nodenext', or 'bundler'.": { + "category": "Message", + "code": 6280 + }, + "'package.json' has a 'peerDependencies' field.": { + "category": "Message", + "code": 6281 + }, + "Found peerDependency '{0}' with '{1}' version.": { + "category": "Message", + "code": 6282 + }, + "Failed to find peerDependency '{0}'.": { + "category": "Message", + "code": 6283 + }, + "File Layout": { + "category": "Message", + "code": 6284 + }, + "Environment Settings": { + "category": "Message", + "code": 6285 + }, + "See also https://aka.ms/tsconfig/module": { + "category": "Message", + "code": 6286 + }, + "For nodejs:": { + "category": "Message", + "code": 6287 + }, + "and npm install -D @types/node": { + "category": "Message", + "code": 6290 + }, + "Other Outputs": { + "category": "Message", + "code": 6291 + }, + "Stricter Typechecking Options": { + "category": "Message", + "code": 6292 + }, + "Style Options": { + "category": "Message", + "code": 6293 + }, + "Recommended Options": { + "category": "Message", + "code": 6294 + }, + + "Enable project compilation": { + "category": "Message", + "code": 6302 + }, + "Composite projects may not disable declaration emit.": { + "category": "Error", + "code": 6304 + }, + "Output file '{0}' has not been built from source file '{1}'.": { + "category": "Error", + "code": 6305 + }, + "Referenced project '{0}' must have setting \"composite\": true.": { + "category": "Error", + "code": 6306 + }, + "File '{0}' is not listed within the file list of project '{1}'. Projects must list all files or use an 'include' pattern.": { + "category": "Error", + "code": 6307 + }, + "Referenced project '{0}' may not disable emit.": { + "category": "Error", + "code": 6310 + }, + "Project '{0}' is out of date because output '{1}' is older than input '{2}'": { + "category": "Message", + "code": 6350 + }, + "Project '{0}' is up to date because newest input '{1}' is older than output '{2}'": { + "category": "Message", + "code": 6351 + }, + "Project '{0}' is out of date because output file '{1}' does not exist": { + "category": "Message", + "code": 6352 + }, + "Project '{0}' is out of date because its dependency '{1}' is out of date": { + "category": "Message", + "code": 6353 + }, + "Project '{0}' is up to date with .d.ts files from its dependencies": { + "category": "Message", + "code": 6354 + }, + "Projects in this build: {0}": { + "category": "Message", + "code": 6355 + }, + "A non-dry build would delete the following files: {0}": { + "category": "Message", + "code": 6356 + }, + "A non-dry build would build project '{0}'": { + "category": "Message", + "code": 6357 + }, + "Building project '{0}'...": { + "category": "Message", + "code": 6358 + }, + "Updating output timestamps of project '{0}'...": { + "category": "Message", + "code": 6359 + }, + "Project '{0}' is up to date": { + "category": "Message", + "code": 6361 + }, + "Skipping build of project '{0}' because its dependency '{1}' has errors": { + "category": "Message", + "code": 6362 + }, + "Project '{0}' can't be built because its dependency '{1}' has errors": { + "category": "Message", + "code": 6363 + }, + "Build one or more projects and their dependencies, if out of date": { + "category": "Message", + "code": 6364 + }, + "Delete the outputs of all projects.": { + "category": "Message", + "code": 6365 + }, + "Show what would be built (or deleted, if specified with '--clean')": { + "category": "Message", + "code": 6367 + }, + "Option '--build' must be the first command line argument.": { + "category": "Error", + "code": 6369 + }, + "Options '{0}' and '{1}' cannot be combined.": { + "category": "Error", + "code": 6370 + }, + "Updating unchanged output timestamps of project '{0}'...": { + "category": "Message", + "code": 6371 + }, + "A non-dry build would update timestamps for output of project '{0}'": { + "category": "Message", + "code": 6374 + }, + "Cannot write file '{0}' because it will overwrite '.tsbuildinfo' file generated by referenced project '{1}'": { + "category": "Error", + "code": 6377 + }, + "Composite projects may not disable incremental compilation.": { + "category": "Error", + "code": 6379 + }, + "Specify file to store incremental compilation information": { + "category": "Message", + "code": 6380 + }, + "Project '{0}' is out of date because output for it was generated with version '{1}' that differs with current version '{2}'": { + "category": "Message", + "code": 6381 + }, + "Skipping build of project '{0}' because its dependency '{1}' was not built": { + "category": "Message", + "code": 6382 + }, + "Project '{0}' can't be built because its dependency '{1}' was not built": { + "category": "Message", + "code": 6383 + }, + "Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it.": { + "category": "Message", + "code": 6384 + }, + "'{0}' is deprecated.": { + "category": "Suggestion", + "code": 6385, + "reportsDeprecated": true + }, + "Performance timings for '--diagnostics' or '--extendedDiagnostics' are not available in this session. A native implementation of the Web Performance API could not be found.": { + "category": "Message", + "code": 6386 + }, + "The signature '{0}' of '{1}' is deprecated.": { + "category": "Suggestion", + "code": 6387, + "reportsDeprecated": true + }, + "Project '{0}' is being forcibly rebuilt": { + "category": "Message", + "code": 6388 + }, + "Reusing resolution of module '{0}' from '{1}' of old program, it was not resolved.": { + "category": "Message", + "code": 6389 + }, + "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was successfully resolved to '{2}'.": { + "category": "Message", + "code": 6390 + }, + "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was successfully resolved to '{2}' with Package ID '{3}'.": { + "category": "Message", + "code": 6391 + }, + "Reusing resolution of type reference directive '{0}' from '{1}' of old program, it was not resolved.": { + "category": "Message", + "code": 6392 + }, + "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}'.": { + "category": "Message", + "code": 6393 + }, + "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}' with Package ID '{4}'.": { + "category": "Message", + "code": 6394 + }, + "Reusing resolution of module '{0}' from '{1}' found in cache from location '{2}', it was not resolved.": { + "category": "Message", + "code": 6395 + }, + "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}'.": { + "category": "Message", + "code": 6396 + }, + "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was successfully resolved to '{3}' with Package ID '{4}'.": { + "category": "Message", + "code": 6397 + }, + "Reusing resolution of type reference directive '{0}' from '{1}' found in cache from location '{2}', it was not resolved.": { + "category": "Message", + "code": 6398 + }, + "Project '{0}' is out of date because buildinfo file '{1}' indicates that some of the changes were not emitted": { + "category": "Message", + "code": 6399 + }, + "Project '{0}' is up to date but needs to update timestamps of output files that are older than input files": { + "category": "Message", + "code": 6400 + }, + "Project '{0}' is out of date because there was error reading file '{1}'": { + "category": "Message", + "code": 6401 + }, + "Resolving in {0} mode with conditions {1}.": { + "category": "Message", + "code": 6402 + }, + "Matched '{0}' condition '{1}'.": { + "category": "Message", + "code": 6403 + }, + "Using '{0}' subpath '{1}' with target '{2}'.": { + "category": "Message", + "code": 6404 + }, + "Saw non-matching condition '{0}'.": { + "category": "Message", + "code": 6405 + }, + "Project '{0}' is out of date because buildinfo file '{1}' indicates there is change in compilerOptions": { + "category": "Message", + "code": 6406 + }, + "Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set.": { + "category": "Message", + "code": 6407 + }, + "Use the package.json 'exports' field when resolving package imports.": { + "category": "Message", + "code": 6408 + }, + "Use the package.json 'imports' field when resolving imports.": { + "category": "Message", + "code": 6409 + }, + "Conditions to set in addition to the resolver-specific defaults when resolving imports.": { + "category": "Message", + "code": 6410 + }, + "`true` when 'moduleResolution' is 'node16', 'nodenext', or 'bundler'; otherwise `false`.": { + "category": "Message", + "code": 6411 + }, + "Project '{0}' is out of date because buildinfo file '{1}' indicates that file '{2}' was root file of compilation but not any more.": { + "category": "Message", + "code": 6412 + }, + "Entering conditional exports.": { + "category": "Message", + "code": 6413 + }, + "Resolved under condition '{0}'.": { + "category": "Message", + "code": 6414 + }, + "Failed to resolve under condition '{0}'.": { + "category": "Message", + "code": 6415 + }, + "Exiting conditional exports.": { + "category": "Message", + "code": 6416 + }, + "Searching all ancestor node_modules directories for preferred extensions: {0}.": { + "category": "Message", + "code": 6417 + }, + "Searching all ancestor node_modules directories for fallback extensions: {0}.": { + "category": "Message", + "code": 6418 + }, + "Project '{0}' is out of date because buildinfo file '{1}' indicates that program needs to report errors.": { + "category": "Message", + "code": 6419 + }, + "Project '{0}' is out of date because {1}.": { + "category": "Message", + "code": 6420 + }, + "Rewrite '.ts', '.tsx', '.mts', and '.cts' file extensions in relative import paths to their JavaScript equivalent in output files.": { + "category": "Message", + "code": 6421 + }, + + "The expected type comes from property '{0}' which is declared here on type '{1}'": { + "category": "Message", + "code": 6500 + }, + "The expected type comes from this index signature.": { + "category": "Message", + "code": 6501 + }, + "The expected type comes from the return type of this signature.": { + "category": "Message", + "code": 6502 + }, + "Print names of files that are part of the compilation and then stop processing.": { + "category": "Message", + "code": 6503 + }, + "File '{0}' is a JavaScript file. Did you mean to enable the 'allowJs' option?": { + "category": "Error", + "code": 6504 + }, + "Print names of files and the reason they are part of the compilation.": { + "category": "Message", + "code": 6505 + }, + "Consider adding a 'declare' modifier to this class.": { + "category": "Message", + "code": 6506 + }, + "Allow JavaScript files to be a part of your program. Use the 'checkJs' option to get errors from these files.": { + "category": "Message", + "code": 6600 + }, + "Allow 'import x from y' when a module doesn't have a default export.": { + "category": "Message", + "code": 6601 + }, + "Allow accessing UMD globals from modules.": { + "category": "Message", + "code": 6602 + }, + "Disable error reporting for unreachable code.": { + "category": "Message", + "code": 6603 + }, + "Disable error reporting for unused labels.": { + "category": "Message", + "code": 6604 + }, + "Ensure 'use strict' is always emitted.": { + "category": "Message", + "code": 6605 + }, + "Have recompiles in projects that use 'incremental' and 'watch' mode assume that changes within a file will only affect files directly depending on it.": { + "category": "Message", + "code": 6606 + }, + "Specify the base directory to resolve non-relative module names.": { + "category": "Message", + "code": 6607 + }, + "No longer supported. In early versions, manually set the text encoding for reading files.": { + "category": "Message", + "code": 6608 + }, + "Enable error reporting in type-checked JavaScript files.": { + "category": "Message", + "code": 6609 + }, + "Enable constraints that allow a TypeScript project to be used with project references.": { + "category": "Message", + "code": 6611 + }, + "Generate .d.ts files from TypeScript and JavaScript files in your project.": { + "category": "Message", + "code": 6612 + }, + "Specify the output directory for generated declaration files.": { + "category": "Message", + "code": 6613 + }, + "Create sourcemaps for d.ts files.": { + "category": "Message", + "code": 6614 + }, + "Output compiler performance information after building.": { + "category": "Message", + "code": 6615 + }, + "Disables inference for type acquisition by looking at filenames in a project.": { + "category": "Message", + "code": 6616 + }, + "Reduce the number of projects loaded automatically by TypeScript.": { + "category": "Message", + "code": 6617 + }, + "Remove the 20mb cap on total source code size for JavaScript files in the TypeScript language server.": { + "category": "Message", + "code": 6618 + }, + "Opt a project out of multi-project reference checking when editing.": { + "category": "Message", + "code": 6619 + }, + "Disable preferring source files instead of declaration files when referencing composite projects.": { + "category": "Message", + "code": 6620 + }, + "Emit more compliant, but verbose and less performant JavaScript for iteration.": { + "category": "Message", + "code": 6621 + }, + "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.": { + "category": "Message", + "code": 6622 + }, + "Only output d.ts files and not JavaScript files.": { + "category": "Message", + "code": 6623 + }, + "Emit design-type metadata for decorated declarations in source files.": { + "category": "Message", + "code": 6624 + }, + "Disable the type acquisition for JavaScript projects": { + "category": "Message", + "code": 6625 + }, + "Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.": { + "category": "Message", + "code": 6626 + }, + "Filters results from the `include` option.": { + "category": "Message", + "code": 6627 + }, + "Remove a list of directories from the watch process.": { + "category": "Message", + "code": 6628 + }, + "Remove a list of files from the watch mode's processing.": { + "category": "Message", + "code": 6629 + }, + "Enable experimental support for legacy experimental decorators.": { + "category": "Message", + "code": 6630 + }, + "Print files read during the compilation including why it was included.": { + "category": "Message", + "code": 6631 + }, + "Output more detailed compiler performance information after building.": { + "category": "Message", + "code": 6632 + }, + "Specify one or more path or node module references to base configuration files from which settings are inherited.": { + "category": "Message", + "code": 6633 + }, + "Specify what approach the watcher should use if the system runs out of native file watchers.": { + "category": "Message", + "code": 6634 + }, + "Include a list of files. This does not support glob patterns, as opposed to `include`.": { + "category": "Message", + "code": 6635 + }, + "Build all projects, including those that appear to be up to date.": { + "category": "Message", + "code": 6636 + }, + "Ensure that casing is correct in imports.": { + "category": "Message", + "code": 6637 + }, + "Emit a v8 CPU profile of the compiler run for debugging.": { + "category": "Message", + "code": 6638 + }, + "Allow importing helper functions from tslib once per project, instead of including them per-file.": { + "category": "Message", + "code": 6639 + }, + "Skip building downstream projects on error in upstream project.": { + "category": "Message", + "code": 6640 + }, + "Specify a list of glob patterns that match files to be included in compilation.": { + "category": "Message", + "code": 6641 + }, + "Save .tsbuildinfo files to allow for incremental compilation of projects.": { + "category": "Message", + "code": 6642 + }, + "Include sourcemap files inside the emitted JavaScript.": { + "category": "Message", + "code": 6643 + }, + "Include source code in the sourcemaps inside the emitted JavaScript.": { + "category": "Message", + "code": 6644 + }, + "Ensure that each file can be safely transpiled without relying on other imports.": { + "category": "Message", + "code": 6645 + }, + "Specify what JSX code is generated.": { + "category": "Message", + "code": 6646 + }, + "Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'.": { + "category": "Message", + "code": 6647 + }, + "Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'.": { + "category": "Message", + "code": 6648 + }, + "Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'.": { + "category": "Message", + "code": 6649 + }, + "Make keyof only return strings instead of string, numbers or symbols. Legacy option.": { + "category": "Message", + "code": 6650 + }, + "Specify a set of bundled library declaration files that describe the target runtime environment.": { + "category": "Message", + "code": 6651 + }, + "Print the names of emitted files after a compilation.": { + "category": "Message", + "code": 6652 + }, + "Print all of the files read during the compilation.": { + "category": "Message", + "code": 6653 + }, + "Set the language of the messaging from TypeScript. This does not affect emit.": { + "category": "Message", + "code": 6654 + }, + "Specify the location where debugger should locate map files instead of generated locations.": { + "category": "Message", + "code": 6655 + }, + "Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'.": { + "category": "Message", + "code": 6656 + }, + "Specify what module code is generated.": { + "category": "Message", + "code": 6657 + }, + "Specify how TypeScript looks up a file from a given module specifier.": { + "category": "Message", + "code": 6658 + }, + "Set the newline character for emitting files.": { + "category": "Message", + "code": 6659 + }, + "Disable emitting files from a compilation.": { + "category": "Message", + "code": 6660 + }, + "Disable generating custom helper functions like '__extends' in compiled output.": { + "category": "Message", + "code": 6661 + }, + "Disable emitting files if any type checking errors are reported.": { + "category": "Message", + "code": 6662 + }, + "Disable truncating types in error messages.": { + "category": "Message", + "code": 6663 + }, + "Enable error reporting for fallthrough cases in switch statements.": { + "category": "Message", + "code": 6664 + }, + "Enable error reporting for expressions and declarations with an implied 'any' type.": { + "category": "Message", + "code": 6665 + }, + "Ensure overriding members in derived classes are marked with an override modifier.": { + "category": "Message", + "code": 6666 + }, + "Enable error reporting for codepaths that do not explicitly return in a function.": { + "category": "Message", + "code": 6667 + }, + "Enable error reporting when 'this' is given the type 'any'.": { + "category": "Message", + "code": 6668 + }, + "Disable adding 'use strict' directives in emitted JavaScript files.": { + "category": "Message", + "code": 6669 + }, + "Disable including any library files, including the default lib.d.ts.": { + "category": "Message", + "code": 6670 + }, + "Enforces using indexed accessors for keys declared using an indexed type.": { + "category": "Message", + "code": 6671 + }, + "Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project.": { + "category": "Message", + "code": 6672 + }, + "Disable strict checking of generic signatures in function types.": { + "category": "Message", + "code": 6673 + }, + "Add 'undefined' to a type when accessed using an index.": { + "category": "Message", + "code": 6674 + }, + "Enable error reporting when local variables aren't read.": { + "category": "Message", + "code": 6675 + }, + "Raise an error when a function parameter isn't read.": { + "category": "Message", + "code": 6676 + }, + "Deprecated setting. Use 'outFile' instead.": { + "category": "Message", + "code": 6677 + }, + "Specify an output folder for all emitted files.": { + "category": "Message", + "code": 6678 + }, + "Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output.": { + "category": "Message", + "code": 6679 + }, + "Specify a set of entries that re-map imports to additional lookup locations.": { + "category": "Message", + "code": 6680 + }, + "Specify a list of language service plugins to include.": { + "category": "Message", + "code": 6681 + }, + "Disable erasing 'const enum' declarations in generated code.": { + "category": "Message", + "code": 6682 + }, + "Disable resolving symlinks to their realpath. This correlates to the same flag in node.": { + "category": "Message", + "code": 6683 + }, + "Disable wiping the console in watch mode.": { + "category": "Message", + "code": 6684 + }, + "Enable color and formatting in TypeScript's output to make compiler errors easier to read.": { + "category": "Message", + "code": 6685 + }, + "Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit.": { + "category": "Message", + "code": 6686 + }, + "Specify an array of objects that specify paths for projects. Used in project references.": { + "category": "Message", + "code": 6687 + }, + "Disable emitting comments.": { + "category": "Message", + "code": 6688 + }, + "Enable importing .json files.": { + "category": "Message", + "code": 6689 + }, + "Specify the root folder within your source files.": { + "category": "Message", + "code": 6690 + }, + "Allow multiple folders to be treated as one when resolving modules.": { + "category": "Message", + "code": 6691 + }, + "Skip type checking .d.ts files that are included with TypeScript.": { + "category": "Message", + "code": 6692 + }, + "Skip type checking all .d.ts files.": { + "category": "Message", + "code": 6693 + }, + "Create source map files for emitted JavaScript files.": { + "category": "Message", + "code": 6694 + }, + "Specify the root path for debuggers to find the reference source code.": { + "category": "Message", + "code": 6695 + }, + "Check that the arguments for 'bind', 'call', and 'apply' methods match the original function.": { + "category": "Message", + "code": 6697 + }, + "When assigning functions, check to ensure parameters and the return values are subtype-compatible.": { + "category": "Message", + "code": 6698 + }, + "When type checking, take into account 'null' and 'undefined'.": { + "category": "Message", + "code": 6699 + }, + "Check for class properties that are declared but not set in the constructor.": { + "category": "Message", + "code": 6700 + }, + "Disable emitting declarations that have '@internal' in their JSDoc comments.": { + "category": "Message", + "code": 6701 + }, + "Disable reporting of excess property errors during the creation of object literals.": { + "category": "Message", + "code": 6702 + }, + "Suppress 'noImplicitAny' errors when indexing objects that lack index signatures.": { + "category": "Message", + "code": 6703 + }, + "Synchronously call callbacks and update the state of directory watchers on platforms that don`t support recursive watching natively.": { + "category": "Message", + "code": 6704 + }, + "Set the JavaScript language version for emitted JavaScript and include compatible library declarations.": { + "category": "Message", + "code": 6705 + }, + "Log paths used during the 'moduleResolution' process.": { + "category": "Message", + "code": 6706 + }, + "Specify the path to .tsbuildinfo incremental compilation file.": { + "category": "Message", + "code": 6707 + }, + "Specify options for automatic acquisition of declaration files.": { + "category": "Message", + "code": 6709 + }, + "Specify multiple folders that act like './node_modules/@types'.": { + "category": "Message", + "code": 6710 + }, + "Specify type package names to be included without being referenced in a source file.": { + "category": "Message", + "code": 6711 + }, + "Emit ECMAScript-standard-compliant class fields.": { + "category": "Message", + "code": 6712 + }, + "Enable verbose logging.": { + "category": "Message", + "code": 6713 + }, + "Specify how directories are watched on systems that lack recursive file-watching functionality.": { + "category": "Message", + "code": 6714 + }, + "Specify how the TypeScript watch mode works.": { + "category": "Message", + "code": 6715 + }, + "Require undeclared properties from index signatures to use element accesses.": { + "category": "Message", + "code": 6717 + }, + "Specify emit/checking behavior for imports that are only used for types.": { + "category": "Message", + "code": 6718 + }, + "Require sufficient annotation on exports so other tools can trivially generate declaration files.": { + "category": "Message", + "code": 6719 + }, + "Built-in iterators are instantiated with a 'TReturn' type of 'undefined' instead of 'any'.": { + "category": "Message", + "code": 6720 + }, + "Do not allow runtime constructs that are not part of ECMAScript.": { + "category": "Message", + "code": 6721 + }, + "Default catch clause variables as 'unknown' instead of 'any'.": { + "category": "Message", + "code": 6803 + }, + "Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting.": { + "category": "Message", + "code": 6804 + }, + "Disable full type checking (only critical parse and emit errors will be reported).": { + "category": "Message", + "code": 6805 + }, + "Check side effect imports.": { + "category": "Message", + "code": 6806 + }, + "This operation can be simplified. This shift is identical to `{0} {1} {2}`.": { + "category": "Error", + "code": 6807 + }, + "Enable lib replacement.": { + "category": "Message", + "code": 6808 + }, + "Ensure types are ordered stably and deterministically across compilations.": { + "category": "Message", + "code": 6809 + }, + + "one of:": { + "category": "Message", + "code": 6900 + }, + "one or more:": { + "category": "Message", + "code": 6901 + }, + "type:": { + "category": "Message", + "code": 6902 + }, + "default:": { + "category": "Message", + "code": 6903 + }, + + "`true`, unless `strict` is `false`": { + "category": "Message", + "code": 6905 + }, + "`false`, unless `composite` is set": { + "category": "Message", + "code": 6906 + }, + "`[\"node_modules\", \"bower_components\", \"jspm_packages\"]`, plus the value of `outDir` if one is specified.": { + "category": "Message", + "code": 6907 + }, + "`[]` if `files` is specified, otherwise `[\"**/*\"]`": { + "category": "Message", + "code": 6908 + }, + "`true` if `composite`, `false` otherwise": { + "category": "Message", + "code": 6909 + }, + "`nodenext` if `module` is `nodenext`; `node16` if `module` is `node16` or `node18`; otherwise, `bundler`.": { + "category": "Message", + "code": 69010 + }, + "Computed from the list of input files": { + "category": "Message", + "code": 6911 + }, + "Platform specific": { + "category": "Message", + "code": 6912 + }, + "You can learn about all of the compiler options at {0}": { + "category": "Message", + "code": 6913 + }, + "Including --watch, -w will start watching the current project for the file changes. Once set, you can config watch mode with:": { + "category": "Message", + "code": 6914 + }, + "Using --build, -b will make tsc behave more like a build orchestrator than a compiler. This is used to trigger building composite projects which you can learn more about at {0}": { + "category": "Message", + "code": 6915 + }, + "COMMON COMMANDS": { + "category": "Message", + "code": 6916 + }, + "ALL COMPILER OPTIONS": { + "category": "Message", + "code": 6917 + }, + "WATCH OPTIONS": { + "category": "Message", + "code": 6918 + }, + "BUILD OPTIONS": { + "category": "Message", + "code": 6919 + }, + "COMMON COMPILER OPTIONS": { + "category": "Message", + "code": 6920 + }, + "COMMAND LINE FLAGS": { + "category": "Message", + "code": 6921 + }, + "tsc: The TypeScript Compiler": { + "category": "Message", + "code": 6922 + }, + "Compiles the current project (tsconfig.json in the working directory.)": { + "category": "Message", + "code": 6923 + }, + "Ignoring tsconfig.json, compiles the specified files with default compiler options.": { + "category": "Message", + "code": 6924 + }, + "Build a composite project in the working directory.": { + "category": "Message", + "code": 6925 + }, + "Creates a tsconfig.json with the recommended settings in the working directory.": { + "category": "Message", + "code": 6926 + }, + "Compiles the TypeScript project located at the specified path.": { + "category": "Message", + "code": 6927 + }, + "An expanded version of this information, showing all possible compiler options": { + "category": "Message", + "code": 6928 + }, + "Compiles the current project, with additional settings.": { + "category": "Message", + "code": 6929 + }, + "`true` for ES2022 and above, including ESNext.": { + "category": "Message", + "code": 6930 + }, + "List of file name suffixes to search when resolving a module.": { + "category": "Error", + "code": 6931 + }, + "`false`, unless `checkJs` is set": { + "category": "Message", + "code": 6932 + }, + + "Variable '{0}' implicitly has an '{1}' type.": { + "category": "Error", + "code": 7005 + }, + "Parameter '{0}' implicitly has an '{1}' type.": { + "category": "Error", + "code": 7006 + }, + "Member '{0}' implicitly has an '{1}' type.": { + "category": "Error", + "code": 7008 + }, + "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type.": { + "category": "Error", + "code": 7009 + }, + "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type.": { + "category": "Error", + "code": 7010 + }, + "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type.": { + "category": "Error", + "code": 7011 + }, + "This overload implicitly returns the type '{0}' because it lacks a return type annotation.": { + "category": "Error", + "code": 7012 + }, + "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.": { + "category": "Error", + "code": 7013 + }, + "Function type, which lacks return-type annotation, implicitly has an '{0}' return type.": { + "category": "Error", + "code": 7014 + }, + "Element implicitly has an 'any' type because index expression is not of type 'number'.": { + "category": "Error", + "code": 7015 + }, + "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.": { + "category": "Error", + "code": 7016 + }, + "Element implicitly has an 'any' type because type '{0}' has no index signature.": { + "category": "Error", + "code": 7017 + }, + "Object literal's property '{0}' implicitly has an '{1}' type.": { + "category": "Error", + "code": 7018 + }, + "Rest parameter '{0}' implicitly has an 'any[]' type.": { + "category": "Error", + "code": 7019 + }, + "Call signature, which lacks return-type annotation, implicitly has an 'any' return type.": { + "category": "Error", + "code": 7020 + }, + "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.": { + "category": "Error", + "code": 7022 + }, + "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.": { + "category": "Error", + "code": 7023 + }, + "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.": { + "category": "Error", + "code": 7024 + }, + "Generator implicitly has yield type '{0}'. Consider supplying a return type annotation.": { + "category": "Error", + "code": 7025 + }, + "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists.": { + "category": "Error", + "code": 7026 + }, + "Unreachable code detected.": { + "category": "Error", + "code": 7027, + "reportsUnnecessary": true + }, + "Unused label.": { + "category": "Error", + "code": 7028, + "reportsUnnecessary": true + }, + "Fallthrough case in switch.": { + "category": "Error", + "code": 7029 + }, + "Not all code paths return a value.": { + "category": "Error", + "code": 7030 + }, + "Binding element '{0}' implicitly has an '{1}' type.": { + "category": "Error", + "code": 7031 + }, + "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation.": { + "category": "Error", + "code": 7032 + }, + "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation.": { + "category": "Error", + "code": 7033 + }, + "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined.": { + "category": "Error", + "code": 7034 + }, + "Try `npm i --save-dev @types/{1}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`": { + "category": "Error", + "code": 7035 + }, + "Dynamic import's specifier must be of type 'string', but here has type '{0}'.": { + "category": "Error", + "code": 7036 + }, + "Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.": { + "category": "Message", + "code": 7037 + }, + "Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.": { + "category": "Message", + "code": 7038 + }, + "Mapped object type implicitly has an 'any' template type.": { + "category": "Error", + "code": 7039 + }, + "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{1}'": { + "category": "Error", + "code": 7040 + }, + "The containing arrow function captures the global value of 'this'.": { + "category": "Error", + "code": 7041 + }, + "Module '{0}' was resolved to '{1}', but '--resolveJsonModule' is not used.": { + "category": "Error", + "code": 7042 + }, + "Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": { + "category": "Suggestion", + "code": 7043 + }, + "Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": { + "category": "Suggestion", + "code": 7044 + }, + "Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": { + "category": "Suggestion", + "code": 7045 + }, + "Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage.": { + "category": "Suggestion", + "code": 7046 + }, + "Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage.": { + "category": "Suggestion", + "code": 7047 + }, + "Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage.": { + "category": "Suggestion", + "code": 7048 + }, + "Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage.": { + "category": "Suggestion", + "code": 7049 + }, + "'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage.": { + "category": "Suggestion", + "code": 7050 + }, + "Parameter has a name but no type. Did you mean '{0}: {1}'?": { + "category": "Error", + "code": 7051 + }, + "Element implicitly has an 'any' type because type '{0}' has no index signature. Did you mean to call '{1}'?": { + "category": "Error", + "code": 7052 + }, + "Element implicitly has an 'any' type because expression of type '{0}' can't be used to index type '{1}'.": { + "category": "Error", + "code": 7053 + }, + "No index signature with a parameter of type '{0}' was found on type '{1}'.": { + "category": "Error", + "code": 7054 + }, + "'{0}', which lacks return-type annotation, implicitly has an '{1}' yield type.": { + "category": "Error", + "code": 7055 + }, + "The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed.": { + "category": "Error", + "code": 7056 + }, + "'yield' expression implicitly results in an 'any' type because its containing generator lacks a return-type annotation.": { + "category": "Error", + "code": 7057 + }, + "If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`": { + "category": "Error", + "code": 7058 + }, + "This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead.": { + "category": "Error", + "code": 7059 + }, + "This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma or explicit constraint.": { + "category": "Error", + "code": 7060 + }, + "A mapped type may not declare properties or methods.": { + "category": "Error", + "code": 7061 + }, + + "You cannot rename this element.": { + "category": "Error", + "code": 8000 + }, + "You cannot rename elements that are defined in the standard TypeScript library.": { + "category": "Error", + "code": 8001 + }, + "'import ... =' can only be used in TypeScript files.": { + "category": "Error", + "code": 8002 + }, + "'export =' can only be used in TypeScript files.": { + "category": "Error", + "code": 8003 + }, + "Type parameter declarations can only be used in TypeScript files.": { + "category": "Error", + "code": 8004 + }, + "'implements' clauses can only be used in TypeScript files.": { + "category": "Error", + "code": 8005 + }, + "'{0}' declarations can only be used in TypeScript files.": { + "category": "Error", + "code": 8006 + }, + "Type aliases can only be used in TypeScript files.": { + "category": "Error", + "code": 8008 + }, + "The '{0}' modifier can only be used in TypeScript files.": { + "category": "Error", + "code": 8009 + }, + "Type annotations can only be used in TypeScript files.": { + "category": "Error", + "code": 8010 + }, + "Type arguments can only be used in TypeScript files.": { + "category": "Error", + "code": 8011 + }, + "Parameter modifiers can only be used in TypeScript files.": { + "category": "Error", + "code": 8012 + }, + "Non-null assertions can only be used in TypeScript files.": { + "category": "Error", + "code": 8013 + }, + "Type assertion expressions can only be used in TypeScript files.": { + "category": "Error", + "code": 8016 + }, + "Signature declarations can only be used in TypeScript files.": { + "category": "Error", + "code": 8017 + }, + "Report errors in .js files.": { + "category": "Message", + "code": 8019 + }, + "JSDoc types can only be used inside documentation comments.": { + "category": "Error", + "code": 8020 + }, + "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.": { + "category": "Error", + "code": 8021 + }, + "JSDoc '@{0}' is not attached to a class.": { + "category": "Error", + "code": 8022 + }, + "JSDoc '@{0} {1}' does not match the 'extends {2}' clause.": { + "category": "Error", + "code": 8023 + }, + "JSDoc '@param' tag has name '{0}', but there is no parameter with that name.": { + "category": "Error", + "code": 8024 + }, + "Class declarations cannot have more than one '@augments' or '@extends' tag.": { + "category": "Error", + "code": 8025 + }, + "Expected {0} type arguments; provide these with an '@extends' tag.": { + "category": "Error", + "code": 8026 + }, + "Expected {0}-{1} type arguments; provide these with an '@extends' tag.": { + "category": "Error", + "code": 8027 + }, + "JSDoc '...' may only appear in the last parameter of a signature.": { + "category": "Error", + "code": 8028 + }, + "JSDoc '@param' tag has name '{0}', but there is no parameter with that name. It would match 'arguments' if it had an array type.": { + "category": "Error", + "code": 8029 + }, + "The type of a function declaration must match the function's signature.": { + "category": "Error", + "code": 8030 + }, + "You cannot rename a module via a global import.": { + "category": "Error", + "code": 8031 + }, + "Qualified name '{0}' is not allowed without a leading '@param {object} {1}'.": { + "category": "Error", + "code": 8032 + }, + "A JSDoc '@typedef' comment may not contain multiple '@type' tags.": { + "category": "Error", + "code": 8033 + }, + "The tag was first specified here.": { + "category": "Error", + "code": 8034 + }, + "You cannot rename elements that are defined in a 'node_modules' folder.": { + "category": "Error", + "code": 8035 + }, + "You cannot rename elements that are defined in another 'node_modules' folder.": { + "category": "Error", + "code": 8036 + }, + "Type satisfaction expressions can only be used in TypeScript files.": { + "category": "Error", + "code": 8037 + }, + "Decorators may not appear after 'export' or 'export default' if they also appear before 'export'.": { + "category": "Error", + "code": 8038 + }, + "A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag": { + "category": "Error", + "code": 8039 + }, + + "Declaration emit for this file requires using private name '{0}'. An explicit type annotation may unblock declaration emit.": { + "category": "Error", + "code": 9005 + }, + "Declaration emit for this file requires using private name '{0}' from module '{1}'. An explicit type annotation may unblock declaration emit.": { + "category": "Error", + "code": 9006 + }, + "Function must have an explicit return type annotation with --isolatedDeclarations.": { + "category": "Error", + "code": 9007 + }, + "Method must have an explicit return type annotation with --isolatedDeclarations.": { + "category": "Error", + "code": 9008 + }, + "At least one accessor must have an explicit type annotation with --isolatedDeclarations.": { + "category": "Error", + "code": 9009 + }, + "Variable must have an explicit type annotation with --isolatedDeclarations.": { + "category": "Error", + "code": 9010 + }, + "Parameter must have an explicit type annotation with --isolatedDeclarations.": { + "category": "Error", + "code": 9011 + }, + "Property must have an explicit type annotation with --isolatedDeclarations.": { + "category": "Error", + "code": 9012 + }, + "Expression type can't be inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9013 + }, + "Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.": { + "category": "Error", + "code": 9014 + }, + "Objects that contain spread assignments can't be inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9015 + }, + "Objects that contain shorthand properties can't be inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9016 + }, + "Only const arrays can be inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9017 + }, + "Arrays with spread elements can't inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9018 + }, + "Binding elements can't be exported directly with --isolatedDeclarations.": { + "category": "Error", + "code": 9019 + }, + "Enum member initializers must be computable without references to external symbols with --isolatedDeclarations.": { + "category": "Error", + "code": 9020 + }, + "Extends clause can't contain an expression with --isolatedDeclarations.": { + "category": "Error", + "code": 9021 + }, + "Inference from class expressions is not supported with --isolatedDeclarations.": { + "category": "Error", + "code": 9022 + }, + "Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.": { + "category": "Error", + "code": 9023 + }, + "Declaration emit for this parameter requires implicitly adding undefined to its type. This is not supported with --isolatedDeclarations.": { + "category": "Error", + "code": 9025 + }, + "Declaration emit for this file requires preserving this import for augmentations. This is not supported with --isolatedDeclarations.": { + "category": "Error", + "code": 9026 + }, + "Add a type annotation to the variable {0}.": { + "category": "Error", + "code": 9027 + }, + "Add a type annotation to the parameter {0}.": { + "category": "Error", + "code": 9028 + }, + "Add a type annotation to the property {0}.": { + "category": "Error", + "code": 9029 + }, + "Add a return type to the function expression.": { + "category": "Error", + "code": 9030 + }, + "Add a return type to the function declaration.": { + "category": "Error", + "code": 9031 + }, + "Add a return type to the get accessor declaration.": { + "category": "Error", + "code": 9032 + }, + "Add a type to parameter of the set accessor declaration.": { + "category": "Error", + "code": 9033 + }, + "Add a return type to the method": { + "category": "Error", + "code": 9034 + }, + "Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit.": { + "category": "Error", + "code": 9035 + }, + "Move the expression in default export to a variable and add a type annotation to it.": { + "category": "Error", + "code": 9036 + }, + "Default exports can't be inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9037 + }, + "Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.": { + "category": "Error", + "code": 9038 + }, + "Type containing private name '{0}' can't be used with --isolatedDeclarations.": { + "category": "Error", + "code": 9039 + }, + "JSX attributes must only be assigned a non-empty 'expression'.": { + "category": "Error", + "code": 17000 + }, + "JSX elements cannot have multiple attributes with the same name.": { + "category": "Error", + "code": 17001 + }, + "Expected corresponding JSX closing tag for '{0}'.": { + "category": "Error", + "code": 17002 + }, + "Cannot use JSX unless the '--jsx' flag is provided.": { + "category": "Error", + "code": 17004 + }, + "A constructor cannot contain a 'super' call when its class extends 'null'.": { + "category": "Error", + "code": 17005 + }, + "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.": { + "category": "Error", + "code": 17006 + }, + "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses.": { + "category": "Error", + "code": 17007 + }, + "JSX element '{0}' has no corresponding closing tag.": { + "category": "Error", + "code": 17008 + }, + "'super' must be called before accessing 'this' in the constructor of a derived class.": { + "category": "Error", + "code": 17009 + }, + "Unknown type acquisition option '{0}'.": { + "category": "Error", + "code": 17010 + }, + "'super' must be called before accessing a property of 'super' in the constructor of a derived class.": { + "category": "Error", + "code": 17011 + }, + "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?": { + "category": "Error", + "code": 17012 + }, + "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor.": { + "category": "Error", + "code": 17013 + }, + "JSX fragment has no corresponding closing tag.": { + "category": "Error", + "code": 17014 + }, + "Expected corresponding closing tag for JSX fragment.": { + "category": "Error", + "code": 17015 + }, + "The 'jsxFragmentFactory' compiler option must be provided to use JSX fragments with the 'jsxFactory' compiler option.": { + "category": "Error", + "code": 17016 + }, + "An @jsxFrag pragma is required when using an @jsx pragma with JSX fragments.": { + "category": "Error", + "code": 17017 + }, + "Unknown type acquisition option '{0}'. Did you mean '{1}'?": { + "category": "Error", + "code": 17018 + }, + "'{0}' at the end of a type is not valid TypeScript syntax. Did you mean to write '{1}'?": { + "category": "Error", + "code": 17019 + }, + "'{0}' at the start of a type is not valid TypeScript syntax. Did you mean to write '{1}'?": { + "category": "Error", + "code": 17020 + }, + "Unicode escape sequence cannot appear here.": { + "category": "Error", + "code": 17021 + }, + "Circularity detected while resolving configuration: {0}": { + "category": "Error", + "code": 18000 + }, + "The 'files' list in config file '{0}' is empty.": { + "category": "Error", + "code": 18002 + }, + "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'.": { + "category": "Error", + "code": 18003 + }, + + "File is a CommonJS module; it may be converted to an ES module.": { + "category": "Suggestion", + "code": 80001 + }, + "This constructor function may be converted to a class declaration.": { + "category": "Suggestion", + "code": 80002 + }, + "Import may be converted to a default import.": { + "category": "Suggestion", + "code": 80003 + }, + "JSDoc types may be moved to TypeScript types.": { + "category": "Suggestion", + "code": 80004 + }, + "'require' call may be converted to an import.": { + "category": "Suggestion", + "code": 80005 + }, + "This may be converted to an async function.": { + "category": "Suggestion", + "code": 80006 + }, + "'await' has no effect on the type of this expression.": { + "category": "Suggestion", + "code": 80007 + }, + "Numeric literals with absolute values equal to 2^53 or greater are too large to be represented accurately as integers.": { + "category": "Suggestion", + "code": 80008 + }, + "JSDoc typedef may be converted to TypeScript type.": { + "category": "Suggestion", + "code": 80009 + }, + "JSDoc typedefs may be converted to TypeScript types.": { + "category": "Suggestion", + "code": 80010 + }, + + "Add missing 'super()' call": { + "category": "Message", + "code": 90001 + }, + "Make 'super()' call the first statement in the constructor": { + "category": "Message", + "code": 90002 + }, + "Change 'extends' to 'implements'": { + "category": "Message", + "code": 90003 + }, + "Remove unused declaration for: '{0}'": { + "category": "Message", + "code": 90004 + }, + "Remove import from '{0}'": { + "category": "Message", + "code": 90005 + }, + "Implement interface '{0}'": { + "category": "Message", + "code": 90006 + }, + "Implement inherited abstract class": { + "category": "Message", + "code": 90007 + }, + "Add '{0}.' to unresolved variable": { + "category": "Message", + "code": 90008 + }, + "Remove variable statement": { + "category": "Message", + "code": 90010 + }, + "Remove template tag": { + "category": "Message", + "code": 90011 + }, + "Remove type parameters": { + "category": "Message", + "code": 90012 + }, + "Import '{0}' from \"{1}\"": { + "category": "Message", + "code": 90013 + }, + "Change '{0}' to '{1}'": { + "category": "Message", + "code": 90014 + }, + "Declare property '{0}'": { + "category": "Message", + "code": 90016 + }, + "Add index signature for property '{0}'": { + "category": "Message", + "code": 90017 + }, + "Disable checking for this file": { + "category": "Message", + "code": 90018 + }, + "Ignore this error message": { + "category": "Message", + "code": 90019 + }, + "Initialize property '{0}' in the constructor": { + "category": "Message", + "code": 90020 + }, + "Initialize static property '{0}'": { + "category": "Message", + "code": 90021 + }, + "Change spelling to '{0}'": { + "category": "Message", + "code": 90022 + }, + "Declare method '{0}'": { + "category": "Message", + "code": 90023 + }, + "Declare static method '{0}'": { + "category": "Message", + "code": 90024 + }, + "Prefix '{0}' with an underscore": { + "category": "Message", + "code": 90025 + }, + "Rewrite as the indexed access type '{0}'": { + "category": "Message", + "code": 90026 + }, + "Declare static property '{0}'": { + "category": "Message", + "code": 90027 + }, + "Call decorator expression": { + "category": "Message", + "code": 90028 + }, + "Add async modifier to containing function": { + "category": "Message", + "code": 90029 + }, + "Replace 'infer {0}' with 'unknown'": { + "category": "Message", + "code": 90030 + }, + "Replace all unused 'infer' with 'unknown'": { + "category": "Message", + "code": 90031 + }, + "Add parameter name": { + "category": "Message", + "code": 90034 + }, + "Declare private property '{0}'": { + "category": "Message", + "code": 90035 + }, + "Replace '{0}' with 'Promise<{1}>'": { + "category": "Message", + "code": 90036 + }, + "Fix all incorrect return type of an async functions": { + "category": "Message", + "code": 90037 + }, + "Declare private method '{0}'": { + "category": "Message", + "code": 90038 + }, + "Remove unused destructuring declaration": { + "category": "Message", + "code": 90039 + }, + "Remove unused declarations for: '{0}'": { + "category": "Message", + "code": 90041 + }, + "Declare a private field named '{0}'.": { + "category": "Message", + "code": 90053 + }, + "Includes imports of types referenced by '{0}'": { + "category": "Message", + "code": 90054 + }, + "Remove 'type' from import declaration from \"{0}\"": { + "category": "Message", + "code": 90055 + }, + "Remove 'type' from import of '{0}' from \"{1}\"": { + "category": "Message", + "code": 90056 + }, + "Add import from \"{0}\"": { + "category": "Message", + "code": 90057 + }, + "Update import from \"{0}\"": { + "category": "Message", + "code": 90058 + }, + "Export '{0}' from module '{1}'": { + "category": "Message", + "code": 90059 + }, + "Export all referenced locals": { + "category": "Message", + "code": 90060 + }, + "Update modifiers of '{0}'": { + "category": "Message", + "code": 90061 + }, + "Add annotation of type '{0}'": { + "category": "Message", + "code": 90062 + }, + "Add return type '{0}'": { + "category": "Message", + "code": 90063 + }, + "Extract base class to variable": { + "category": "Message", + "code": 90064 + }, + "Extract default export to variable": { + "category": "Message", + "code": 90065 + }, + "Extract binding expressions to variable": { + "category": "Message", + "code": 90066 + }, + "Add all missing type annotations": { + "category": "Message", + "code": 90067 + }, + "Add satisfies and an inline type assertion with '{0}'": { + "category": "Message", + "code": 90068 + }, + "Extract to variable and replace with '{0} as typeof {0}'": { + "category": "Message", + "code": 90069 + }, + "Mark array literal as const": { + "category": "Message", + "code": 90070 + }, + "Annotate types of properties expando function in a namespace": { + "category": "Message", + "code": 90071 + }, + + "Convert function to an ES2015 class": { + "category": "Message", + "code": 95001 + }, + "Convert '{0}' to '{1} in {0}'": { + "category": "Message", + "code": 95003 + }, + "Extract to {0} in {1}": { + "category": "Message", + "code": 95004 + }, + "Extract function": { + "category": "Message", + "code": 95005 + }, + "Extract constant": { + "category": "Message", + "code": 95006 + }, + "Extract to {0} in enclosing scope": { + "category": "Message", + "code": 95007 + }, + "Extract to {0} in {1} scope": { + "category": "Message", + "code": 95008 + }, + "Annotate with type from JSDoc": { + "category": "Message", + "code": 95009 + }, + "Infer type of '{0}' from usage": { + "category": "Message", + "code": 95011 + }, + "Infer parameter types from usage": { + "category": "Message", + "code": 95012 + }, + "Convert to default import": { + "category": "Message", + "code": 95013 + }, + "Install '{0}'": { + "category": "Message", + "code": 95014 + }, + "Replace import with '{0}'.": { + "category": "Message", + "code": 95015 + }, + "Use synthetic 'default' member.": { + "category": "Message", + "code": 95016 + }, + "Convert to ES module": { + "category": "Message", + "code": 95017 + }, + "Add 'undefined' type to property '{0}'": { + "category": "Message", + "code": 95018 + }, + "Add initializer to property '{0}'": { + "category": "Message", + "code": 95019 + }, + "Add definite assignment assertion to property '{0}'": { + "category": "Message", + "code": 95020 + }, + "Convert all type literals to mapped type": { + "category": "Message", + "code": 95021 + }, + "Add all missing members": { + "category": "Message", + "code": 95022 + }, + "Infer all types from usage": { + "category": "Message", + "code": 95023 + }, + "Delete all unused declarations": { + "category": "Message", + "code": 95024 + }, + "Prefix all unused declarations with '_' where possible": { + "category": "Message", + "code": 95025 + }, + "Fix all detected spelling errors": { + "category": "Message", + "code": 95026 + }, + "Add initializers to all uninitialized properties": { + "category": "Message", + "code": 95027 + }, + "Add definite assignment assertions to all uninitialized properties": { + "category": "Message", + "code": 95028 + }, + "Add undefined type to all uninitialized properties": { + "category": "Message", + "code": 95029 + }, + "Change all jsdoc-style types to TypeScript": { + "category": "Message", + "code": 95030 + }, + "Change all jsdoc-style types to TypeScript (and add '| undefined' to nullable types)": { + "category": "Message", + "code": 95031 + }, + "Implement all unimplemented interfaces": { + "category": "Message", + "code": 95032 + }, + "Install all missing types packages": { + "category": "Message", + "code": 95033 + }, + "Rewrite all as indexed access types": { + "category": "Message", + "code": 95034 + }, + "Convert all to default imports": { + "category": "Message", + "code": 95035 + }, + "Make all 'super()' calls the first statement in their constructor": { + "category": "Message", + "code": 95036 + }, + "Add qualifier to all unresolved variables matching a member name": { + "category": "Message", + "code": 95037 + }, + "Change all extended interfaces to 'implements'": { + "category": "Message", + "code": 95038 + }, + "Add all missing super calls": { + "category": "Message", + "code": 95039 + }, + "Implement all inherited abstract classes": { + "category": "Message", + "code": 95040 + }, + "Add all missing 'async' modifiers": { + "category": "Message", + "code": 95041 + }, + "Add '@ts-ignore' to all error messages": { + "category": "Message", + "code": 95042 + }, + "Annotate everything with types from JSDoc": { + "category": "Message", + "code": 95043 + }, + "Add '()' to all uncalled decorators": { + "category": "Message", + "code": 95044 + }, + "Convert all constructor functions to classes": { + "category": "Message", + "code": 95045 + }, + "Generate 'get' and 'set' accessors": { + "category": "Message", + "code": 95046 + }, + "Convert 'require' to 'import'": { + "category": "Message", + "code": 95047 + }, + "Convert all 'require' to 'import'": { + "category": "Message", + "code": 95048 + }, + "Move to a new file": { + "category": "Message", + "code": 95049 + }, + "Remove unreachable code": { + "category": "Message", + "code": 95050 + }, + "Remove all unreachable code": { + "category": "Message", + "code": 95051 + }, + "Add missing 'typeof'": { + "category": "Message", + "code": 95052 + }, + "Remove unused label": { + "category": "Message", + "code": 95053 + }, + "Remove all unused labels": { + "category": "Message", + "code": 95054 + }, + "Convert '{0}' to mapped object type": { + "category": "Message", + "code": 95055 + }, + "Convert namespace import to named imports": { + "category": "Message", + "code": 95056 + }, + "Convert named imports to namespace import": { + "category": "Message", + "code": 95057 + }, + "Add or remove braces in an arrow function": { + "category": "Message", + "code": 95058 + }, + "Add braces to arrow function": { + "category": "Message", + "code": 95059 + }, + "Remove braces from arrow function": { + "category": "Message", + "code": 95060 + }, + "Convert default export to named export": { + "category": "Message", + "code": 95061 + }, + "Convert named export to default export": { + "category": "Message", + "code": 95062 + }, + "Add missing enum member '{0}'": { + "category": "Message", + "code": 95063 + }, + "Add all missing imports": { + "category": "Message", + "code": 95064 + }, + "Convert to async function": { + "category": "Message", + "code": 95065 + }, + "Convert all to async functions": { + "category": "Message", + "code": 95066 + }, + "Add missing call parentheses": { + "category": "Message", + "code": 95067 + }, + "Add all missing call parentheses": { + "category": "Message", + "code": 95068 + }, + "Add 'unknown' conversion for non-overlapping types": { + "category": "Message", + "code": 95069 + }, + "Add 'unknown' to all conversions of non-overlapping types": { + "category": "Message", + "code": 95070 + }, + "Add missing 'new' operator to call": { + "category": "Message", + "code": 95071 + }, + "Add missing 'new' operator to all calls": { + "category": "Message", + "code": 95072 + }, + "Add names to all parameters without names": { + "category": "Message", + "code": 95073 + }, + "Enable the 'experimentalDecorators' option in your configuration file": { + "category": "Message", + "code": 95074 + }, + "Convert parameters to destructured object": { + "category": "Message", + "code": 95075 + }, + "Extract type": { + "category": "Message", + "code": 95077 + }, + "Extract to type alias": { + "category": "Message", + "code": 95078 + }, + "Extract to typedef": { + "category": "Message", + "code": 95079 + }, + "Infer 'this' type of '{0}' from usage": { + "category": "Message", + "code": 95080 + }, + "Add 'const' to unresolved variable": { + "category": "Message", + "code": 95081 + }, + "Add 'const' to all unresolved variables": { + "category": "Message", + "code": 95082 + }, + "Add 'await'": { + "category": "Message", + "code": 95083 + }, + "Add 'await' to initializer for '{0}'": { + "category": "Message", + "code": 95084 + }, + "Fix all expressions possibly missing 'await'": { + "category": "Message", + "code": 95085 + }, + "Remove unnecessary 'await'": { + "category": "Message", + "code": 95086 + }, + "Remove all unnecessary uses of 'await'": { + "category": "Message", + "code": 95087 + }, + "Enable the '--jsx' flag in your configuration file": { + "category": "Message", + "code": 95088 + }, + "Add 'await' to initializers": { + "category": "Message", + "code": 95089 + }, + "Extract to interface": { + "category": "Message", + "code": 95090 + }, + "Convert to a bigint numeric literal": { + "category": "Message", + "code": 95091 + }, + "Convert all to bigint numeric literals": { + "category": "Message", + "code": 95092 + }, + "Convert 'const' to 'let'": { + "category": "Message", + "code": 95093 + }, + "Prefix with 'declare'": { + "category": "Message", + "code": 95094 + }, + "Prefix all incorrect property declarations with 'declare'": { + "category": "Message", + "code": 95095 + }, + "Convert to template string": { + "category": "Message", + "code": 95096 + }, + "Add 'export {}' to make this file into a module": { + "category": "Message", + "code": 95097 + }, + "Set the 'target' option in your configuration file to '{0}'": { + "category": "Message", + "code": 95098 + }, + "Set the 'module' option in your configuration file to '{0}'": { + "category": "Message", + "code": 95099 + }, + "Convert invalid character to its html entity code": { + "category": "Message", + "code": 95100 + }, + "Convert all invalid characters to HTML entity code": { + "category": "Message", + "code": 95101 + }, + "Convert all 'const' to 'let'": { + "category": "Message", + "code": 95102 + }, + "Convert function expression '{0}' to arrow function": { + "category": "Message", + "code": 95105 + }, + "Convert function declaration '{0}' to arrow function": { + "category": "Message", + "code": 95106 + }, + "Fix all implicit-'this' errors": { + "category": "Message", + "code": 95107 + }, + "Wrap invalid character in an expression container": { + "category": "Message", + "code": 95108 + }, + "Wrap all invalid characters in an expression container": { + "category": "Message", + "code": 95109 + }, + "Visit https://aka.ms/tsconfig to read more about this file": { + "category": "Message", + "code": 95110 + }, + "Add a return statement": { + "category": "Message", + "code": 95111 + }, + "Remove braces from arrow function body": { + "category": "Message", + "code": 95112 + }, + "Wrap the following body with parentheses which should be an object literal": { + "category": "Message", + "code": 95113 + }, + "Add all missing return statement": { + "category": "Message", + "code": 95114 + }, + "Remove braces from all arrow function bodies with relevant issues": { + "category": "Message", + "code": 95115 + }, + "Wrap all object literal with parentheses": { + "category": "Message", + "code": 95116 + }, + "Move labeled tuple element modifiers to labels": { + "category": "Message", + "code": 95117 + }, + "Convert overload list to single signature": { + "category": "Message", + "code": 95118 + }, + "Generate 'get' and 'set' accessors for all overriding properties": { + "category": "Message", + "code": 95119 + }, + "Wrap in JSX fragment": { + "category": "Message", + "code": 95120 + }, + "Wrap all unparented JSX in JSX fragment": { + "category": "Message", + "code": 95121 + }, + "Convert arrow function or function expression": { + "category": "Message", + "code": 95122 + }, + "Convert to anonymous function": { + "category": "Message", + "code": 95123 + }, + "Convert to named function": { + "category": "Message", + "code": 95124 + }, + "Convert to arrow function": { + "category": "Message", + "code": 95125 + }, + "Remove parentheses": { + "category": "Message", + "code": 95126 + }, + "Could not find a containing arrow function": { + "category": "Message", + "code": 95127 + }, + "Containing function is not an arrow function": { + "category": "Message", + "code": 95128 + }, + "Could not find export statement": { + "category": "Message", + "code": 95129 + }, + "This file already has a default export": { + "category": "Message", + "code": 95130 + }, + "Could not find import clause": { + "category": "Message", + "code": 95131 + }, + "Could not find namespace import or named imports": { + "category": "Message", + "code": 95132 + }, + "Selection is not a valid type node": { + "category": "Message", + "code": 95133 + }, + "No type could be extracted from this type node": { + "category": "Message", + "code": 95134 + }, + "Could not find property for which to generate accessor": { + "category": "Message", + "code": 95135 + }, + "Name is not valid": { + "category": "Message", + "code": 95136 + }, + "Can only convert property with modifier": { + "category": "Message", + "code": 95137 + }, + "Switch each misused '{0}' to '{1}'": { + "category": "Message", + "code": 95138 + }, + "Convert to optional chain expression": { + "category": "Message", + "code": 95139 + }, + "Could not find convertible access expression": { + "category": "Message", + "code": 95140 + }, + "Could not find matching access expressions": { + "category": "Message", + "code": 95141 + }, + "Can only convert logical AND access chains": { + "category": "Message", + "code": 95142 + }, + "Add 'void' to Promise resolved without a value": { + "category": "Message", + "code": 95143 + }, + "Add 'void' to all Promises resolved without a value": { + "category": "Message", + "code": 95144 + }, + "Use element access for '{0}'": { + "category": "Message", + "code": 95145 + }, + "Use element access for all undeclared properties.": { + "category": "Message", + "code": 95146 + }, + "Delete all unused imports": { + "category": "Message", + "code": 95147 + }, + "Infer function return type": { + "category": "Message", + "code": 95148 + }, + "Return type must be inferred from a function": { + "category": "Message", + "code": 95149 + }, + "Could not determine function return type": { + "category": "Message", + "code": 95150 + }, + "Could not convert to arrow function": { + "category": "Message", + "code": 95151 + }, + "Could not convert to named function": { + "category": "Message", + "code": 95152 + }, + "Could not convert to anonymous function": { + "category": "Message", + "code": 95153 + }, + "Can only convert string concatenations and string literals": { + "category": "Message", + "code": 95154 + }, + "Selection is not a valid statement or statements": { + "category": "Message", + "code": 95155 + }, + "Add missing function declaration '{0}'": { + "category": "Message", + "code": 95156 + }, + "Add all missing function declarations": { + "category": "Message", + "code": 95157 + }, + "Method not implemented.": { + "category": "Message", + "code": 95158 + }, + "Function not implemented.": { + "category": "Message", + "code": 95159 + }, + "Add 'override' modifier": { + "category": "Message", + "code": 95160 + }, + "Remove 'override' modifier": { + "category": "Message", + "code": 95161 + }, + "Add all missing 'override' modifiers": { + "category": "Message", + "code": 95162 + }, + "Remove all unnecessary 'override' modifiers": { + "category": "Message", + "code": 95163 + }, + "Can only convert named export": { + "category": "Message", + "code": 95164 + }, + "Add missing properties": { + "category": "Message", + "code": 95165 + }, + "Add all missing properties": { + "category": "Message", + "code": 95166 + }, + "Add missing attributes": { + "category": "Message", + "code": 95167 + }, + "Add all missing attributes": { + "category": "Message", + "code": 95168 + }, + "Add 'undefined' to optional property type": { + "category": "Message", + "code": 95169 + }, + "Convert named imports to default import": { + "category": "Message", + "code": 95170 + }, + "Delete unused '@param' tag '{0}'": { + "category": "Message", + "code": 95171 + }, + "Delete all unused '@param' tags": { + "category": "Message", + "code": 95172 + }, + "Rename '@param' tag name '{0}' to '{1}'": { + "category": "Message", + "code": 95173 + }, + "Use `{0}`.": { + "category": "Message", + "code": 95174 + }, + "Use `Number.isNaN` in all conditions.": { + "category": "Message", + "code": 95175 + }, + "Convert typedef to TypeScript type.": { + "category": "Message", + "code": 95176 + }, + "Convert all typedef to TypeScript types.": { + "category": "Message", + "code": 95177 + }, + "Move to file": { + "category": "Message", + "code": 95178 + }, + "Cannot move to file, selected file is invalid": { + "category": "Message", + "code": 95179 + }, + "Use 'import type'": { + "category": "Message", + "code": 95180 + }, + "Use 'type {0}'": { + "category": "Message", + "code": 95181 + }, + "Fix all with type-only imports": { + "category": "Message", + "code": 95182 + }, + "Cannot move statements to the selected file": { + "category": "Message", + "code": 95183 + }, + "Inline variable": { + "category": "Message", + "code": 95184 + }, + "Could not find variable to inline.": { + "category": "Message", + "code": 95185 + }, + "Variables with multiple declarations cannot be inlined.": { + "category": "Message", + "code": 95186 + }, + "Add missing comma for object member completion '{0}'.": { + "category": "Message", + "code": 95187 + }, + "Add missing parameter to '{0}'": { + "category": "Message", + "code": 95188 + }, + "Add missing parameters to '{0}'": { + "category": "Message", + "code": 95189 + }, + "Add all missing parameters": { + "category": "Message", + "code": 95190 + }, + "Add optional parameter to '{0}'": { + "category": "Message", + "code": 95191 + }, + "Add optional parameters to '{0}'": { + "category": "Message", + "code": 95192 + }, + "Add all optional parameters": { + "category": "Message", + "code": 95193 + }, + "Wrap in parentheses": { + "category": "Message", + "code": 95194 + }, + "Wrap all invalid decorator expressions in parentheses": { + "category": "Message", + "code": 95195 + }, + "Add 'resolution-mode' import attribute": { + "category": "Message", + "code": 95196 + }, + "Add 'resolution-mode' import attribute to all type-only imports that need it": { + "category": "Message", + "code": 95197 + }, + + "No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer.": { + "category": "Error", + "code": 18004 + }, + "Classes may not have a field named 'constructor'.": { + "category": "Error", + "code": 18006 + }, + "JSX expressions may not use the comma operator. Did you mean to write an array?": { + "category": "Error", + "code": 18007 + }, + "Private identifiers cannot be used as parameters.": { + "category": "Error", + "code": 18009 + }, + "An accessibility modifier cannot be used with a private identifier.": { + "category": "Error", + "code": 18010 + }, + "The operand of a 'delete' operator cannot be a private identifier.": { + "category": "Error", + "code": 18011 + }, + "'#constructor' is a reserved word.": { + "category": "Error", + "code": 18012 + }, + "Property '{0}' is not accessible outside class '{1}' because it has a private identifier.": { + "category": "Error", + "code": 18013 + }, + "The property '{0}' cannot be accessed on type '{1}' within this class because it is shadowed by another private identifier with the same spelling.": { + "category": "Error", + "code": 18014 + }, + "Property '{0}' in type '{1}' refers to a different member that cannot be accessed from within type '{2}'.": { + "category": "Error", + "code": 18015 + }, + "Private identifiers are not allowed outside class bodies.": { + "category": "Error", + "code": 18016 + }, + "The shadowing declaration of '{0}' is defined here": { + "category": "Error", + "code": 18017 + }, + "The declaration of '{0}' that you probably intended to use is defined here": { + "category": "Error", + "code": 18018 + }, + "'{0}' modifier cannot be used with a private identifier.": { + "category": "Error", + "code": 18019 + }, + "An enum member cannot be named with a private identifier.": { + "category": "Error", + "code": 18024 + }, + "'#!' can only be used at the start of a file.": { + "category": "Error", + "code": 18026 + }, + "Compiler reserves name '{0}' when emitting private identifier downlevel.": { + "category": "Error", + "code": 18027 + }, + "Private identifiers are only available when targeting ECMAScript 2015 and higher.": { + "category": "Error", + "code": 18028 + }, + "Private identifiers are not allowed in variable declarations.": { + "category": "Error", + "code": 18029 + }, + "An optional chain cannot contain private identifiers.": { + "category": "Error", + "code": 18030 + }, + "The intersection '{0}' was reduced to 'never' because property '{1}' has conflicting types in some constituents.": { + "category": "Error", + "code": 18031 + }, + "The intersection '{0}' was reduced to 'never' because property '{1}' exists in multiple constituents and is private in some.": { + "category": "Error", + "code": 18032 + }, + "Type '{0}' is not assignable to type '{1}' as required for computed enum member values.": { + "category": "Error", + "code": 18033 + }, + "Specify the JSX fragment factory function to use when targeting 'react' JSX emit with 'jsxFactory' compiler option is specified, e.g. 'Fragment'.": { + "category": "Message", + "code": 18034 + }, + "Invalid value for 'jsxFragmentFactory'. '{0}' is not a valid identifier or qualified-name.": { + "category": "Error", + "code": 18035 + }, + "Class decorators can't be used with static private identifier. Consider removing the experimental decorator.": { + "category": "Error", + "code": 18036 + }, + "'await' expression cannot be used inside a class static block.": { + "category": "Error", + "code": 18037 + }, + "'for await' loops cannot be used inside a class static block.": { + "category": "Error", + "code": 18038 + }, + "Invalid use of '{0}'. It cannot be used inside a class static block.": { + "category": "Error", + "code": 18039 + }, + "A 'return' statement cannot be used inside a class static block.": { + "category": "Error", + "code": 18041 + }, + "'{0}' is a type and cannot be imported in JavaScript files. Use '{1}' in a JSDoc type annotation.": { + "category": "Error", + "code": 18042 + }, + "Types cannot appear in export declarations in JavaScript files.": { + "category": "Error", + "code": 18043 + }, + "'{0}' is automatically exported here.": { + "category": "Message", + "code": 18044 + }, + "Properties with the 'accessor' modifier are only available when targeting ECMAScript 2015 and higher.": { + "category": "Error", + "code": 18045 + }, + "'{0}' is of type 'unknown'.": { + "category": "Error", + "code": 18046 + }, + "'{0}' is possibly 'null'.": { + "category": "Error", + "code": 18047 + }, + "'{0}' is possibly 'undefined'.": { + "category": "Error", + "code": 18048 + }, + "'{0}' is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 18049 + }, + "The value '{0}' cannot be used here.": { + "category": "Error", + "code": 18050 + }, + "Compiler option '{0}' cannot be given an empty string.": { + "category": "Error", + "code": 18051 + }, + "Its type '{0}' is not a valid JSX element type.": { + "category": "Error", + "code": 18053 + }, + "'await using' statements cannot be used inside a class static block.": { + "category": "Error", + "code": 18054 + }, + "'{0}' has a string type, but must have syntactically recognizable string syntax when 'isolatedModules' is enabled.": { + "category": "Error", + "code": 18055 + }, + "Enum member following a non-literal numeric member must have an initializer when 'isolatedModules' is enabled.": { + "category": "Error", + "code": 18056 + }, + "String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.": { + "category": "Error", + "code": 18057 + }, + "Default imports are not allowed in a deferred import.": { + "category": "Error", + "code": 18058 + }, + "Named imports are not allowed in a deferred import.": { + "category": "Error", + "code": 18059 + }, + "Deferred imports are only supported when the '--module' flag is set to 'esnext' or 'preserve'.": { + "category": "Error", + "code": 18060 + }, + "'{0}' is not a valid meta-property for keyword 'import'. Did you mean 'meta' or 'defer'?": { + "category": "Error", + "code": 18061 + }, + "'import.defer' does not support optional invocation.": { + "category": "Error", + "code": 18062 + } +} diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 68133ac5f1e40..9ccb5bc2dc7a6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1,10823 +1,10826 @@ -import { - AccessorDeclaration, - addRange, - addRelatedInfo, - append, - ArrayBindingElement, - ArrayBindingPattern, - ArrayLiteralExpression, - ArrayTypeNode, - ArrowFunction, - AsExpression, - AssertionLevel, - AsteriskToken, - attachFileToDiagnostics, - AwaitExpression, - BaseNodeFactory, - BigIntLiteral, - BinaryExpression, - BinaryOperatorToken, - BindingElement, - BindingName, - BindingPattern, - Block, - BooleanLiteral, - BreakOrContinueStatement, - BreakStatement, - CallExpression, - CallSignatureDeclaration, - canHaveJSDoc, - canHaveModifiers, - CaseBlock, - CaseClause, - CaseOrDefaultClause, - CatchClause, - CharacterCodes, - ClassDeclaration, - ClassElement, - ClassExpression, - ClassLikeDeclaration, - ClassStaticBlockDeclaration, - CommaListExpression, - CommentDirective, - commentPragmas, - CommentRange, - ComputedPropertyName, - concatenate, - ConditionalExpression, - ConditionalTypeNode, - ConstructorDeclaration, - ConstructorTypeNode, - ConstructSignatureDeclaration, - containsParseError, - ContinueStatement, - convertToJson, - createDetachedDiagnostic, - createNodeFactory, - createScanner, - createTextChangeRange, - createTextSpanFromBounds, - Debug, - Decorator, - DefaultClause, - DeleteExpression, - Diagnostic, - DiagnosticArguments, - DiagnosticMessage, - Diagnostics, - DiagnosticWithDetachedLocation, - DoStatement, - DotDotDotToken, - ElementAccessExpression, - emptyArray, - emptyMap, - EndOfFileToken, - ensureScriptKind, - EntityName, - EnumDeclaration, - EnumMember, - ExclamationToken, - ExportAssignment, - ExportDeclaration, - ExportSpecifier, - Expression, - ExpressionStatement, - ExpressionWithTypeArguments, - Extension, - ExternalModuleReference, - fileExtensionIs, - findIndex, - firstOrUndefined, - forEach, - ForEachChildNodes, - ForInOrOfStatement, - ForInStatement, - ForOfStatement, - ForStatement, - FunctionDeclaration, - FunctionExpression, - FunctionOrConstructorTypeNode, - FunctionTypeNode, - GetAccessorDeclaration, - getAnyExtensionFromPath, - getBaseFileName, - getBinaryOperatorPrecedence, - getFullWidth, - getJSDocCommentRanges, - getLanguageVariant, - getLastChild, - getLeadingCommentRanges, - getSpellingSuggestion, - getTextOfNodeFromSourceText, - HasJSDoc, - hasJSDocNodes, - HasModifiers, - HeritageClause, - Identifier, - identity, - idText, - IfStatement, - ImportAttribute, - ImportAttributes, - ImportClause, - ImportDeclaration, - ImportEqualsDeclaration, - ImportOrExportSpecifier, - ImportPhaseModifierSyntaxKind, - ImportSpecifier, - ImportTypeAssertionContainer, - ImportTypeNode, - IndexedAccessTypeNode, - IndexSignatureDeclaration, - InferTypeNode, - InterfaceDeclaration, - IntersectionTypeNode, - isArray, - isAssignmentOperator, - isAsyncModifier, - isClassMemberModifier, - isExportAssignment, - isExportDeclaration, - isExportModifier, - isExpressionWithTypeArguments, - isExternalModuleReference, - isFunctionTypeNode, - isIdentifier as isIdentifierNode, - isIdentifierText, - isImportDeclaration, - isImportEqualsDeclaration, - isJSDocFunctionType, - isJSDocNullableType, - isJSDocReturnTag, - isJSDocTypeTag, - isJsxNamespacedName, - isJsxOpeningElement, - isJsxOpeningFragment, - isKeyword, - isKeywordOrPunctuation, - isLeftHandSideExpression, - isLiteralKind, - isMetaProperty, - isModifierKind, - isNonNullExpression, - isPrivateIdentifier, - isSetAccessorDeclaration, - isStringOrNumericLiteralLike, - isTaggedTemplateExpression, - isTemplateLiteralKind, - isTypeReferenceNode, - IterationStatement, - JSDoc, - JSDocAllType, - JSDocAugmentsTag, - JSDocAuthorTag, - JSDocCallbackTag, - JSDocClassTag, - JSDocComment, - JSDocDeprecatedTag, - JSDocEnumTag, - JSDocFunctionType, - JSDocImplementsTag, - JSDocImportTag, - JSDocLink, - JSDocLinkCode, - JSDocLinkPlain, - JSDocMemberName, - JSDocNameReference, - JSDocNamespaceDeclaration, - JSDocNonNullableType, - JSDocNullableType, - JSDocOptionalType, - JSDocOverloadTag, - JSDocOverrideTag, - JSDocParameterTag, - JSDocParsingMode, - JSDocPrivateTag, - JSDocPropertyLikeTag, - JSDocPropertyTag, - JSDocProtectedTag, - JSDocPublicTag, - JSDocReadonlyTag, - JSDocReturnTag, - JSDocSatisfiesTag, - JSDocSeeTag, - JSDocSignature, - JSDocSyntaxKind, - JSDocTag, - JSDocTemplateTag, - JSDocText, - JSDocThisTag, - JSDocThrowsTag, - JSDocTypedefTag, - JSDocTypeExpression, - JSDocTypeLiteral, - JSDocTypeTag, - JSDocUnknownTag, - JSDocUnknownType, - JSDocVariadicType, - JsonMinusNumericLiteral, - JsonObjectExpressionStatement, - JsonSourceFile, - JsxAttribute, - JsxAttributes, - JsxAttributeValue, - JsxChild, - JsxClosingElement, - JsxClosingFragment, - JsxElement, - JsxExpression, - JsxFragment, - JsxNamespacedName, - JsxOpeningElement, - JsxOpeningFragment, - JsxOpeningLikeElement, - JsxSelfClosingElement, - JsxSpreadAttribute, - JsxTagNameExpression, - JsxText, - JsxTokenSyntaxKind, - LabeledStatement, - LanguageVariant, - lastOrUndefined, - LeftHandSideExpression, - LiteralExpression, - LiteralLikeNode, - LiteralTypeNode, - map, - mapDefined, - MappedTypeNode, - MemberExpression, - MetaProperty, - MethodDeclaration, - MethodSignature, - MinusToken, - MissingDeclaration, - Modifier, - ModifierFlags, - ModifierLike, - modifiersToFlags, - ModuleBlock, - ModuleDeclaration, - ModuleExportName, - ModuleKind, - Mutable, - NamedExportBindings, - NamedExports, - NamedImports, - NamedImportsOrExports, - NamedTupleMember, - NamespaceDeclaration, - NamespaceExport, - NamespaceExportDeclaration, - NamespaceImport, - NewExpression, - Node, - NodeArray, - NodeFactory, - NodeFactoryFlags, - NodeFlags, - nodeIsMissing, - nodeIsPresent, - NonNullExpression, - noop, - normalizePath, - NoSubstitutionTemplateLiteral, - NullLiteral, - NumericLiteral, - objectAllocator, - ObjectBindingPattern, - ObjectLiteralElementLike, - ObjectLiteralExpression, - OperatorPrecedence, - OptionalTypeNode, - PackageJsonInfo, - ParameterDeclaration, - ParenthesizedExpression, - ParenthesizedTypeNode, - PartiallyEmittedExpression, - PlusToken, - PostfixUnaryExpression, - PostfixUnaryOperator, - PragmaContext, - PragmaDefinition, - PragmaKindFlags, - PragmaMap, - PragmaPseudoMap, - PragmaPseudoMapEntry, - PrefixUnaryExpression, - PrefixUnaryOperator, - PrimaryExpression, - PrivateIdentifier, - PropertyAccessEntityNameExpression, - PropertyAccessExpression, - PropertyAssignment, - PropertyDeclaration, - PropertyName, - PropertySignature, - PunctuationOrKeywordSyntaxKind, - PunctuationSyntaxKind, - QualifiedName, - QuestionDotToken, - QuestionToken, - ReadonlyKeyword, - ReadonlyPragmaMap, - ResolutionMode, - RestTypeNode, - ReturnStatement, - SatisfiesExpression, - ScriptKind, - ScriptTarget, - SetAccessorDeclaration, - setParent, - setParentRecursive, - setTextRange, - setTextRangePos, - setTextRangePosEnd, - setTextRangePosWidth, - ShorthandPropertyAssignment, - skipTrivia, - some, - SourceFile, - SpreadAssignment, - SpreadElement, - startsWith, - Statement, - StringLiteral, - supportedDeclarationExtensions, - SwitchStatement, - SyntaxKind, - TaggedTemplateExpression, - TemplateExpression, - TemplateHead, - TemplateLiteralToken, - TemplateLiteralTypeNode, - TemplateLiteralTypeSpan, - TemplateMiddle, - TemplateSpan, - TemplateTail, - TextChangeRange, - textChangeRangeIsUnchanged, - textChangeRangeNewSpan, - TextRange, - textSpanEnd, - textToKeywordObj, - ThisExpression, - ThisTypeNode, - ThrowStatement, - toArray, - Token, - TokenFlags, - tokenIsIdentifierOrKeyword, - tokenIsIdentifierOrKeywordOrGreaterThan, - tokenToString, - tracing, - transferSourceFileChildren, - TransformFlags, - TryStatement, - TupleTypeNode, - TypeAliasDeclaration, - TypeAssertion, - TypeElement, - TypeLiteralNode, - TypeNode, - TypeOfExpression, - TypeOperatorNode, - TypeParameterDeclaration, - TypePredicateNode, - TypeQueryNode, - TypeReferenceNode, - UnaryExpression, - unescapeLeadingUnderscores, - UnionOrIntersectionTypeNode, - UnionTypeNode, - unsetNodeChildren, - UpdateExpression, - VariableDeclaration, - VariableDeclarationList, - VariableStatement, - VoidExpression, - WhileStatement, - WithStatement, - YieldExpression, -} from "./_namespaces/ts.js"; -import * as performance from "./_namespaces/ts.performance.js"; - -const enum SignatureFlags { - None = 0, - Yield = 1 << 0, - Await = 1 << 1, - Type = 1 << 2, - IgnoreMissingOpenBrace = 1 << 4, - JSDoc = 1 << 5, -} - -const enum SpeculationKind { - TryParse, - Lookahead, - Reparse, -} - -let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; -let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; -let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Node; -let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => Node; -let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => Node; - -/** - * NOTE: You should not use this, it is only exported to support `createNode` in `~/src/deprecatedCompat/deprecations.ts`. - * - * @internal - * @knipignore - */ -export const parseBaseNodeFactory: BaseNodeFactory = { - createBaseSourceFileNode: kind => new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, -1, -1), - createBaseIdentifierNode: kind => new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, -1, -1), - createBasePrivateIdentifierNode: kind => new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, -1, -1), - createBaseTokenNode: kind => new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, -1, -1), - createBaseNode: kind => new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, -1, -1), -}; - -/** @internal */ -export const parseNodeFactory: NodeFactory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); - -function visitNode(cbNode: (node: Node) => T, node: Node | undefined): T | undefined { - return node && cbNode(node); -} - -function visitNodes(cbNode: (node: Node) => T, cbNodes: ((node: NodeArray) => T | undefined) | undefined, nodes: NodeArray | undefined): T | undefined { - if (nodes) { - if (cbNodes) { - return cbNodes(nodes); - } - for (const node of nodes) { - const result = cbNode(node); - if (result) { - return result; - } - } - } -} - -/** @internal */ -export function isJSDocLikeText(text: string, start: number): boolean { - return text.charCodeAt(start + 1) === CharacterCodes.asterisk && - text.charCodeAt(start + 2) === CharacterCodes.asterisk && - text.charCodeAt(start + 3) !== CharacterCodes.slash; -} - -/** @internal */ -export function isFileProbablyExternalModule(sourceFile: SourceFile): Node | undefined { - // Try to use the first top-level import/export when available, then - // fall back to looking for an 'import.meta' somewhere in the tree if necessary. - return forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || - getImportMetaIfNecessary(sourceFile); -} - -function isAnExternalModuleIndicatorNode(node: Node) { - return canHaveModifiers(node) && hasModifierOfKind(node, SyntaxKind.ExportKeyword) - || isImportEqualsDeclaration(node) && isExternalModuleReference(node.moduleReference) - || isImportDeclaration(node) - || isExportAssignment(node) - || isExportDeclaration(node) ? node : undefined; -} - -function getImportMetaIfNecessary(sourceFile: SourceFile) { - return sourceFile.flags & NodeFlags.PossiblyContainsImportMeta ? - walkTreeForImportMeta(sourceFile) : - undefined; -} - -function walkTreeForImportMeta(node: Node): Node | undefined { - return isImportMeta(node) ? node : forEachChild(node, walkTreeForImportMeta); -} - -/** Do not use hasModifier inside the parser; it relies on parent pointers. Use this instead. */ -function hasModifierOfKind(node: HasModifiers, kind: SyntaxKind) { - return some(node.modifiers, m => m.kind === kind); -} - -function isImportMeta(node: Node): boolean { - return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta"; -} - -type ForEachChildFunction = (node: TNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined) => T | undefined; -type ForEachChildTable = { [TNode in ForEachChildNodes as TNode["kind"]]: ForEachChildFunction; }; -const forEachChildTable: ForEachChildTable = { - [SyntaxKind.QualifiedName]: function forEachChildInQualifiedName(node: QualifiedName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.left) || - visitNode(cbNode, node.right); - }, - [SyntaxKind.TypeParameter]: function forEachChildInTypeParameter(node: TypeParameterDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.constraint) || - visitNode(cbNode, node.default) || - visitNode(cbNode, node.expression); - }, - [SyntaxKind.ShorthandPropertyAssignment]: function forEachChildInShorthandPropertyAssignment(node: ShorthandPropertyAssignment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.exclamationToken) || - visitNode(cbNode, node.equalsToken) || - visitNode(cbNode, node.objectAssignmentInitializer); - }, - [SyntaxKind.SpreadAssignment]: function forEachChildInSpreadAssignment(node: SpreadAssignment, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.Parameter]: function forEachChildInParameter(node: ParameterDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.dotDotDotToken) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.PropertyDeclaration]: function forEachChildInPropertyDeclaration(node: PropertyDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.exclamationToken) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.PropertySignature]: function forEachChildInPropertySignature(node: PropertySignature, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.PropertyAssignment]: function forEachChildInPropertyAssignment(node: PropertyAssignment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.exclamationToken) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.VariableDeclaration]: function forEachChildInVariableDeclaration(node: VariableDeclaration, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name) || - visitNode(cbNode, node.exclamationToken) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.BindingElement]: function forEachChildInBindingElement(node: BindingElement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.dotDotDotToken) || - visitNode(cbNode, node.propertyName) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.IndexSignature]: function forEachChildInIndexSignature(node: IndexSignatureDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.ConstructorType]: function forEachChildInConstructorType(node: ConstructorTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.FunctionType]: function forEachChildInFunctionType(node: FunctionTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.CallSignature]: forEachChildInCallOrConstructSignature, - [SyntaxKind.ConstructSignature]: forEachChildInCallOrConstructSignature, - [SyntaxKind.MethodDeclaration]: function forEachChildInMethodDeclaration(node: MethodDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.asteriskToken) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.exclamationToken) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.MethodSignature]: function forEachChildInMethodSignature(node: MethodSignature, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.Constructor]: function forEachChildInConstructor(node: ConstructorDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.GetAccessor]: function forEachChildInGetAccessor(node: GetAccessorDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.SetAccessor]: function forEachChildInSetAccessor(node: SetAccessorDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.FunctionDeclaration]: function forEachChildInFunctionDeclaration(node: FunctionDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.asteriskToken) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.FunctionExpression]: function forEachChildInFunctionExpression(node: FunctionExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.asteriskToken) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.ArrowFunction]: function forEachChildInArrowFunction(node: ArrowFunction, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type) || - visitNode(cbNode, node.equalsGreaterThanToken) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.ClassStaticBlockDeclaration]: function forEachChildInClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.TypeReference]: function forEachChildInTypeReference(node: TypeReferenceNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.typeName) || - visitNodes(cbNode, cbNodes, node.typeArguments); - }, - [SyntaxKind.TypePredicate]: function forEachChildInTypePredicate(node: TypePredicateNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.assertsModifier) || - visitNode(cbNode, node.parameterName) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.TypeQuery]: function forEachChildInTypeQuery(node: TypeQueryNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.exprName) || - visitNodes(cbNode, cbNodes, node.typeArguments); - }, - [SyntaxKind.TypeLiteral]: function forEachChildInTypeLiteral(node: TypeLiteralNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.members); - }, - [SyntaxKind.ArrayType]: function forEachChildInArrayType(node: ArrayTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.elementType); - }, - [SyntaxKind.TupleType]: function forEachChildInTupleType(node: TupleTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.elements); - }, - [SyntaxKind.UnionType]: forEachChildInUnionOrIntersectionType, - [SyntaxKind.IntersectionType]: forEachChildInUnionOrIntersectionType, - [SyntaxKind.ConditionalType]: function forEachChildInConditionalType(node: ConditionalTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.checkType) || - visitNode(cbNode, node.extendsType) || - visitNode(cbNode, node.trueType) || - visitNode(cbNode, node.falseType); - }, - [SyntaxKind.InferType]: function forEachChildInInferType(node: InferTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.typeParameter); - }, - [SyntaxKind.ImportType]: function forEachChildInImportType(node: ImportTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.argument) || - visitNode(cbNode, node.attributes) || - visitNode(cbNode, node.qualifier) || - visitNodes(cbNode, cbNodes, node.typeArguments); - }, - [SyntaxKind.ImportTypeAssertionContainer]: function forEachChildInImportTypeAssertionContainer(node: ImportTypeAssertionContainer, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.assertClause); - }, - [SyntaxKind.ParenthesizedType]: forEachChildInParenthesizedTypeOrTypeOperator, - [SyntaxKind.TypeOperator]: forEachChildInParenthesizedTypeOrTypeOperator, - [SyntaxKind.IndexedAccessType]: function forEachChildInIndexedAccessType(node: IndexedAccessTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.objectType) || - visitNode(cbNode, node.indexType); - }, - [SyntaxKind.MappedType]: function forEachChildInMappedType(node: MappedTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.readonlyToken) || - visitNode(cbNode, node.typeParameter) || - visitNode(cbNode, node.nameType) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.type) || - visitNodes(cbNode, cbNodes, node.members); - }, - [SyntaxKind.LiteralType]: function forEachChildInLiteralType(node: LiteralTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.literal); - }, - [SyntaxKind.NamedTupleMember]: function forEachChildInNamedTupleMember(node: NamedTupleMember, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.dotDotDotToken) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.ObjectBindingPattern]: forEachChildInObjectOrArrayBindingPattern, - [SyntaxKind.ArrayBindingPattern]: forEachChildInObjectOrArrayBindingPattern, - [SyntaxKind.ArrayLiteralExpression]: function forEachChildInArrayLiteralExpression(node: ArrayLiteralExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.elements); - }, - [SyntaxKind.ObjectLiteralExpression]: function forEachChildInObjectLiteralExpression(node: ObjectLiteralExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.properties); - }, - [SyntaxKind.PropertyAccessExpression]: function forEachChildInPropertyAccessExpression(node: PropertyAccessExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.questionDotToken) || - visitNode(cbNode, node.name); - }, - [SyntaxKind.ElementAccessExpression]: function forEachChildInElementAccessExpression(node: ElementAccessExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.questionDotToken) || - visitNode(cbNode, node.argumentExpression); - }, - [SyntaxKind.CallExpression]: forEachChildInCallOrNewExpression, - [SyntaxKind.NewExpression]: forEachChildInCallOrNewExpression, - [SyntaxKind.TaggedTemplateExpression]: function forEachChildInTaggedTemplateExpression(node: TaggedTemplateExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tag) || - visitNode(cbNode, node.questionDotToken) || - visitNodes(cbNode, cbNodes, node.typeArguments) || - visitNode(cbNode, node.template); - }, - [SyntaxKind.TypeAssertionExpression]: function forEachChildInTypeAssertionExpression(node: TypeAssertion, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.type) || - visitNode(cbNode, node.expression); - }, - [SyntaxKind.ParenthesizedExpression]: function forEachChildInParenthesizedExpression(node: ParenthesizedExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.DeleteExpression]: function forEachChildInDeleteExpression(node: DeleteExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.TypeOfExpression]: function forEachChildInTypeOfExpression(node: TypeOfExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.VoidExpression]: function forEachChildInVoidExpression(node: VoidExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.PrefixUnaryExpression]: function forEachChildInPrefixUnaryExpression(node: PrefixUnaryExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.operand); - }, - [SyntaxKind.YieldExpression]: function forEachChildInYieldExpression(node: YieldExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.asteriskToken) || - visitNode(cbNode, node.expression); - }, - [SyntaxKind.AwaitExpression]: function forEachChildInAwaitExpression(node: AwaitExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.PostfixUnaryExpression]: function forEachChildInPostfixUnaryExpression(node: PostfixUnaryExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.operand); - }, - [SyntaxKind.BinaryExpression]: function forEachChildInBinaryExpression(node: BinaryExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.left) || - visitNode(cbNode, node.operatorToken) || - visitNode(cbNode, node.right); - }, - [SyntaxKind.AsExpression]: function forEachChildInAsExpression(node: AsExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.NonNullExpression]: function forEachChildInNonNullExpression(node: NonNullExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.SatisfiesExpression]: function forEachChildInSatisfiesExpression(node: SatisfiesExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || visitNode(cbNode, node.type); - }, - [SyntaxKind.MetaProperty]: function forEachChildInMetaProperty(node: MetaProperty, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name); - }, - [SyntaxKind.ConditionalExpression]: function forEachChildInConditionalExpression(node: ConditionalExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.condition) || - visitNode(cbNode, node.questionToken) || - visitNode(cbNode, node.whenTrue) || - visitNode(cbNode, node.colonToken) || - visitNode(cbNode, node.whenFalse); - }, - [SyntaxKind.SpreadElement]: function forEachChildInSpreadElement(node: SpreadElement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.Block]: forEachChildInBlock, - [SyntaxKind.ModuleBlock]: forEachChildInBlock, - [SyntaxKind.SourceFile]: function forEachChildInSourceFile(node: SourceFile, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.statements) || - visitNode(cbNode, node.endOfFileToken); - }, - [SyntaxKind.VariableStatement]: function forEachChildInVariableStatement(node: VariableStatement, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.declarationList); - }, - [SyntaxKind.VariableDeclarationList]: function forEachChildInVariableDeclarationList(node: VariableDeclarationList, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.declarations); - }, - [SyntaxKind.ExpressionStatement]: function forEachChildInExpressionStatement(node: ExpressionStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.IfStatement]: function forEachChildInIfStatement(node: IfStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.thenStatement) || - visitNode(cbNode, node.elseStatement); - }, - [SyntaxKind.DoStatement]: function forEachChildInDoStatement(node: DoStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.statement) || - visitNode(cbNode, node.expression); - }, - [SyntaxKind.WhileStatement]: function forEachChildInWhileStatement(node: WhileStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.statement); - }, - [SyntaxKind.ForStatement]: function forEachChildInForStatement(node: ForStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.initializer) || - visitNode(cbNode, node.condition) || - visitNode(cbNode, node.incrementor) || - visitNode(cbNode, node.statement); - }, - [SyntaxKind.ForInStatement]: function forEachChildInForInStatement(node: ForInStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.initializer) || - visitNode(cbNode, node.expression) || - visitNode(cbNode, node.statement); - }, - [SyntaxKind.ForOfStatement]: function forEachChildInForOfStatement(node: ForOfStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.awaitModifier) || - visitNode(cbNode, node.initializer) || - visitNode(cbNode, node.expression) || - visitNode(cbNode, node.statement); - }, - [SyntaxKind.ContinueStatement]: forEachChildInContinueOrBreakStatement, - [SyntaxKind.BreakStatement]: forEachChildInContinueOrBreakStatement, - [SyntaxKind.ReturnStatement]: function forEachChildInReturnStatement(node: ReturnStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.WithStatement]: function forEachChildInWithStatement(node: WithStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.statement); - }, - [SyntaxKind.SwitchStatement]: function forEachChildInSwitchStatement(node: SwitchStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.caseBlock); - }, - [SyntaxKind.CaseBlock]: function forEachChildInCaseBlock(node: CaseBlock, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.clauses); - }, - [SyntaxKind.CaseClause]: function forEachChildInCaseClause(node: CaseClause, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNodes(cbNode, cbNodes, node.statements); - }, - [SyntaxKind.DefaultClause]: function forEachChildInDefaultClause(node: DefaultClause, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.statements); - }, - [SyntaxKind.LabeledStatement]: function forEachChildInLabeledStatement(node: LabeledStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.label) || - visitNode(cbNode, node.statement); - }, - [SyntaxKind.ThrowStatement]: function forEachChildInThrowStatement(node: ThrowStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.TryStatement]: function forEachChildInTryStatement(node: TryStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tryBlock) || - visitNode(cbNode, node.catchClause) || - visitNode(cbNode, node.finallyBlock); - }, - [SyntaxKind.CatchClause]: function forEachChildInCatchClause(node: CatchClause, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.variableDeclaration) || - visitNode(cbNode, node.block); - }, - [SyntaxKind.Decorator]: function forEachChildInDecorator(node: Decorator, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.ClassDeclaration]: forEachChildInClassDeclarationOrExpression, - [SyntaxKind.ClassExpression]: forEachChildInClassDeclarationOrExpression, - [SyntaxKind.InterfaceDeclaration]: function forEachChildInInterfaceDeclaration(node: InterfaceDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.heritageClauses) || - visitNodes(cbNode, cbNodes, node.members); - }, - [SyntaxKind.TypeAliasDeclaration]: function forEachChildInTypeAliasDeclaration(node: TypeAliasDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.EnumDeclaration]: function forEachChildInEnumDeclaration(node: EnumDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.members); - }, - [SyntaxKind.EnumMember]: function forEachChildInEnumMember(node: EnumMember, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.ModuleDeclaration]: function forEachChildInModuleDeclaration(node: ModuleDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.body); - }, - [SyntaxKind.ImportEqualsDeclaration]: function forEachChildInImportEqualsDeclaration(node: ImportEqualsDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNode(cbNode, node.moduleReference); - }, - [SyntaxKind.ImportDeclaration]: function forEachChildInImportDeclaration(node: ImportDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.importClause) || - visitNode(cbNode, node.moduleSpecifier) || - visitNode(cbNode, node.attributes); - }, - [SyntaxKind.ImportClause]: function forEachChildInImportClause(node: ImportClause, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name) || - visitNode(cbNode, node.namedBindings); - }, - [SyntaxKind.ImportAttributes]: function forEachChildInImportAttributes(node: ImportAttributes, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.elements); - }, - [SyntaxKind.ImportAttribute]: function forEachChildInImportAttribute(node: ImportAttribute, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name) || - visitNode(cbNode, node.value); - }, - [SyntaxKind.NamespaceExportDeclaration]: function forEachChildInNamespaceExportDeclaration(node: NamespaceExportDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name); - }, - [SyntaxKind.NamespaceImport]: function forEachChildInNamespaceImport(node: NamespaceImport, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name); - }, - [SyntaxKind.NamespaceExport]: function forEachChildInNamespaceExport(node: NamespaceExport, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name); - }, - [SyntaxKind.NamedImports]: forEachChildInNamedImportsOrExports, - [SyntaxKind.NamedExports]: forEachChildInNamedImportsOrExports, - [SyntaxKind.ExportDeclaration]: function forEachChildInExportDeclaration(node: ExportDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.exportClause) || - visitNode(cbNode, node.moduleSpecifier) || - visitNode(cbNode, node.attributes); - }, - [SyntaxKind.ImportSpecifier]: forEachChildInImportOrExportSpecifier, - [SyntaxKind.ExportSpecifier]: forEachChildInImportOrExportSpecifier, - [SyntaxKind.ExportAssignment]: function forEachChildInExportAssignment(node: ExportAssignment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.expression); - }, - [SyntaxKind.TemplateExpression]: function forEachChildInTemplateExpression(node: TemplateExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.head) || - visitNodes(cbNode, cbNodes, node.templateSpans); - }, - [SyntaxKind.TemplateSpan]: function forEachChildInTemplateSpan(node: TemplateSpan, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNode(cbNode, node.literal); - }, - [SyntaxKind.TemplateLiteralType]: function forEachChildInTemplateLiteralType(node: TemplateLiteralTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.head) || - visitNodes(cbNode, cbNodes, node.templateSpans); - }, - [SyntaxKind.TemplateLiteralTypeSpan]: function forEachChildInTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.type) || - visitNode(cbNode, node.literal); - }, - [SyntaxKind.ComputedPropertyName]: function forEachChildInComputedPropertyName(node: ComputedPropertyName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.HeritageClause]: function forEachChildInHeritageClause(node: HeritageClause, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.types); - }, - [SyntaxKind.ExpressionWithTypeArguments]: function forEachChildInExpressionWithTypeArguments(node: ExpressionWithTypeArguments, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - visitNodes(cbNode, cbNodes, node.typeArguments); - }, - [SyntaxKind.ExternalModuleReference]: function forEachChildInExternalModuleReference(node: ExternalModuleReference, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.MissingDeclaration]: function forEachChildInMissingDeclaration(node: MissingDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers); - }, - [SyntaxKind.CommaListExpression]: function forEachChildInCommaListExpression(node: CommaListExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.elements); - }, - [SyntaxKind.JsxElement]: function forEachChildInJsxElement(node: JsxElement, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.openingElement) || - visitNodes(cbNode, cbNodes, node.children) || - visitNode(cbNode, node.closingElement); - }, - [SyntaxKind.JsxFragment]: function forEachChildInJsxFragment(node: JsxFragment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.openingFragment) || - visitNodes(cbNode, cbNodes, node.children) || - visitNode(cbNode, node.closingFragment); - }, - [SyntaxKind.JsxSelfClosingElement]: forEachChildInJsxOpeningOrSelfClosingElement, - [SyntaxKind.JsxOpeningElement]: forEachChildInJsxOpeningOrSelfClosingElement, - [SyntaxKind.JsxAttributes]: function forEachChildInJsxAttributes(node: JsxAttributes, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.properties); - }, - [SyntaxKind.JsxAttribute]: function forEachChildInJsxAttribute(node: JsxAttribute, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name) || - visitNode(cbNode, node.initializer); - }, - [SyntaxKind.JsxSpreadAttribute]: function forEachChildInJsxSpreadAttribute(node: JsxSpreadAttribute, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); - }, - [SyntaxKind.JsxExpression]: function forEachChildInJsxExpression(node: JsxExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.dotDotDotToken) || - visitNode(cbNode, node.expression); - }, - [SyntaxKind.JsxClosingElement]: function forEachChildInJsxClosingElement(node: JsxClosingElement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName); - }, - [SyntaxKind.JsxNamespacedName]: function forEachChildInJsxNamespacedName(node: JsxNamespacedName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.namespace) || - visitNode(cbNode, node.name); - }, - [SyntaxKind.OptionalType]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.RestType]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.JSDocTypeExpression]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.JSDocNonNullableType]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.JSDocNullableType]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.JSDocOptionalType]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.JSDocVariadicType]: forEachChildInOptionalRestOrJSDocParameterModifier, - [SyntaxKind.JSDocFunctionType]: function forEachChildInJSDocFunctionType(node: JSDocFunctionType, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.JSDoc]: function forEachChildInJSDoc(node: JSDoc, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)) - || visitNodes(cbNode, cbNodes, node.tags); - }, - [SyntaxKind.JSDocSeeTag]: function forEachChildInJSDocSeeTag(node: JSDocSeeTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNode(cbNode, node.name) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); - }, - [SyntaxKind.JSDocNameReference]: function forEachChildInJSDocNameReference(node: JSDocNameReference, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name); - }, - [SyntaxKind.JSDocMemberName]: function forEachChildInJSDocMemberName(node: JSDocMemberName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.left) || - visitNode(cbNode, node.right); - }, - [SyntaxKind.JSDocParameterTag]: forEachChildInJSDocParameterOrPropertyTag, - [SyntaxKind.JSDocPropertyTag]: forEachChildInJSDocParameterOrPropertyTag, - [SyntaxKind.JSDocAuthorTag]: function forEachChildInJSDocAuthorTag(node: JSDocAuthorTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); - }, - [SyntaxKind.JSDocImplementsTag]: function forEachChildInJSDocImplementsTag(node: JSDocImplementsTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNode(cbNode, node.class) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); - }, - [SyntaxKind.JSDocAugmentsTag]: function forEachChildInJSDocAugmentsTag(node: JSDocAugmentsTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNode(cbNode, node.class) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); - }, - [SyntaxKind.JSDocTemplateTag]: function forEachChildInJSDocTemplateTag(node: JSDocTemplateTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNode(cbNode, node.constraint) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); - }, - [SyntaxKind.JSDocTypedefTag]: function forEachChildInJSDocTypedefTag(node: JSDocTypedefTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - (node.typeExpression && - node.typeExpression.kind === SyntaxKind.JSDocTypeExpression - ? visitNode(cbNode, node.typeExpression) || - visitNode(cbNode, node.fullName) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)) - : visitNode(cbNode, node.fullName) || - visitNode(cbNode, node.typeExpression) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment))); - }, - [SyntaxKind.JSDocCallbackTag]: function forEachChildInJSDocCallbackTag(node: JSDocCallbackTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNode(cbNode, node.fullName) || - visitNode(cbNode, node.typeExpression) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); - }, - [SyntaxKind.JSDocReturnTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocTypeTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocThisTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocEnumTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocSatisfiesTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocThrowsTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocOverloadTag]: forEachChildInJSDocTypeLikeTag, - [SyntaxKind.JSDocSignature]: function forEachChildInJSDocSignature(node: JSDocSignature, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return forEach(node.typeParameters, cbNode) || - forEach(node.parameters, cbNode) || - visitNode(cbNode, node.type); - }, - [SyntaxKind.JSDocLink]: forEachChildInJSDocLinkCodeOrPlain, - [SyntaxKind.JSDocLinkCode]: forEachChildInJSDocLinkCodeOrPlain, - [SyntaxKind.JSDocLinkPlain]: forEachChildInJSDocLinkCodeOrPlain, - [SyntaxKind.JSDocTypeLiteral]: function forEachChildInJSDocTypeLiteral(node: JSDocTypeLiteral, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return forEach(node.jsDocPropertyTags, cbNode); - }, - [SyntaxKind.JSDocTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocClassTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocPublicTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocPrivateTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocProtectedTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocReadonlyTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocDeprecatedTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocOverrideTag]: forEachChildInJSDocTag, - [SyntaxKind.JSDocImportTag]: forEachChildInJSDocImportTag, - [SyntaxKind.PartiallyEmittedExpression]: forEachChildInPartiallyEmittedExpression, -}; - -// shared - -function forEachChildInCallOrConstructSignature(node: CallSignatureDeclaration | ConstructSignatureDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.parameters) || - visitNode(cbNode, node.type); -} - -function forEachChildInUnionOrIntersectionType(node: UnionTypeNode | IntersectionTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.types); -} - -function forEachChildInParenthesizedTypeOrTypeOperator(node: ParenthesizedTypeNode | TypeOperatorNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.type); -} - -function forEachChildInObjectOrArrayBindingPattern(node: BindingPattern, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.elements); -} - -function forEachChildInCallOrNewExpression(node: CallExpression | NewExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression) || - // TODO: should we separate these branches out? - visitNode(cbNode, (node as CallExpression).questionDotToken) || - visitNodes(cbNode, cbNodes, node.typeArguments) || - visitNodes(cbNode, cbNodes, node.arguments); -} - -function forEachChildInBlock(node: Block | ModuleBlock, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.statements); -} - -function forEachChildInContinueOrBreakStatement(node: ContinueStatement | BreakStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.label); -} - -function forEachChildInClassDeclarationOrExpression(node: ClassDeclaration | ClassExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.modifiers) || - visitNode(cbNode, node.name) || - visitNodes(cbNode, cbNodes, node.typeParameters) || - visitNodes(cbNode, cbNodes, node.heritageClauses) || - visitNodes(cbNode, cbNodes, node.members); -} - -function forEachChildInNamedImportsOrExports(node: NamedImports | NamedExports, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNodes(cbNode, cbNodes, node.elements); -} - -function forEachChildInImportOrExportSpecifier(node: ImportSpecifier | ExportSpecifier, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.propertyName) || - visitNode(cbNode, node.name); -} - -function forEachChildInJsxOpeningOrSelfClosingElement(node: JsxOpeningLikeElement, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNodes(cbNode, cbNodes, node.typeArguments) || - visitNode(cbNode, node.attributes); -} - -function forEachChildInOptionalRestOrJSDocParameterModifier(node: OptionalTypeNode | RestTypeNode | JSDocTypeExpression | JSDocNullableType | JSDocNonNullableType | JSDocOptionalType | JSDocVariadicType, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.type); -} - -function forEachChildInJSDocParameterOrPropertyTag(node: JSDocParameterTag | JSDocPropertyTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - (node.isNameFirst - ? visitNode(cbNode, node.name) || visitNode(cbNode, node.typeExpression) - : visitNode(cbNode, node.typeExpression) || visitNode(cbNode, node.name)) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); -} - -function forEachChildInJSDocTypeLikeTag(node: JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag | JSDocThrowsTag | JSDocOverloadTag | JSDocSatisfiesTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) || - visitNode(cbNode, node.typeExpression) || - (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); -} - -function forEachChildInJSDocLinkCodeOrPlain(node: JSDocLink | JSDocLinkCode | JSDocLinkPlain, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name); -} - -function forEachChildInJSDocTag(node: JSDocUnknownTag | JSDocClassTag | JSDocPublicTag | JSDocPrivateTag | JSDocProtectedTag | JSDocReadonlyTag | JSDocDeprecatedTag | JSDocOverrideTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) - || (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); -} - -function forEachChildInJSDocImportTag(node: JSDocImportTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.tagName) - || visitNode(cbNode, node.importClause) - || visitNode(cbNode, node.moduleSpecifier) - || visitNode(cbNode, node.attributes) - || (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); -} - -function forEachChildInPartiallyEmittedExpression(node: PartiallyEmittedExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.expression); -} - -/** - * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes - * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, - * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns - * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. - * - * @param node a given node to visit its children - * @param cbNode a callback to be invoked for all child nodes - * @param cbNodes a callback to be invoked for embedded array - * - * @remarks `forEachChild` must visit the children of a node in the order - * that they appear in the source code. The language service depends on this property to locate nodes by position. - */ -export function forEachChild(node: Node, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - if (node === undefined || node.kind <= SyntaxKind.LastToken) { - return; - } - const fn = (forEachChildTable as Record>)[node.kind]; - return fn === undefined ? undefined : fn(node, cbNode, cbNodes); -} - -/** - * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes - * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; additionally, - * unlike `forEachChild`, embedded arrays are flattened and the 'cbNode' callback is invoked for each element. - * If a callback returns a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. - * - * @param node a given node to visit its children - * @param cbNode a callback to be invoked for all child nodes - * @param cbNodes a callback to be invoked for embedded array - * - * @remarks Unlike `forEachChild`, `forEachChildRecursively` handles recursively invoking the traversal on each child node found, - * and while doing so, handles traversing the structure without relying on the callstack to encode the tree structure. - * - * @internal - */ -export function forEachChildRecursively(rootNode: Node, cbNode: (node: Node, parent: Node) => T | "skip" | undefined, cbNodes?: (nodes: NodeArray, parent: Node) => T | "skip" | undefined): T | undefined { - const queue: (Node | NodeArray)[] = gatherPossibleChildren(rootNode); - const parents: Node[] = []; // tracks parent references for elements in queue - while (parents.length < queue.length) { - parents.push(rootNode); - } - while (queue.length !== 0) { - const current = queue.pop()!; - const parent = parents.pop()!; - if (isArray(current)) { - if (cbNodes) { - const res = cbNodes(current, parent); - if (res) { - if (res === "skip") continue; - return res; - } - } - for (let i = current.length - 1; i >= 0; --i) { - queue.push(current[i]); - parents.push(parent); - } - } - else { - const res = cbNode(current, parent); - if (res) { - if (res === "skip") continue; - return res; - } - if (current.kind >= SyntaxKind.FirstNode) { - // add children in reverse order to the queue, so popping gives the first child - for (const child of gatherPossibleChildren(current)) { - queue.push(child); - parents.push(current); - } - } - } - } -} - -function gatherPossibleChildren(node: Node) { - const children: (Node | NodeArray)[] = []; - forEachChild(node, addWorkItem, addWorkItem); // By using a stack above and `unshift` here, we emulate a depth-first preorder traversal - return children; - - function addWorkItem(n: Node | NodeArray) { - children.unshift(n); - } -} - -export interface CreateSourceFileOptions { - languageVersion: ScriptTarget; - /** - * Controls the format the file is detected as - this can be derived from only the path - * and files on disk, but needs to be done with a module resolution cache in scope to be performant. - * This is usually `undefined` for compilations that do not have `moduleResolution` values of `node16` or `nodenext`. - */ - impliedNodeFormat?: ResolutionMode; - /** - * Controls how module-y-ness is set for the given file. Usually the result of calling - * `getSetExternalModuleIndicator` on a valid `CompilerOptions` object. If not present, the default - * check specified by `isFileProbablyExternalModule` will be used to set the field. - */ - setExternalModuleIndicator?: (file: SourceFile) => void; - /** @internal */ packageJsonLocations?: readonly string[]; - /** @internal */ packageJsonScope?: PackageJsonInfo; - jsDocParsingMode?: JSDocParsingMode; -} - -function setExternalModuleIndicator(sourceFile: SourceFile) { - sourceFile.externalModuleIndicator = isFileProbablyExternalModule(sourceFile); -} - -export function createSourceFile(fileName: string, sourceText: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, setParentNodes = false, scriptKind?: ScriptKind): SourceFile { - tracing?.push(tracing.Phase.Parse, "createSourceFile", { path: fileName }, /*separateBeginAndEnd*/ true); - performance.mark("beforeParse"); - let result: SourceFile; - - const { - languageVersion, - setExternalModuleIndicator: overrideSetExternalModuleIndicator, - impliedNodeFormat: format, - jsDocParsingMode, - } = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions : ({ languageVersion: languageVersionOrOptions } as CreateSourceFileOptions); - if (languageVersion === ScriptTarget.JSON) { - result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ScriptKind.JSON, noop, jsDocParsingMode); - } - else { - const setIndicator = format === undefined ? overrideSetExternalModuleIndicator : (file: SourceFile) => { - file.impliedNodeFormat = format; - return (overrideSetExternalModuleIndicator || setExternalModuleIndicator)(file); - }; - result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind, setIndicator, jsDocParsingMode); - } - - performance.mark("afterParse"); - performance.measure("Parse", "beforeParse", "afterParse"); - tracing?.pop(); - return result; -} - -export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName | undefined { - return Parser.parseIsolatedEntityName(text, languageVersion); -} - -/** - * Parse json text into SyntaxTree and return node and parse errors if any - * @param fileName - * @param sourceText - */ -export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { - return Parser.parseJsonText(fileName, sourceText); -} - -// See also `isExternalOrCommonJsModule` in utilities.ts -export function isExternalModule(file: SourceFile): boolean { - return file.externalModuleIndicator !== undefined; -} - -// Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter -// indicates what changed between the 'text' that this SourceFile has and the 'newText'. -// The SourceFile will be created with the compiler attempting to reuse as many nodes from -// this file as possible. -// -// Note: this function mutates nodes from this SourceFile. That means any existing nodes -// from this SourceFile that are being held onto may change as a result (including -// becoming detached from any SourceFile). It is recommended that this SourceFile not -// be used once 'update' is called on it. -export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks = false): SourceFile { - const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); - // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. - // We will manually port the flag to the new source file. - (newSourceFile as Mutable).flags |= sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags; - return newSourceFile; -} - -/** @internal */ -export interface JsDocWithDiagnostics { - jsDoc: JSDoc; - diagnostics: Diagnostic[]; -} - -/** @internal */ -export function parseIsolatedJSDocComment(content: string, start?: number, length?: number): JsDocWithDiagnostics | undefined { - const result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); - if (result && result.jsDoc) { - // because the jsDocComment was parsed out of the source file, it might - // not be covered by the fixupParentReferences. - Parser.fixupParentReferences(result.jsDoc); - } - - return result; -} - -/** @internal */ -// Exposed only for testing. -export function parseJSDocTypeExpressionForTests(content: string, start?: number, length?: number): { - jsDocTypeExpression: JSDocTypeExpression; - diagnostics: Diagnostic[]; -} | undefined { - return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); -} - -// Implement the parser as a singleton module. We do this for perf reasons because creating -// parser instances can actually be expensive enough to impact us on projects with many source -// files. -namespace Parser { - // Why var? It avoids TDZ checks in the runtime which can be costly. - // See: https://github.com/microsoft/TypeScript/issues/52924 - /* eslint-disable no-var */ - - // Share a single scanner across all calls to parse a source file. This helps speed things - // up by avoiding the cost of creating/compiling scanners over and over again. - var scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); - - var disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext; - - // capture constructors in 'initializeState' to avoid null checks - var NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - var TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - var IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Identifier; - var PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => PrivateIdentifier; - var SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => SourceFile; - - function countNode(node: Node) { - nodeCount++; - return node; - } - - // Rather than using `createBaseNodeFactory` here, we establish a `BaseNodeFactory` that closes over the - // constructors above, which are reset each time `initializeState` is called. - var baseNodeFactory: BaseNodeFactory = { - createBaseSourceFileNode: kind => countNode(new SourceFileConstructor(kind, /*pos*/ 0, /*end*/ 0)), - createBaseIdentifierNode: kind => countNode(new IdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), - createBasePrivateIdentifierNode: kind => countNode(new PrivateIdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), - createBaseTokenNode: kind => countNode(new TokenConstructor(kind, /*pos*/ 0, /*end*/ 0)), - createBaseNode: kind => countNode(new NodeConstructor(kind, /*pos*/ 0, /*end*/ 0)), - }; - - var factory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules | NodeFactoryFlags.NoNodeConverters | NodeFactoryFlags.NoOriginalNode, baseNodeFactory); - - var { - createNodeArray: factoryCreateNodeArray, - createNumericLiteral: factoryCreateNumericLiteral, - createStringLiteral: factoryCreateStringLiteral, - createLiteralLikeNode: factoryCreateLiteralLikeNode, - createIdentifier: factoryCreateIdentifier, - createPrivateIdentifier: factoryCreatePrivateIdentifier, - createToken: factoryCreateToken, - createArrayLiteralExpression: factoryCreateArrayLiteralExpression, - createObjectLiteralExpression: factoryCreateObjectLiteralExpression, - createPropertyAccessExpression: factoryCreatePropertyAccessExpression, - createPropertyAccessChain: factoryCreatePropertyAccessChain, - createElementAccessExpression: factoryCreateElementAccessExpression, - createElementAccessChain: factoryCreateElementAccessChain, - createCallExpression: factoryCreateCallExpression, - createCallChain: factoryCreateCallChain, - createNewExpression: factoryCreateNewExpression, - createParenthesizedExpression: factoryCreateParenthesizedExpression, - createBlock: factoryCreateBlock, - createVariableStatement: factoryCreateVariableStatement, - createExpressionStatement: factoryCreateExpressionStatement, - createIfStatement: factoryCreateIfStatement, - createWhileStatement: factoryCreateWhileStatement, - createForStatement: factoryCreateForStatement, - createForOfStatement: factoryCreateForOfStatement, - createVariableDeclaration: factoryCreateVariableDeclaration, - createVariableDeclarationList: factoryCreateVariableDeclarationList, - } = factory; - - var fileName: string; - var sourceFlags: NodeFlags; - var sourceText: string; - var languageVersion: ScriptTarget; - var scriptKind: ScriptKind; - var languageVariant: LanguageVariant; - var parseDiagnostics: DiagnosticWithDetachedLocation[]; - var jsDocDiagnostics: DiagnosticWithDetachedLocation[]; - var syntaxCursor: IncrementalParser.SyntaxCursor | undefined; - - var currentToken: SyntaxKind; - var nodeCount: number; - var identifiers: Map; - var identifierCount: number; - - // TODO(jakebailey): This type is a lie; this value actually contains the result - // of ORing a bunch of `1 << ParsingContext.XYZ`. - var parsingContext: ParsingContext; - - var notParenthesizedArrow: Set | undefined; - - // Flags that dictate what parsing context we're in. For example: - // Whether or not we are in strict parsing mode. All that changes in strict parsing mode is - // that some tokens that would be considered identifiers may be considered keywords. - // - // When adding more parser context flags, consider which is the more common case that the - // flag will be in. This should be the 'false' state for that flag. The reason for this is - // that we don't store data in our nodes unless the value is in the *non-default* state. So, - // for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for - // 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost - // all nodes would need extra state on them to store this info. - // - // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 - // grammar specification. - // - // An important thing about these context concepts. By default they are effectively inherited - // while parsing through every grammar production. i.e. if you don't change them, then when - // you parse a sub-production, it will have the same context values as the parent production. - // This is great most of the time. After all, consider all the 'expression' grammar productions - // and how nearly all of them pass along the 'in' and 'yield' context values: - // - // EqualityExpression[In, Yield] : - // RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield] - // EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield] - // - // Where you have to be careful is then understanding what the points are in the grammar - // where the values are *not* passed along. For example: - // - // SingleNameBinding[Yield,GeneratorParameter] - // [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt - // [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt - // - // Here this is saying that if the GeneratorParameter context flag is set, that we should - // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier - // and we should explicitly unset the 'yield' context flag before calling into the Initializer. - // production. Conversely, if the GeneratorParameter context flag is not set, then we - // should leave the 'yield' context flag alone. - // - // Getting this all correct is tricky and requires careful reading of the grammar to - // understand when these values should be changed versus when they should be inherited. - // - // Note: it should not be necessary to save/restore these flags during speculative/lookahead - // parsing. These context flags are naturally stored and restored through normal recursive - // descent parsing and unwinding. - var contextFlags: NodeFlags; - - // Indicates whether we are currently parsing top-level statements. - var topLevel = true; - - // Whether or not we've had a parse error since creating the last AST node. If we have - // encountered an error, it will be stored on the next AST node we create. Parse errors - // can be broken down into three categories: - // - // 1) An error that occurred during scanning. For example, an unterminated literal, or a - // character that was completely not understood. - // - // 2) A token was expected, but was not present. This type of error is commonly produced - // by the 'parseExpected' function. - // - // 3) A token was present that no parsing function was able to consume. This type of error - // only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser - // decides to skip the token. - // - // In all of these cases, we want to mark the next node as having had an error before it. - // With this mark, we can know in incremental settings if this node can be reused, or if - // we have to reparse it. If we don't keep this information around, we may just reuse the - // node. in that event we would then not produce the same errors as we did before, causing - // significant confusion problems. - // - // Note: it is necessary that this value be saved/restored during speculative/lookahead - // parsing. During lookahead parsing, we will often create a node. That node will have - // this value attached, and then this value will be set back to 'false'. If we decide to - // rewind, we must get back to the same value we had prior to the lookahead. - // - // Note: any errors at the end of the file that do not precede a regular node, should get - // attached to the EOF token. - var parseErrorBeforeNextFinishedNode = false; - /* eslint-enable no-var */ - - export function parseSourceFile( - fileName: string, - sourceText: string, - languageVersion: ScriptTarget, - syntaxCursor: IncrementalParser.SyntaxCursor | undefined, - setParentNodes = false, - scriptKind?: ScriptKind, - setExternalModuleIndicatorOverride?: (file: SourceFile) => void, - jsDocParsingMode = JSDocParsingMode.ParseAll, - ): SourceFile { - scriptKind = ensureScriptKind(fileName, scriptKind); - if (scriptKind === ScriptKind.JSON) { - const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); - convertToJson(result, result.statements[0]?.expression, result.parseDiagnostics, /*returnValue*/ false, /*jsonConversionNotifier*/ undefined); - result.referencedFiles = emptyArray; - result.typeReferenceDirectives = emptyArray; - result.libReferenceDirectives = emptyArray; - result.amdDependencies = emptyArray; - result.hasNoDefaultLib = false; - result.pragmas = emptyMap as ReadonlyPragmaMap; - return result; - } - - initializeState(fileName, sourceText, languageVersion, syntaxCursor, scriptKind, jsDocParsingMode); - - const result = parseSourceFileWorker(languageVersion, setParentNodes, scriptKind, setExternalModuleIndicatorOverride || setExternalModuleIndicator, jsDocParsingMode); - - clearState(); - - return result; - } - - export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName | undefined { - // Choice of `isDeclarationFile` should be arbitrary - initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS, JSDocParsingMode.ParseAll); - // Prime the scanner. - nextToken(); - const entityName = parseEntityName(/*allowReservedWords*/ true); - const isValid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length; - clearState(); - return isValid ? entityName : undefined; - } - - export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes = false): JsonSourceFile { - initializeState(fileName, sourceText, languageVersion, syntaxCursor, ScriptKind.JSON, JSDocParsingMode.ParseAll); - sourceFlags = contextFlags; - - // Prime the scanner. - nextToken(); - const pos = getNodePos(); - let statements, endOfFileToken; - if (token() === SyntaxKind.EndOfFileToken) { - statements = createNodeArray([], pos, pos); - endOfFileToken = parseTokenNode(); - } - else { - // Loop and synthesize an ArrayLiteralExpression if there are more than - // one top-level expressions to ensure all input text is consumed. - let expressions: Expression[] | Expression | undefined; - while (token() !== SyntaxKind.EndOfFileToken) { - let expression; - switch (token()) { - case SyntaxKind.OpenBracketToken: - expression = parseArrayLiteralExpression(); - break; - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - expression = parseTokenNode(); - break; - case SyntaxKind.MinusToken: - if (lookAhead(() => nextToken() === SyntaxKind.NumericLiteral && nextToken() !== SyntaxKind.ColonToken)) { - expression = parsePrefixUnaryExpression() as JsonMinusNumericLiteral; - } - else { - expression = parseObjectLiteralExpression(); - } - break; - case SyntaxKind.NumericLiteral: - case SyntaxKind.StringLiteral: - if (lookAhead(() => nextToken() !== SyntaxKind.ColonToken)) { - expression = parseLiteralNode() as StringLiteral | NumericLiteral; - break; - } - // falls through - default: - expression = parseObjectLiteralExpression(); - break; - } - - // Error recovery: collect multiple top-level expressions - if (expressions && isArray(expressions)) { - expressions.push(expression); - } - else if (expressions) { - expressions = [expressions, expression]; - } - else { - expressions = expression; - if (token() !== SyntaxKind.EndOfFileToken) { - parseErrorAtCurrentToken(Diagnostics.Unexpected_token); - } - } - } - - const expression = isArray(expressions) ? finishNode(factoryCreateArrayLiteralExpression(expressions), pos) : Debug.checkDefined(expressions); - const statement = factoryCreateExpressionStatement(expression) as JsonObjectExpressionStatement; - finishNode(statement, pos); - statements = createNodeArray([statement], pos); - endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token) as EndOfFileToken; - } - - // Set source file so that errors will be reported with this file name - const sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclarationFile*/ false, statements, endOfFileToken, sourceFlags, noop); - - if (setParentNodes) { - fixupParentReferences(sourceFile); - } - - sourceFile.nodeCount = nodeCount; - sourceFile.identifierCount = identifierCount; - sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); - if (jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); - } - - const result = sourceFile as JsonSourceFile; - clearState(); - return result; - } - - function initializeState(_fileName: string, _sourceText: string, _languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, _scriptKind: ScriptKind, _jsDocParsingMode: JSDocParsingMode) { - NodeConstructor = objectAllocator.getNodeConstructor(); - TokenConstructor = objectAllocator.getTokenConstructor(); - IdentifierConstructor = objectAllocator.getIdentifierConstructor(); - PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor(); - SourceFileConstructor = objectAllocator.getSourceFileConstructor(); - - fileName = normalizePath(_fileName); - sourceText = _sourceText; - languageVersion = _languageVersion; - syntaxCursor = _syntaxCursor; - scriptKind = _scriptKind; - languageVariant = getLanguageVariant(_scriptKind); - - parseDiagnostics = []; - parsingContext = 0; - identifiers = new Map(); - identifierCount = 0; - nodeCount = 0; - sourceFlags = 0; - topLevel = true; - - switch (scriptKind) { - case ScriptKind.JS: - case ScriptKind.JSX: - contextFlags = NodeFlags.JavaScriptFile; - break; - case ScriptKind.JSON: - contextFlags = NodeFlags.JavaScriptFile | NodeFlags.JsonFile; - break; - default: - contextFlags = NodeFlags.None; - break; - } - parseErrorBeforeNextFinishedNode = false; - - // Initialize and prime the scanner before parsing the source elements. - scanner.setText(sourceText); - scanner.setOnError(scanError); - scanner.setScriptTarget(languageVersion); - scanner.setLanguageVariant(languageVariant); - scanner.setScriptKind(scriptKind); - scanner.setJSDocParsingMode(_jsDocParsingMode); - } - - function clearState() { - // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. - scanner.clearCommentDirectives(); - scanner.setText(""); - scanner.setOnError(undefined); - scanner.setScriptKind(ScriptKind.Unknown); - scanner.setJSDocParsingMode(JSDocParsingMode.ParseAll); - - // Clear any data. We don't want to accidentally hold onto it for too long. - sourceText = undefined!; - languageVersion = undefined!; - syntaxCursor = undefined; - scriptKind = undefined!; - languageVariant = undefined!; - sourceFlags = 0; - parseDiagnostics = undefined!; - jsDocDiagnostics = undefined!; - parsingContext = 0; - identifiers = undefined!; - notParenthesizedArrow = undefined; - topLevel = true; - } - - function parseSourceFileWorker(languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind, setExternalModuleIndicator: (file: SourceFile) => void, jsDocParsingMode: JSDocParsingMode): SourceFile { - const isDeclarationFile = isDeclarationFileName(fileName); - if (isDeclarationFile) { - contextFlags |= NodeFlags.Ambient; - } - - sourceFlags = contextFlags; - - // Prime the scanner. - nextToken(); - - const statements = parseList(ParsingContext.SourceElements, parseStatement); - Debug.assert(token() === SyntaxKind.EndOfFileToken); - const endHasJSDoc = hasPrecedingJSDocComment(); - const endOfFileToken = withJSDoc(parseTokenNode(), endHasJSDoc); - - const sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile, statements, endOfFileToken, sourceFlags, setExternalModuleIndicator); - - // A member of ReadonlyArray isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future - processCommentPragmas(sourceFile as {} as PragmaContext, sourceText); - processPragmasIntoFields(sourceFile as {} as PragmaContext, reportPragmaDiagnostic); - - sourceFile.commentDirectives = scanner.getCommentDirectives(); - sourceFile.nodeCount = nodeCount; - sourceFile.identifierCount = identifierCount; - sourceFile.identifiers = identifiers; - sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); - sourceFile.jsDocParsingMode = jsDocParsingMode; - if (jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); - } - - if (setParentNodes) { - fixupParentReferences(sourceFile); - } - - return sourceFile; - - function reportPragmaDiagnostic(pos: number, end: number, diagnostic: DiagnosticMessage) { - parseDiagnostics.push(createDetachedDiagnostic(fileName, sourceText, pos, end, diagnostic)); - } - } - - let hasDeprecatedTag = false; - function withJSDoc(node: T, hasJSDoc: boolean): T { - if (!hasJSDoc) { - return node; - } - - Debug.assert(!node.jsDoc); // Should only be called once per node - const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceText), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); - if (jsDoc.length) node.jsDoc = jsDoc; - if (hasDeprecatedTag) { - hasDeprecatedTag = false; - (node as Mutable).flags |= NodeFlags.Deprecated; - } - return node; - } - - function reparseTopLevelAwait(sourceFile: SourceFile) { - const savedSyntaxCursor = syntaxCursor; - const baseSyntaxCursor = IncrementalParser.createSyntaxCursor(sourceFile); - syntaxCursor = { currentNode }; - - const statements: Statement[] = []; - const savedParseDiagnostics = parseDiagnostics; - - parseDiagnostics = []; - - let pos = 0; - let start = findNextStatementWithAwait(sourceFile.statements, 0); - while (start !== -1) { - // append all statements between pos and start - const prevStatement = sourceFile.statements[pos]; - const nextStatement = sourceFile.statements[start]; - addRange(statements, sourceFile.statements, pos, start); - pos = findNextStatementWithoutAwait(sourceFile.statements, start); - - // append all diagnostics associated with the copied range - const diagnosticStart = findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); - const diagnosticEnd = diagnosticStart >= 0 ? findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= nextStatement.pos, diagnosticStart) : -1; - if (diagnosticStart >= 0) { - addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart, diagnosticEnd >= 0 ? diagnosticEnd : undefined); - } - - // reparse all statements between start and pos. We skip existing diagnostics for the same range and allow the parser to generate new ones. - speculationHelper(() => { - const savedContextFlags = contextFlags; - contextFlags |= NodeFlags.AwaitContext; - scanner.resetTokenState(nextStatement.pos); - nextToken(); - - while (token() !== SyntaxKind.EndOfFileToken) { - const startPos = scanner.getTokenFullStart(); - const statement = parseListElement(ParsingContext.SourceElements, parseStatement); - statements.push(statement); - if (startPos === scanner.getTokenFullStart()) { - nextToken(); - } - - if (pos >= 0) { - const nonAwaitStatement = sourceFile.statements[pos]; - if (statement.end === nonAwaitStatement.pos) { - // done reparsing this section - break; - } - if (statement.end > nonAwaitStatement.pos) { - // we ate into the next statement, so we must reparse it. - pos = findNextStatementWithoutAwait(sourceFile.statements, pos + 1); - } - } - } - - contextFlags = savedContextFlags; - }, SpeculationKind.Reparse); - - // find the next statement containing an `await` - start = pos >= 0 ? findNextStatementWithAwait(sourceFile.statements, pos) : -1; - } - - // append all statements between pos and the end of the list - if (pos >= 0) { - const prevStatement = sourceFile.statements[pos]; - addRange(statements, sourceFile.statements, pos); - - // append all diagnostics associated with the copied range - const diagnosticStart = findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); - if (diagnosticStart >= 0) { - addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart); - } - } - - syntaxCursor = savedSyntaxCursor; - return factory.updateSourceFile(sourceFile, setTextRange(factoryCreateNodeArray(statements), sourceFile.statements)); - - function containsPossibleTopLevelAwait(node: Node) { - return !(node.flags & NodeFlags.AwaitContext) - && !!(node.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait); - } - - function findNextStatementWithAwait(statements: NodeArray, start: number) { - for (let i = start; i < statements.length; i++) { - if (containsPossibleTopLevelAwait(statements[i])) { - return i; - } - } - return -1; - } - - function findNextStatementWithoutAwait(statements: NodeArray, start: number) { - for (let i = start; i < statements.length; i++) { - if (!containsPossibleTopLevelAwait(statements[i])) { - return i; - } - } - return -1; - } - - function currentNode(position: number) { - const node = baseSyntaxCursor.currentNode(position); - if (topLevel && node && containsPossibleTopLevelAwait(node)) { - markAsIntersectingIncrementalChange(node); - } - return node; - } - } - - export function fixupParentReferences(rootNode: Node) { - // normally parent references are set during binding. However, for clients that only need - // a syntax tree, and no semantic features, then the binding process is an unnecessary - // overhead. This functions allows us to set all the parents, without all the expense of - // binding. - setParentRecursive(rootNode, /*incremental*/ true); - } - - function createSourceFile( - fileName: string, - languageVersion: ScriptTarget, - scriptKind: ScriptKind, - isDeclarationFile: boolean, - statements: readonly Statement[], - endOfFileToken: EndOfFileToken, - flags: NodeFlags, - setExternalModuleIndicator: (sourceFile: SourceFile) => void, - ): SourceFile { - // code from createNode is inlined here so createNode won't have to deal with special case of creating source files - // this is quite rare comparing to other nodes and createNode should be as fast as possible - let sourceFile = factory.createSourceFile(statements, endOfFileToken, flags); - setTextRangePosWidth(sourceFile, 0, sourceText.length); - setFields(sourceFile); - - // If we parsed this as an external module, it may contain top-level await - if (!isDeclarationFile && isExternalModule(sourceFile) && sourceFile.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait) { - const oldSourceFile = sourceFile; - sourceFile = reparseTopLevelAwait(sourceFile); - if (oldSourceFile !== sourceFile) setFields(sourceFile); - } - - return sourceFile; - - function setFields(sourceFile: SourceFile) { - sourceFile.text = sourceText; - sourceFile.bindDiagnostics = []; - sourceFile.bindSuggestionDiagnostics = undefined; - sourceFile.languageVersion = languageVersion; - sourceFile.fileName = fileName; - sourceFile.languageVariant = getLanguageVariant(scriptKind); - sourceFile.isDeclarationFile = isDeclarationFile; - sourceFile.scriptKind = scriptKind; - - setExternalModuleIndicator(sourceFile); - sourceFile.setExternalModuleIndicator = setExternalModuleIndicator; - } - } - - function setContextFlag(val: boolean, flag: NodeFlags) { - if (val) { - contextFlags |= flag; - } - else { - contextFlags &= ~flag; - } - } - - function setDisallowInContext(val: boolean) { - setContextFlag(val, NodeFlags.DisallowInContext); - } - - function setYieldContext(val: boolean) { - setContextFlag(val, NodeFlags.YieldContext); - } - - function setDecoratorContext(val: boolean) { - setContextFlag(val, NodeFlags.DecoratorContext); - } - - function setAwaitContext(val: boolean) { - setContextFlag(val, NodeFlags.AwaitContext); - } - - function doOutsideOfContext(context: NodeFlags, func: () => T): T { - // contextFlagsToClear will contain only the context flags that are - // currently set that we need to temporarily clear - // We don't just blindly reset to the previous flags to ensure - // that we do not mutate cached flags for the incremental - // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and - // HasAggregatedChildData). - const contextFlagsToClear = context & contextFlags; - if (contextFlagsToClear) { - // clear the requested context flags - setContextFlag(/*val*/ false, contextFlagsToClear); - const result = func(); - // restore the context flags we just cleared - setContextFlag(/*val*/ true, contextFlagsToClear); - return result; - } - - // no need to do anything special as we are not in any of the requested contexts - return func(); - } - - function doInsideOfContext(context: NodeFlags, func: () => T): T { - // contextFlagsToSet will contain only the context flags that - // are not currently set that we need to temporarily enable. - // We don't just blindly reset to the previous flags to ensure - // that we do not mutate cached flags for the incremental - // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and - // HasAggregatedChildData). - const contextFlagsToSet = context & ~contextFlags; - if (contextFlagsToSet) { - // set the requested context flags - setContextFlag(/*val*/ true, contextFlagsToSet); - const result = func(); - // reset the context flags we just set - setContextFlag(/*val*/ false, contextFlagsToSet); - return result; - } - - // no need to do anything special as we are already in all of the requested contexts - return func(); - } - - function allowInAnd(func: () => T): T { - return doOutsideOfContext(NodeFlags.DisallowInContext, func); - } - - function disallowInAnd(func: () => T): T { - return doInsideOfContext(NodeFlags.DisallowInContext, func); - } - - function allowConditionalTypesAnd(func: () => T): T { - return doOutsideOfContext(NodeFlags.DisallowConditionalTypesContext, func); - } - - function disallowConditionalTypesAnd(func: () => T): T { - return doInsideOfContext(NodeFlags.DisallowConditionalTypesContext, func); - } - - function doInYieldContext(func: () => T): T { - return doInsideOfContext(NodeFlags.YieldContext, func); - } - - function doInDecoratorContext(func: () => T): T { - return doInsideOfContext(NodeFlags.DecoratorContext, func); - } - - function doInAwaitContext(func: () => T): T { - return doInsideOfContext(NodeFlags.AwaitContext, func); - } - - function doOutsideOfAwaitContext(func: () => T): T { - return doOutsideOfContext(NodeFlags.AwaitContext, func); - } - - function doInYieldAndAwaitContext(func: () => T): T { - return doInsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); - } - - function doOutsideOfYieldAndAwaitContext(func: () => T): T { - return doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); - } - - function inContext(flags: NodeFlags) { - return (contextFlags & flags) !== 0; - } - - function inYieldContext() { - return inContext(NodeFlags.YieldContext); - } - - function inDisallowInContext() { - return inContext(NodeFlags.DisallowInContext); - } - - function inDisallowConditionalTypesContext() { - return inContext(NodeFlags.DisallowConditionalTypesContext); - } - - function inDecoratorContext() { - return inContext(NodeFlags.DecoratorContext); - } - - function inAwaitContext() { - return inContext(NodeFlags.AwaitContext); - } - - function parseErrorAtCurrentToken(message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { - return parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), message, ...args); - } - - function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { - // Don't report another error if it would just be at the same position as the last error. - const lastError = lastOrUndefined(parseDiagnostics); - let result: DiagnosticWithDetachedLocation | undefined; - if (!lastError || start !== lastError.start) { - result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args); - parseDiagnostics.push(result); - } - - // Mark that we've encountered an error. We'll set an appropriate bit on the next - // node we finish so that it can't be reused incrementally. - parseErrorBeforeNextFinishedNode = true; - return result; - } - - function parseErrorAt(start: number, end: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { - return parseErrorAtPosition(start, end - start, message, ...args); - } - - function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, ...args: DiagnosticArguments): void { - parseErrorAt(range.pos, range.end, message, ...args); - } - - function scanError(message: DiagnosticMessage, length: number, arg0?: any): void { - parseErrorAtPosition(scanner.getTokenEnd(), length, message, arg0); - } - - function getNodePos(): number { - return scanner.getTokenFullStart(); - } - - function hasPrecedingJSDocComment() { - return scanner.hasPrecedingJSDocComment(); - } - - // Use this function to access the current token instead of reading the currentToken - // variable. Since function results aren't narrowed in control flow analysis, this ensures - // that the type checker doesn't make wrong assumptions about the type of the current - // token (e.g. a call to nextToken() changes the current token but the checker doesn't - // reason about this side effect). Mainstream VMs inline simple functions like this, so - // there is no performance penalty. - function token(): SyntaxKind { - return currentToken; - } - - function nextTokenWithoutCheck() { - return currentToken = scanner.scan(); - } - - function nextTokenAnd(func: () => T): T { - nextToken(); - return func(); - } - - function nextToken(): SyntaxKind { - // if the keyword had an escape - if (isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) { - // issue a parse error for the escape - parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), Diagnostics.Keywords_cannot_contain_escape_characters); - } - return nextTokenWithoutCheck(); - } - - function nextTokenJSDoc(): JSDocSyntaxKind { - return currentToken = scanner.scanJsDocToken(); - } - - function nextJSDocCommentTextToken(inBackticks: boolean): JSDocSyntaxKind | SyntaxKind.JSDocCommentTextToken { - return currentToken = scanner.scanJSDocCommentTextToken(inBackticks); - } - - function reScanGreaterToken(): SyntaxKind { - return currentToken = scanner.reScanGreaterToken(); - } - - function reScanSlashToken(): SyntaxKind { - return currentToken = scanner.reScanSlashToken(); - } - - function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind { - return currentToken = scanner.reScanTemplateToken(isTaggedTemplate); - } - - function reScanLessThanToken(): SyntaxKind { - return currentToken = scanner.reScanLessThanToken(); - } - - function reScanHashToken(): SyntaxKind { - return currentToken = scanner.reScanHashToken(); - } - - function scanJsxIdentifier(): SyntaxKind { - return currentToken = scanner.scanJsxIdentifier(); - } - - function scanJsxText(): SyntaxKind { - return currentToken = scanner.scanJsxToken(); - } - - function scanJsxAttributeValue(): SyntaxKind { - return currentToken = scanner.scanJsxAttributeValue(); - } - - function speculationHelper(callback: () => T, speculationKind: SpeculationKind): T { - // Keep track of the state we'll need to rollback to if lookahead fails (or if the - // caller asked us to always reset our state). - const saveToken = currentToken; - const saveParseDiagnosticsLength = parseDiagnostics.length; - const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; - - // Note: it is not actually necessary to save/restore the context flags here. That's - // because the saving/restoring of these flags happens naturally through the recursive - // descent nature of our parser. However, we still store this here just so we can - // assert that invariant holds. - const saveContextFlags = contextFlags; - - // If we're only looking ahead, then tell the scanner to only lookahead as well. - // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the - // same. - const result = speculationKind !== SpeculationKind.TryParse - ? scanner.lookAhead(callback) - : scanner.tryScan(callback); - - Debug.assert(saveContextFlags === contextFlags); - - // If our callback returned something 'falsy' or we're just looking ahead, - // then unconditionally restore us to where we were. - if (!result || speculationKind !== SpeculationKind.TryParse) { - currentToken = saveToken; - if (speculationKind !== SpeculationKind.Reparse) { - parseDiagnostics.length = saveParseDiagnosticsLength; - } - parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; - } - - return result; - } - - /** Invokes the provided callback then unconditionally restores the parser to the state it - * was in immediately prior to invoking the callback. The result of invoking the callback - * is returned from this function. - */ - function lookAhead(callback: () => T): T { - return speculationHelper(callback, SpeculationKind.Lookahead); - } - - /** Invokes the provided callback. If the callback returns something falsy, then it restores - * the parser to the state it was in immediately prior to invoking the callback. If the - * callback returns something truthy, then the parser state is not rolled back. The result - * of invoking the callback is returned from this function. - */ - function tryParse(callback: () => T): T { - return speculationHelper(callback, SpeculationKind.TryParse); - } - - function isBindingIdentifier(): boolean { - if (token() === SyntaxKind.Identifier) { - return true; - } - - // `let await`/`let yield` in [Yield] or [Await] are allowed here and disallowed in the binder. - return token() > SyntaxKind.LastReservedWord; - } - - // Ignore strict mode flag because we will report an error in type checker instead. - function isIdentifier(): boolean { - if (token() === SyntaxKind.Identifier) { - return true; - } - - // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is - // considered a keyword and is not an identifier. - if (token() === SyntaxKind.YieldKeyword && inYieldContext()) { - return false; - } - - // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is - // considered a keyword and is not an identifier. - if (token() === SyntaxKind.AwaitKeyword && inAwaitContext()) { - return false; - } - - return token() > SyntaxKind.LastReservedWord; - } - - function parseExpected(kind: PunctuationOrKeywordSyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean { - if (token() === kind) { - if (shouldAdvance) { - nextToken(); - } - return true; - } - - // Report specific message if provided with one. Otherwise, report generic fallback message. - if (diagnosticMessage) { - parseErrorAtCurrentToken(diagnosticMessage); - } - else { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); - } - return false; - } - - const viableKeywordSuggestions = Object.keys(textToKeywordObj).filter(keyword => keyword.length > 2); - - /** - * Provides a better error message than the generic "';' expected" if possible for - * known common variants of a missing semicolon, such as from a mispelled names. - * - * @param node Node preceding the expected semicolon location. - */ - function parseErrorForMissingSemicolonAfter(node: Expression | PropertyName): void { - // Tagged template literals are sometimes used in places where only simple strings are allowed, i.e.: - // module `M1` { - // ^^^^^^^^^^^ This block is parsed as a template literal like module`M1`. - if (isTaggedTemplateExpression(node)) { - parseErrorAt(skipTrivia(sourceText, node.template.pos), node.template.end, Diagnostics.Module_declaration_names_may_only_use_or_quoted_strings); - return; - } - - // Otherwise, if this isn't a well-known keyword-like identifier, give the generic fallback message. - const expressionText = isIdentifierNode(node) ? idText(node) : undefined; - if (!expressionText || !isIdentifierText(expressionText, languageVersion)) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); - return; - } - - const pos = skipTrivia(sourceText, node.pos); - - // Some known keywords are likely signs of syntax being used improperly. - switch (expressionText) { - case "const": - case "let": - case "var": - parseErrorAt(pos, node.end, Diagnostics.Variable_declaration_not_allowed_at_this_location); - return; - - case "declare": - // If a declared node failed to parse, it would have emitted a diagnostic already. - return; - - case "interface": - parseErrorForInvalidName(Diagnostics.Interface_name_cannot_be_0, Diagnostics.Interface_must_be_given_a_name, SyntaxKind.OpenBraceToken); - return; - - case "is": - parseErrorAt(pos, scanner.getTokenStart(), Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); - return; - - case "module": - case "namespace": - parseErrorForInvalidName(Diagnostics.Namespace_name_cannot_be_0, Diagnostics.Namespace_must_be_given_a_name, SyntaxKind.OpenBraceToken); - return; - - case "type": - parseErrorForInvalidName(Diagnostics.Type_alias_name_cannot_be_0, Diagnostics.Type_alias_must_be_given_a_name, SyntaxKind.EqualsToken); - return; - } - - // The user alternatively might have misspelled or forgotten to add a space after a common keyword. - const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, identity) ?? getSpaceSuggestion(expressionText); - if (suggestion) { - parseErrorAt(pos, node.end, Diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion); - return; - } - - // Unknown tokens are handled with their own errors in the scanner - if (token() === SyntaxKind.Unknown) { - return; - } - - // Otherwise, we know this some kind of unknown word, not just a missing expected semicolon. - parseErrorAt(pos, node.end, Diagnostics.Unexpected_keyword_or_identifier); - } - - /** - * Reports a diagnostic error for the current token being an invalid name. - * - * @param blankDiagnostic Diagnostic to report for the case of the name being blank (matched tokenIfBlankName). - * @param nameDiagnostic Diagnostic to report for all other cases. - * @param tokenIfBlankName Current token if the name was invalid for being blank (not provided / skipped). - */ - function parseErrorForInvalidName(nameDiagnostic: DiagnosticMessage, blankDiagnostic: DiagnosticMessage, tokenIfBlankName: SyntaxKind) { - if (token() === tokenIfBlankName) { - parseErrorAtCurrentToken(blankDiagnostic); - } - else { - parseErrorAtCurrentToken(nameDiagnostic, scanner.getTokenValue()); - } - } - - function getSpaceSuggestion(expressionText: string) { - for (const keyword of viableKeywordSuggestions) { - if (expressionText.length > keyword.length + 2 && startsWith(expressionText, keyword)) { - return `${keyword} ${expressionText.slice(keyword.length)}`; - } - } - - return undefined; - } - - function parseSemicolonAfterPropertyName(name: PropertyName, type: TypeNode | undefined, initializer: Expression | undefined) { - if (token() === SyntaxKind.AtToken && !scanner.hasPrecedingLineBreak()) { - parseErrorAtCurrentToken(Diagnostics.Decorators_must_precede_the_name_and_all_keywords_of_property_declarations); - return; - } - - if (token() === SyntaxKind.OpenParenToken) { - parseErrorAtCurrentToken(Diagnostics.Cannot_start_a_function_call_in_a_type_annotation); - nextToken(); - return; - } - - if (type && !canParseSemicolon()) { - if (initializer) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); - } - else { - parseErrorAtCurrentToken(Diagnostics.Expected_for_property_initializer); - } - return; - } - - if (tryParseSemicolon()) { - return; - } - - if (initializer) { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); - return; - } - - parseErrorForMissingSemicolonAfter(name); - } - - function parseExpectedJSDoc(kind: JSDocSyntaxKind) { - if (token() === kind) { - nextTokenJSDoc(); - return true; - } - Debug.assert(isKeywordOrPunctuation(kind)); - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); - return false; - } - - function parseExpectedMatchingBrackets(openKind: PunctuationSyntaxKind, closeKind: PunctuationSyntaxKind, openParsed: boolean, openPosition: number) { - if (token() === closeKind) { - nextToken(); - return; - } - const lastError = parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(closeKind)); - if (!openParsed) { - return; - } - if (lastError) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, sourceText, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind)), - ); - } - } - - function parseOptional(t: SyntaxKind): boolean { - if (token() === t) { - nextToken(); - return true; - } - return false; - } - - function parseOptionalToken(t: TKind): Token; - function parseOptionalToken(t: SyntaxKind): Node | undefined { - if (token() === t) { - return parseTokenNode(); - } - return undefined; - } - - function parseOptionalTokenJSDoc(t: TKind): Token; - function parseOptionalTokenJSDoc(t: JSDocSyntaxKind): Node | undefined { - if (token() === t) { - return parseTokenNodeJSDoc(); - } - return undefined; - } - - function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: string): Token; - function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: string): Node { - return parseOptionalToken(t) || - createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)!); - } - - function parseExpectedTokenJSDoc(t: TKind): Token; - function parseExpectedTokenJSDoc(t: JSDocSyntaxKind): Node { - const optional = parseOptionalTokenJSDoc(t); - if (optional) return optional; - Debug.assert(isKeywordOrPunctuation(t)); - return createMissingNode(t, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(t)); - } - - function parseTokenNode(): T { - const pos = getNodePos(); - const kind = token(); - nextToken(); - return finishNode(factoryCreateToken(kind), pos) as T; - } - - function parseTokenNodeJSDoc(): T { - const pos = getNodePos(); - const kind = token(); - nextTokenJSDoc(); - return finishNode(factoryCreateToken(kind), pos) as T; - } - - function canParseSemicolon() { - // If there's a real semicolon, then we can always parse it out. - if (token() === SyntaxKind.SemicolonToken) { - return true; - } - - // We can parse out an optional semicolon in ASI cases in the following cases. - return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); - } - - function tryParseSemicolon() { - if (!canParseSemicolon()) { - return false; - } - - if (token() === SyntaxKind.SemicolonToken) { - // consume the semicolon if it was explicitly provided. - nextToken(); - } - - return true; - } - - function parseSemicolon(): boolean { - return tryParseSemicolon() || parseExpected(SyntaxKind.SemicolonToken); - } - - function createNodeArray(elements: T[], pos: number, end?: number, hasTrailingComma?: boolean): NodeArray { - const array = factoryCreateNodeArray(elements, hasTrailingComma); - setTextRangePosEnd(array, pos, end ?? scanner.getTokenFullStart()); - return array; - } - - function finishNode(node: T, pos: number, end?: number): T { - setTextRangePosEnd(node, pos, end ?? scanner.getTokenFullStart()); - if (contextFlags) { - (node as Mutable).flags |= contextFlags; - } - - // Keep track on the node if we encountered an error while parsing it. If we did, then - // we cannot reuse the node incrementally. Once we've marked this node, clear out the - // flag so that we don't mark any subsequent nodes. - if (parseErrorBeforeNextFinishedNode) { - parseErrorBeforeNextFinishedNode = false; - (node as Mutable).flags |= NodeFlags.ThisNodeHasError; - } - - return node; - } - - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, ...args: DiagnosticArguments): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): T { - if (reportAtCurrentPosition) { - parseErrorAtPosition(scanner.getTokenFullStart(), 0, diagnosticMessage!, ...args); - } - else if (diagnosticMessage) { - parseErrorAtCurrentToken(diagnosticMessage, ...args); - } - - const pos = getNodePos(); - const result = kind === SyntaxKind.Identifier ? factoryCreateIdentifier("", /*originalKeywordKind*/ undefined) : - isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, "", "", /*templateFlags*/ undefined) : - kind === SyntaxKind.NumericLiteral ? factoryCreateNumericLiteral("", /*numericLiteralFlags*/ undefined) : - kind === SyntaxKind.StringLiteral ? factoryCreateStringLiteral("", /*isSingleQuote*/ undefined) : - kind === SyntaxKind.MissingDeclaration ? factory.createMissingDeclaration() : - factoryCreateToken(kind); - return finishNode(result, pos) as T; - } - - function internIdentifier(text: string): string { - let identifier = identifiers.get(text); - if (identifier === undefined) { - identifiers.set(text, identifier = text); - } - return identifier; - } - - // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues - // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for - // each identifier in order to reduce memory consumption. - function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { - if (isIdentifier) { - identifierCount++; - const pos = scanner.hasPrecedingJSDocLeadingAsterisks() ? scanner.getTokenStart() : getNodePos(); - // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker - const originalKeywordKind = token(); - const text = internIdentifier(scanner.getTokenValue()); - const hasExtendedUnicodeEscape = scanner.hasExtendedUnicodeEscape(); - nextTokenWithoutCheck(); - return finishNode(factoryCreateIdentifier(text, originalKeywordKind, hasExtendedUnicodeEscape), pos); - } - - if (token() === SyntaxKind.PrivateIdentifier) { - parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage || Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); - return createIdentifier(/*isIdentifier*/ true); - } - - if (token() === SyntaxKind.Unknown && scanner.tryScan(() => scanner.reScanInvalidIdentifier() === SyntaxKind.Identifier)) { - // Scanner has already recorded an 'Invalid character' error, so no need to add another from the parser. - return createIdentifier(/*isIdentifier*/ true); - } - - identifierCount++; - // Only for end of file because the error gets reported incorrectly on embedded script tags. - const reportAtCurrentPosition = token() === SyntaxKind.EndOfFileToken; - - const isReservedWord = scanner.isReservedWord(); - const msgArg = scanner.getTokenText(); - - const defaultMessage = isReservedWord ? - Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here : - Diagnostics.Identifier_expected; - - return createMissingNode(SyntaxKind.Identifier, reportAtCurrentPosition, diagnosticMessage || defaultMessage, msgArg); - } - - function parseBindingIdentifier(privateIdentifierDiagnosticMessage?: DiagnosticMessage) { - return createIdentifier(isBindingIdentifier(), /*diagnosticMessage*/ undefined, privateIdentifierDiagnosticMessage); - } - - function parseIdentifier(diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { - return createIdentifier(isIdentifier(), diagnosticMessage, privateIdentifierDiagnosticMessage); - } - - function parseIdentifierName(diagnosticMessage?: DiagnosticMessage): Identifier { - return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage); - } - - function parseIdentifierNameErrorOnUnicodeEscapeSequence(): Identifier { - if (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape()) { - parseErrorAtCurrentToken(Diagnostics.Unicode_escape_sequence_cannot_appear_here); - } - return createIdentifier(tokenIsIdentifierOrKeyword(token())); - } - - function isLiteralPropertyName(): boolean { - return tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral || - token() === SyntaxKind.NumericLiteral || - token() === SyntaxKind.BigIntLiteral; - } - - function isImportAttributeName(): boolean { - return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral; - } - - function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName { - if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral) { - const node = parseLiteralNode() as StringLiteral | NumericLiteral | BigIntLiteral; - node.text = internIdentifier(node.text); - return node; - } - if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) { - return parseComputedPropertyName(); - } - if (token() === SyntaxKind.PrivateIdentifier) { - return parsePrivateIdentifier(); - } - return parseIdentifierName(); - } - - function parsePropertyName(): PropertyName { - return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true); - } - - function parseComputedPropertyName(): ComputedPropertyName { - // PropertyName [Yield]: - // LiteralPropertyName - // ComputedPropertyName[?Yield] - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBracketToken); - // We parse any expression (including a comma expression). But the grammar - // says that only an assignment expression is allowed, so the grammar checker - // will error if it sees a comma expression. - const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(factory.createComputedPropertyName(expression), pos); - } - - function parsePrivateIdentifier(): PrivateIdentifier { - const pos = getNodePos(); - const node = factoryCreatePrivateIdentifier(internIdentifier(scanner.getTokenValue())); - nextToken(); - return finishNode(node, pos); - } - - function parseContextualModifier(t: SyntaxKind): boolean { - return token() === t && tryParse(nextTokenCanFollowModifier); - } - - function nextTokenIsOnSameLineAndCanFollowModifier() { - nextToken(); - if (scanner.hasPrecedingLineBreak()) { - return false; - } - return canFollowModifier(); - } - - function nextTokenCanFollowModifier() { - switch (token()) { - case SyntaxKind.ConstKeyword: - // 'const' is only a modifier if followed by 'enum'. - return nextToken() === SyntaxKind.EnumKeyword; - case SyntaxKind.ExportKeyword: - nextToken(); - if (token() === SyntaxKind.DefaultKeyword) { - return lookAhead(nextTokenCanFollowDefaultKeyword); - } - if (token() === SyntaxKind.TypeKeyword) { - return lookAhead(nextTokenCanFollowExportModifier); - } - return canFollowExportModifier(); - case SyntaxKind.DefaultKeyword: - return nextTokenCanFollowDefaultKeyword(); - case SyntaxKind.StaticKeyword: - nextToken(); - return canFollowModifier(); - case SyntaxKind.GetKeyword: - case SyntaxKind.SetKeyword: - nextToken(); - return canFollowGetOrSetKeyword(); - default: - return nextTokenIsOnSameLineAndCanFollowModifier(); - } - } - - function canFollowExportModifier(): boolean { - return token() === SyntaxKind.AtToken - || token() !== SyntaxKind.AsteriskToken - && token() !== SyntaxKind.AsKeyword - && token() !== SyntaxKind.OpenBraceToken - && canFollowModifier(); - } - - function nextTokenCanFollowExportModifier(): boolean { - nextToken(); - return canFollowExportModifier(); - } - - function parseAnyContextualModifier(): boolean { - return isModifierKind(token()) && tryParse(nextTokenCanFollowModifier); - } - - function canFollowModifier(): boolean { - return token() === SyntaxKind.OpenBracketToken - || token() === SyntaxKind.OpenBraceToken - || token() === SyntaxKind.AsteriskToken - || token() === SyntaxKind.DotDotDotToken - || isLiteralPropertyName(); - } - - function canFollowGetOrSetKeyword(): boolean { - return token() === SyntaxKind.OpenBracketToken - || isLiteralPropertyName(); - } - - function nextTokenCanFollowDefaultKeyword(): boolean { - nextToken(); - return token() === SyntaxKind.ClassKeyword - || token() === SyntaxKind.FunctionKeyword - || token() === SyntaxKind.InterfaceKeyword - || token() === SyntaxKind.AtToken - || (token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) - || (token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); - } - - // True if positioned at the start of a list element - function isListElement(parsingContext: ParsingContext, inErrorRecovery: boolean): boolean { - const node = currentNode(parsingContext); - if (node) { - return true; - } - - switch (parsingContext) { - case ParsingContext.SourceElements: - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauseStatements: - // If we're in error recovery, then we don't want to treat ';' as an empty statement. - // The problem is that ';' can show up in far too many contexts, and if we see one - // and assume it's a statement, then we may bail out inappropriately from whatever - // we're parsing. For example, if we have a semicolon in the middle of a class, then - // we really don't want to assume the class is over and we're on a statement in the - // outer module. We just want to consume and move on. - return !(token() === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement(); - case ParsingContext.SwitchClauses: - return token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; - case ParsingContext.TypeMembers: - return lookAhead(isTypeMemberStart); - case ParsingContext.ClassMembers: - // We allow semicolons as class elements (as specified by ES6) as long as we're - // not in error recovery. If we're in error recovery, we don't want an errant - // semicolon to be treated as a class member (since they're almost always used - // for statements. - return lookAhead(isClassMemberStart) || (token() === SyntaxKind.SemicolonToken && !inErrorRecovery); - case ParsingContext.EnumMembers: - // Include open bracket computed properties. This technically also lets in indexers, - // which would be a candidate for improved error reporting. - return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); - case ParsingContext.ObjectLiteralMembers: - switch (token()) { - case SyntaxKind.OpenBracketToken: - case SyntaxKind.AsteriskToken: - case SyntaxKind.DotDotDotToken: - case SyntaxKind.DotToken: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`) - return true; - default: - return isLiteralPropertyName(); - } - case ParsingContext.RestProperties: - return isLiteralPropertyName(); - case ParsingContext.ObjectBindingElements: - return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); - case ParsingContext.ImportAttributes: - return isImportAttributeName(); - case ParsingContext.HeritageClauseElement: - // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{` - // That way we won't consume the body of a class in its heritage clause. - if (token() === SyntaxKind.OpenBraceToken) { - return lookAhead(isValidHeritageClauseObjectLiteral); - } - - if (!inErrorRecovery) { - return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword(); - } - else { - // If we're in error recovery we tighten up what we're willing to match. - // That way we don't treat something like "this" as a valid heritage clause - // element during recovery. - return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword(); - } - case ParsingContext.VariableDeclarations: - return isBindingIdentifierOrPrivateIdentifierOrPattern(); - case ParsingContext.ArrayBindingElements: - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isBindingIdentifierOrPrivateIdentifierOrPattern(); - case ParsingContext.TypeParameters: - return token() === SyntaxKind.InKeyword || token() === SyntaxKind.ConstKeyword || isIdentifier(); - case ParsingContext.ArrayLiteralMembers: - switch (token()) { - case SyntaxKind.CommaToken: - case SyntaxKind.DotToken: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`) - return true; - } - // falls through - case ParsingContext.ArgumentExpressions: - return token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); - case ParsingContext.Parameters: - return isStartOfParameter(/*isJSDocParameter*/ false); - case ParsingContext.JSDocParameters: - return isStartOfParameter(/*isJSDocParameter*/ true); - case ParsingContext.TypeArguments: - case ParsingContext.TupleElementTypes: - return token() === SyntaxKind.CommaToken || isStartOfType(); - case ParsingContext.HeritageClauses: - return isHeritageClause(); - case ParsingContext.ImportOrExportSpecifiers: - // bail out if the next token is [FromKeyword StringLiteral]. - // That means we're in something like `import { from "mod"`. Stop here can give better error message. - if (token() === SyntaxKind.FromKeyword && lookAhead(nextTokenIsStringLiteral)) { - return false; - } - if (token() === SyntaxKind.StringLiteral) { - return true; // For "arbitrary module namespace identifiers" - } - return tokenIsIdentifierOrKeyword(token()); - case ParsingContext.JsxAttributes: - return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.OpenBraceToken; - case ParsingContext.JsxChildren: - return true; - case ParsingContext.JSDocComment: - return true; - case ParsingContext.Count: - return Debug.fail("ParsingContext.Count used as a context"); // Not a real context, only a marker. - default: - Debug.assertNever(parsingContext, "Non-exhaustive case in 'isListElement'."); - } - } - - function isValidHeritageClauseObjectLiteral() { - Debug.assert(token() === SyntaxKind.OpenBraceToken); - if (nextToken() === SyntaxKind.CloseBraceToken) { - // if we see "extends {}" then only treat the {} as what we're extending (and not - // the class body) if we have: - // - // extends {} { - // extends {}, - // extends {} extends - // extends {} implements - - const next = nextToken(); - return next === SyntaxKind.CommaToken || next === SyntaxKind.OpenBraceToken || next === SyntaxKind.ExtendsKeyword || next === SyntaxKind.ImplementsKeyword; - } - - return true; - } - - function nextTokenIsIdentifier() { - nextToken(); - return isIdentifier(); - } - - function nextTokenIsIdentifierOrKeyword() { - nextToken(); - return tokenIsIdentifierOrKeyword(token()); - } - - function nextTokenIsIdentifierOrKeywordOrGreaterThan() { - nextToken(); - return tokenIsIdentifierOrKeywordOrGreaterThan(token()); - } - - function isHeritageClauseExtendsOrImplementsKeyword(): boolean { - if ( - token() === SyntaxKind.ImplementsKeyword || - token() === SyntaxKind.ExtendsKeyword - ) { - return lookAhead(nextTokenIsStartOfExpression); - } - - return false; - } - - function nextTokenIsStartOfExpression() { - nextToken(); - return isStartOfExpression(); - } - - function nextTokenIsStartOfType() { - nextToken(); - return isStartOfType(); - } - - // True if positioned at a list terminator - function isListTerminator(kind: ParsingContext): boolean { - if (token() === SyntaxKind.EndOfFileToken) { - // Being at the end of the file ends all lists. - return true; - } - - switch (kind) { - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauses: - case ParsingContext.TypeMembers: - case ParsingContext.ClassMembers: - case ParsingContext.EnumMembers: - case ParsingContext.ObjectLiteralMembers: - case ParsingContext.ObjectBindingElements: - case ParsingContext.ImportOrExportSpecifiers: - case ParsingContext.ImportAttributes: - return token() === SyntaxKind.CloseBraceToken; - case ParsingContext.SwitchClauseStatements: - return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; - case ParsingContext.HeritageClauseElement: - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; - case ParsingContext.VariableDeclarations: - return isVariableDeclaratorListTerminator(); - case ParsingContext.TypeParameters: - // Tokens other than '>' are here for better error recovery - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; - case ParsingContext.ArgumentExpressions: - // Tokens other than ')' are here for better error recovery - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.SemicolonToken; - case ParsingContext.ArrayLiteralMembers: - case ParsingContext.TupleElementTypes: - case ParsingContext.ArrayBindingElements: - return token() === SyntaxKind.CloseBracketToken; - case ParsingContext.JSDocParameters: - case ParsingContext.Parameters: - case ParsingContext.RestProperties: - // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery - return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/; - case ParsingContext.TypeArguments: - // All other tokens should cause the type-argument to terminate except comma token - return token() !== SyntaxKind.CommaToken; - case ParsingContext.HeritageClauses: - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken; - case ParsingContext.JsxAttributes: - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.SlashToken; - case ParsingContext.JsxChildren: - return token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash); - default: - return false; - } - } - - function isVariableDeclaratorListTerminator(): boolean { - // If we can consume a semicolon (either explicitly, or with ASI), then consider us done - // with parsing the list of variable declarators. - if (canParseSemicolon()) { - return true; - } - - // in the case where we're parsing the variable declarator of a 'for-in' statement, we - // are done if we see an 'in' keyword in front of us. Same with for-of - if (isInOrOfKeyword(token())) { - return true; - } - - // ERROR RECOVERY TWEAK: - // For better error recovery, if we see an '=>' then we just stop immediately. We've got an - // arrow function here and it's going to be very unlikely that we'll resynchronize and get - // another variable declaration. - if (token() === SyntaxKind.EqualsGreaterThanToken) { - return true; - } - - // Keep trying to parse out variable declarators. - return false; - } - - // True if positioned at element or terminator of the current list or any enclosing list - function isInSomeParsingContext(): boolean { - // We should be in at least one parsing context, be it SourceElements while parsing - // a SourceFile, or JSDocComment when lazily parsing JSDoc. - Debug.assert(parsingContext, "Missing parsing context"); - for (let kind = 0; kind < ParsingContext.Count; kind++) { - if (parsingContext & (1 << kind)) { - if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) { - return true; - } - } - } - - return false; - } - - // Parses a list of elements - function parseList(kind: ParsingContext, parseElement: () => T): NodeArray { - const saveParsingContext = parsingContext; - parsingContext |= 1 << kind; - const list = []; - const listPos = getNodePos(); - - while (!isListTerminator(kind)) { - if (isListElement(kind, /*inErrorRecovery*/ false)) { - list.push(parseListElement(kind, parseElement)); - - continue; - } - - if (abortParsingListOrMoveToNextToken(kind)) { - break; - } - } - - parsingContext = saveParsingContext; - return createNodeArray(list, listPos); - } - - function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { - const node = currentNode(parsingContext); - if (node) { - return consumeNode(node) as T; - } - - return parseElement(); - } - - function currentNode(parsingContext: ParsingContext, pos?: number): Node | undefined { - // If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse. - // - // If there is an outstanding parse error that we've encountered, but not attached to - // some node, then we cannot get a node from the old source tree. This is because we - // want to mark the next node we encounter as being unusable. - // - // Note: This may be too conservative. Perhaps we could reuse the node and set the bit - // on it (or its leftmost child) as having the error. For now though, being conservative - // is nice and likely won't ever affect perf. - if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) { - return undefined; - } - - const node = syntaxCursor.currentNode(pos ?? scanner.getTokenFullStart()); - - // Can't reuse a missing node. - // Can't reuse a node that intersected the change range. - // Can't reuse a node that contains a parse error. This is necessary so that we - // produce the same set of errors again. - if (nodeIsMissing(node) || intersectsIncrementalChange(node) || containsParseError(node)) { - return undefined; - } - - // We can only reuse a node if it was parsed under the same strict mode that we're - // currently in. i.e. if we originally parsed a node in non-strict mode, but then - // the user added 'using strict' at the top of the file, then we can't use that node - // again as the presence of strict mode may cause us to parse the tokens in the file - // differently. - // - // Note: we *can* reuse tokens when the strict mode changes. That's because tokens - // are unaffected by strict mode. It's just the parser will decide what to do with it - // differently depending on what mode it is in. - // - // This also applies to all our other context flags as well. - const nodeContextFlags = node.flags & NodeFlags.ContextFlags; - if (nodeContextFlags !== contextFlags) { - return undefined; - } - - // Ok, we have a node that looks like it could be reused. Now verify that it is valid - // in the current list parsing context that we're currently at. - if (!canReuseNode(node, parsingContext)) { - return undefined; - } - - if (canHaveJSDoc(node) && node.jsDoc?.jsDocCache) { - // jsDocCache may include tags from parent nodes, which might have been modified. - node.jsDoc.jsDocCache = undefined; - } - - return node; - } - - function consumeNode(node: Node) { - // Move the scanner so it is after the node we just consumed. - scanner.resetTokenState(node.end); - nextToken(); - return node; - } - - function isReusableParsingContext(parsingContext: ParsingContext): boolean { - switch (parsingContext) { - case ParsingContext.ClassMembers: - case ParsingContext.SwitchClauses: - case ParsingContext.SourceElements: - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauseStatements: - case ParsingContext.EnumMembers: - case ParsingContext.TypeMembers: - case ParsingContext.VariableDeclarations: - case ParsingContext.JSDocParameters: - case ParsingContext.Parameters: - return true; - } - return false; - } - - function canReuseNode(node: Node, parsingContext: ParsingContext): boolean { - switch (parsingContext) { - case ParsingContext.ClassMembers: - return isReusableClassMember(node); - - case ParsingContext.SwitchClauses: - return isReusableSwitchClause(node); - - case ParsingContext.SourceElements: - case ParsingContext.BlockStatements: - case ParsingContext.SwitchClauseStatements: - return isReusableStatement(node); - - case ParsingContext.EnumMembers: - return isReusableEnumMember(node); - - case ParsingContext.TypeMembers: - return isReusableTypeMember(node); - - case ParsingContext.VariableDeclarations: - return isReusableVariableDeclaration(node); - - case ParsingContext.JSDocParameters: - case ParsingContext.Parameters: - return isReusableParameter(node); - - // Any other lists we do not care about reusing nodes in. But feel free to add if - // you can do so safely. Danger areas involve nodes that may involve speculative - // parsing. If speculative parsing is involved with the node, then the range the - // parser reached while looking ahead might be in the edited range (see the example - // in canReuseVariableDeclaratorNode for a good case of this). - - // case ParsingContext.HeritageClauses: - // This would probably be safe to reuse. There is no speculative parsing with - // heritage clauses. - - // case ParsingContext.TypeParameters: - // This would probably be safe to reuse. There is no speculative parsing with - // type parameters. Note that that's because type *parameters* only occur in - // unambiguous *type* contexts. While type *arguments* occur in very ambiguous - // *expression* contexts. - - // case ParsingContext.TupleElementTypes: - // This would probably be safe to reuse. There is no speculative parsing with - // tuple types. - - // Technically, type argument list types are probably safe to reuse. While - // speculative parsing is involved with them (since type argument lists are only - // produced from speculative parsing a < as a type argument list), we only have - // the types because speculative parsing succeeded. Thus, the lookahead never - // went past the end of the list and rewound. - // case ParsingContext.TypeArguments: - - // Note: these are almost certainly not safe to ever reuse. Expressions commonly - // need a large amount of lookahead, and we should not reuse them as they may - // have actually intersected the edit. - // case ParsingContext.ArgumentExpressions: - - // This is not safe to reuse for the same reason as the 'AssignmentExpression' - // cases. i.e. a property assignment may end with an expression, and thus might - // have lookahead far beyond it's old node. - // case ParsingContext.ObjectLiteralMembers: - - // This is probably not safe to reuse. There can be speculative parsing with - // type names in a heritage clause. There can be generic names in the type - // name list, and there can be left hand side expressions (which can have type - // arguments.) - // case ParsingContext.HeritageClauseElement: - - // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes - // on any given element. Same for children. - // case ParsingContext.JsxAttributes: - // case ParsingContext.JsxChildren: - } - - return false; - } - - function isReusableClassMember(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.Constructor: - case SyntaxKind.IndexSignature: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.SemicolonClassElement: - return true; - case SyntaxKind.MethodDeclaration: - // Method declarations are not necessarily reusable. An object-literal - // may have a method calls "constructor(...)" and we must reparse that - // into an actual .ConstructorDeclaration. - const methodDeclaration = node as MethodDeclaration; - const nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier && - methodDeclaration.name.escapedText === "constructor"; - - return !nameIsConstructor; - } - } - - return false; - } - - function isReusableSwitchClause(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.CaseClause: - case SyntaxKind.DefaultClause: - return true; - } - } - - return false; - } - - function isReusableStatement(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.VariableStatement: - case SyntaxKind.Block: - case SyntaxKind.IfStatement: - case SyntaxKind.ExpressionStatement: - case SyntaxKind.ThrowStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.BreakStatement: - case SyntaxKind.ContinueStatement: - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - case SyntaxKind.ForStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.EmptyStatement: - case SyntaxKind.TryStatement: - case SyntaxKind.LabeledStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.DebuggerStatement: - case SyntaxKind.ImportDeclaration: - case SyntaxKind.ImportEqualsDeclaration: - case SyntaxKind.ExportDeclaration: - case SyntaxKind.ExportAssignment: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - case SyntaxKind.TypeAliasDeclaration: - return true; - } - } - - return false; - } - - function isReusableEnumMember(node: Node) { - return node.kind === SyntaxKind.EnumMember; - } - - function isReusableTypeMember(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.ConstructSignature: - case SyntaxKind.MethodSignature: - case SyntaxKind.IndexSignature: - case SyntaxKind.PropertySignature: - case SyntaxKind.CallSignature: - return true; - } - } - - return false; - } - - function isReusableVariableDeclaration(node: Node) { - if (node.kind !== SyntaxKind.VariableDeclaration) { - return false; - } - - // Very subtle incremental parsing bug. Consider the following code: - // - // let v = new List < A, B - // - // This is actually legal code. It's a list of variable declarators "v = new List() - // - // then we have a problem. "v = new List(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray; - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray> | undefined; - function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray> | undefined { - const saveParsingContext = parsingContext; - parsingContext |= 1 << kind; - const list: NonNullable[] = []; - const listPos = getNodePos(); - - let commaStart = -1; // Meaning the previous token was not a comma - while (true) { - if (isListElement(kind, /*inErrorRecovery*/ false)) { - const startPos = scanner.getTokenFullStart(); - const result = parseListElement(kind, parseElement); - if (!result) { - parsingContext = saveParsingContext; - return undefined; - } - list.push(result); - commaStart = scanner.getTokenStart(); - - if (parseOptional(SyntaxKind.CommaToken)) { - // No need to check for a zero length node since we know we parsed a comma - continue; - } - - commaStart = -1; // Back to the state where the last token was not a comma - if (isListTerminator(kind)) { - break; - } - - // We didn't get a comma, and the list wasn't terminated, explicitly parse - // out a comma so we give a good error message. - parseExpected(SyntaxKind.CommaToken, getExpectedCommaDiagnostic(kind)); - - // If the token was a semicolon, and the caller allows that, then skip it and - // continue. This ensures we get back on track and don't result in tons of - // parse errors. For example, this can happen when people do things like use - // a semicolon to delimit object literal members. Note: we'll have already - // reported an error when we called parseExpected above. - if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) { - nextToken(); - } - if (startPos === scanner.getTokenFullStart()) { - // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever - // Consume a token to advance the parser in some way and avoid an infinite loop - // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions, - // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied - nextToken(); - } - continue; - } - - if (isListTerminator(kind)) { - break; - } - - if (abortParsingListOrMoveToNextToken(kind)) { - break; - } - } - - parsingContext = saveParsingContext; - // Recording the trailing comma is deliberately done after the previous - // loop, and not just if we see a list terminator. This is because the list - // may have ended incorrectly, but it is still important to know if there - // was a trailing comma. - // Check if the last token was a comma. - // Always preserve a trailing comma by marking it on the NodeArray - return createNodeArray(list, listPos, /*end*/ undefined, commaStart >= 0); - } - - function getExpectedCommaDiagnostic(kind: ParsingContext) { - return kind === ParsingContext.EnumMembers ? Diagnostics.An_enum_member_name_must_be_followed_by_a_or : undefined; - } - - interface MissingList extends NodeArray { - isMissingList: true; - } - - function createMissingList(): MissingList { - const list = createNodeArray([], getNodePos()) as MissingList; - list.isMissingList = true; - return list; - } - - function isMissingList(arr: NodeArray): boolean { - return !!(arr as MissingList).isMissingList; - } - - function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: PunctuationSyntaxKind, close: PunctuationSyntaxKind): NodeArray { - if (parseExpected(open)) { - const result = parseDelimitedList(kind, parseElement); - parseExpected(close); - return result; - } - - return createMissingList(); - } - - function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { - const pos = getNodePos(); - let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); - while (parseOptional(SyntaxKind.DotToken)) { - if (token() === SyntaxKind.LessThanToken) { - // The entity is part of a JSDoc-style generic. We will use the gap between `typeName` and - // `typeArguments` to report it as a grammar error in the checker. - break; - } - entity = finishNode( - factory.createQualifiedName( - entity, - parseRightSideOfDot(allowReservedWords, /*allowPrivateIdentifiers*/ false, /*allowUnicodeEscapeSequenceInIdentifierName*/ true) as Identifier, - ), - pos, - ); - } - return entity; - } - - function createQualifiedName(entity: EntityName, name: Identifier): QualifiedName { - return finishNode(factory.createQualifiedName(entity, name), entity.pos); - } - - function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean, allowUnicodeEscapeSequenceInIdentifierName: boolean): Identifier | PrivateIdentifier { - // Technically a keyword is valid here as all identifiers and keywords are identifier names. - // However, often we'll encounter this in error situations when the identifier or keyword - // is actually starting another valid construct. - // - // So, we check for the following specific case: - // - // name. - // identifierOrKeyword identifierNameOrKeyword - // - // Note: the newlines are important here. For example, if that above code - // were rewritten into: - // - // name.identifierOrKeyword - // identifierNameOrKeyword - // - // Then we would consider it valid. That's because ASI would take effect and - // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". - // In the first case though, ASI will not take effect because there is not a - // line terminator after the identifier or keyword. - if (scanner.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(token())) { - const matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); - - if (matchesPattern) { - // Report that we need an identifier. However, report it right after the dot, - // and not on the next token. This is because the next token might actually - // be an identifier and the error would be quite confusing. - return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); - } - } - - if (token() === SyntaxKind.PrivateIdentifier) { - const node = parsePrivateIdentifier(); - return allowPrivateIdentifiers ? node : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); - } - - if (allowIdentifierNames) { - return allowUnicodeEscapeSequenceInIdentifierName ? parseIdentifierName() : parseIdentifierNameErrorOnUnicodeEscapeSequence(); - } - - return parseIdentifier(); - } - - function parseTemplateSpans(isTaggedTemplate: boolean) { - const pos = getNodePos(); - const list = []; - let node: TemplateSpan; - do { - node = parseTemplateSpan(isTaggedTemplate); - list.push(node); - } - while (node.literal.kind === SyntaxKind.TemplateMiddle); - return createNodeArray(list, pos); - } - - function parseTemplateExpression(isTaggedTemplate: boolean): TemplateExpression { - const pos = getNodePos(); - return finishNode( - factory.createTemplateExpression( - parseTemplateHead(isTaggedTemplate), - parseTemplateSpans(isTaggedTemplate), - ), - pos, - ); - } - - function parseTemplateType(): TemplateLiteralTypeNode { - const pos = getNodePos(); - return finishNode( - factory.createTemplateLiteralType( - parseTemplateHead(/*isTaggedTemplate*/ false), - parseTemplateTypeSpans(), - ), - pos, - ); - } - - function parseTemplateTypeSpans() { - const pos = getNodePos(); - const list = []; - let node: TemplateLiteralTypeSpan; - do { - node = parseTemplateTypeSpan(); - list.push(node); - } - while (node.literal.kind === SyntaxKind.TemplateMiddle); - return createNodeArray(list, pos); - } - - function parseTemplateTypeSpan(): TemplateLiteralTypeSpan { - const pos = getNodePos(); - return finishNode( - factory.createTemplateLiteralTypeSpan( - parseType(), - parseLiteralOfTemplateSpan(/*isTaggedTemplate*/ false), - ), - pos, - ); - } - - function parseLiteralOfTemplateSpan(isTaggedTemplate: boolean) { - if (token() === SyntaxKind.CloseBraceToken) { - reScanTemplateToken(isTaggedTemplate); - return parseTemplateMiddleOrTemplateTail(); - } - else { - // TODO(rbuckton): Do we need to call `parseExpectedToken` or can we just call `createMissingNode` directly? - return parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)) as TemplateTail; - } - } - - function parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan { - const pos = getNodePos(); - return finishNode( - factory.createTemplateSpan( - allowInAnd(parseExpression), - parseLiteralOfTemplateSpan(isTaggedTemplate), - ), - pos, - ); - } - - function parseLiteralNode(): LiteralExpression { - return parseLiteralLikeNode(token()) as LiteralExpression; - } - - function parseTemplateHead(isTaggedTemplate: boolean): TemplateHead { - if (!isTaggedTemplate && scanner.getTokenFlags() & TokenFlags.IsInvalid) { - reScanTemplateToken(/*isTaggedTemplate*/ false); - } - const fragment = parseLiteralLikeNode(token()); - Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); - return fragment as TemplateHead; - } - - function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail { - const fragment = parseLiteralLikeNode(token()); - Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind"); - return fragment as TemplateMiddle | TemplateTail; - } - - function getTemplateLiteralRawText(kind: TemplateLiteralToken["kind"]) { - const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; - const tokenText = scanner.getTokenText(); - return tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); - } - - function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode { - const pos = getNodePos(); - const node = isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, scanner.getTokenValue(), getTemplateLiteralRawText(kind), scanner.getTokenFlags() & TokenFlags.TemplateLiteralLikeFlags) : - // Note that theoretically the following condition would hold true literals like 009, - // which is not octal. But because of how the scanner separates the tokens, we would - // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. - // We also do not need to check for negatives because any prefix operator would be part of a - // parent unary expression. - kind === SyntaxKind.NumericLiteral ? factoryCreateNumericLiteral(scanner.getTokenValue(), scanner.getNumericLiteralFlags()) : - kind === SyntaxKind.StringLiteral ? factoryCreateStringLiteral(scanner.getTokenValue(), /*isSingleQuote*/ undefined, scanner.hasExtendedUnicodeEscape()) : - isLiteralKind(kind) ? factoryCreateLiteralLikeNode(kind, scanner.getTokenValue()) : - Debug.fail(); - - if (scanner.hasExtendedUnicodeEscape()) { - node.hasExtendedUnicodeEscape = true; - } - - if (scanner.isUnterminated()) { - node.isUnterminated = true; - } - - nextToken(); - return finishNode(node, pos); - } - - // TYPES - - function parseEntityNameOfTypeReference() { - return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); - } - - function parseTypeArgumentsOfTypeReference() { - if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) { - return parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); - } - } - - function parseTypeReference(): TypeReferenceNode { - const pos = getNodePos(); - return finishNode( - factory.createTypeReferenceNode( - parseEntityNameOfTypeReference(), - parseTypeArgumentsOfTypeReference(), - ), - pos, - ); - } - - // If true, we should abort parsing an error function. - function typeHasArrowFunctionBlockingParseError(node: TypeNode): boolean { - switch (node.kind) { - case SyntaxKind.TypeReference: - return nodeIsMissing((node as TypeReferenceNode).typeName); - case SyntaxKind.FunctionType: - case SyntaxKind.ConstructorType: { - const { parameters, type } = node as FunctionOrConstructorTypeNode; - return isMissingList(parameters) || typeHasArrowFunctionBlockingParseError(type); - } - case SyntaxKind.ParenthesizedType: - return typeHasArrowFunctionBlockingParseError((node as ParenthesizedTypeNode).type); - default: - return false; - } - } - - function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode { - nextToken(); - return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, lhs, parseType()), lhs.pos); - } - - function parseThisTypeNode(): ThisTypeNode { - const pos = getNodePos(); - nextToken(); - return finishNode(factory.createThisTypeNode(), pos); - } - - function parseJSDocAllType(): JSDocAllType | JSDocOptionalType { - const pos = getNodePos(); - nextToken(); - return finishNode(factory.createJSDocAllType(), pos); - } - - function parseJSDocNonNullableType(): TypeNode { - const pos = getNodePos(); - nextToken(); - return finishNode(factory.createJSDocNonNullableType(parseNonArrayType(), /*postfix*/ false), pos); - } - - function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { - const pos = getNodePos(); - // skip the ? - nextToken(); - - // Need to lookahead to decide if this is a nullable or unknown type. - - // Here are cases where we'll pick the unknown type: - // - // Foo(?, - // { a: ? } - // Foo(?) - // Foo - // Foo(?= - // (?| - if ( - token() === SyntaxKind.CommaToken || - token() === SyntaxKind.CloseBraceToken || - token() === SyntaxKind.CloseParenToken || - token() === SyntaxKind.GreaterThanToken || - token() === SyntaxKind.EqualsToken || - token() === SyntaxKind.BarToken - ) { - return finishNode(factory.createJSDocUnknownType(), pos); - } - else { - return finishNode(factory.createJSDocNullableType(parseType(), /*postfix*/ false), pos); - } - } - - function parseJSDocFunctionType(): JSDocFunctionType | TypeReferenceNode { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - if (tryParse(nextTokenIsOpenParen)) { - const parameters = parseParameters(SignatureFlags.Type | SignatureFlags.JSDoc); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - return withJSDoc(finishNode(factory.createJSDocFunctionType(parameters, type), pos), hasJSDoc); - } - return finishNode(factory.createTypeReferenceNode(parseIdentifierName(), /*typeArguments*/ undefined), pos); - } - - function parseJSDocParameter(): ParameterDeclaration { - const pos = getNodePos(); - let name: Identifier | undefined; - if (token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword) { - name = parseIdentifierName(); - parseExpected(SyntaxKind.ColonToken); - } - return finishNode( - factory.createParameterDeclaration( - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - // TODO(rbuckton): JSDoc parameters don't have names (except `this`/`new`), should we manufacture an empty identifier? - name!, - /*questionToken*/ undefined, - parseJSDocType(), - /*initializer*/ undefined, - ), - pos, - ); - } - - function parseJSDocType(): TypeNode { - scanner.setSkipJsDocLeadingAsterisks(true); - const pos = getNodePos(); - if (parseOptional(SyntaxKind.ModuleKeyword)) { - // TODO(rbuckton): We never set the type for a JSDocNamepathType. What should we put here? - const moduleTag = factory.createJSDocNamepathType(/*type*/ undefined!); - terminate: - while (true) { - switch (token()) { - case SyntaxKind.CloseBraceToken: - case SyntaxKind.EndOfFileToken: - case SyntaxKind.CommaToken: - case SyntaxKind.WhitespaceTrivia: - break terminate; - default: - nextTokenJSDoc(); - } - } - - scanner.setSkipJsDocLeadingAsterisks(false); - return finishNode(moduleTag, pos); - } - - const hasDotDotDot = parseOptional(SyntaxKind.DotDotDotToken); - let type = parseTypeOrTypePredicate(); - scanner.setSkipJsDocLeadingAsterisks(false); - if (hasDotDotDot) { - type = finishNode(factory.createJSDocVariadicType(type), pos); - } - if (token() === SyntaxKind.EqualsToken) { - nextToken(); - return finishNode(factory.createJSDocOptionalType(type), pos); - } - return type; - } - - function parseTypeQuery(): TypeQueryNode { - const pos = getNodePos(); - parseExpected(SyntaxKind.TypeOfKeyword); - const entityName = parseEntityName(/*allowReservedWords*/ true); - // Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression. - const typeArguments = !scanner.hasPrecedingLineBreak() ? tryParseTypeArguments() : undefined; - return finishNode(factory.createTypeQueryNode(entityName, typeArguments), pos); - } - - function parseTypeParameter(): TypeParameterDeclaration { - const pos = getNodePos(); - const modifiers = parseModifiers(/*allowDecorators*/ false, /*permitConstAsModifier*/ true); - const name = parseIdentifier(); - let constraint: TypeNode | undefined; - let expression: Expression | undefined; - if (parseOptional(SyntaxKind.ExtendsKeyword)) { - // It's not uncommon for people to write improper constraints to a generic. If the - // user writes a constraint that is an expression and not an actual type, then parse - // it out as an expression (so we can recover well), but report that a type is needed - // instead. - if (isStartOfType() || !isStartOfExpression()) { - constraint = parseType(); - } - else { - // It was not a type, and it looked like an expression. Parse out an expression - // here so we recover well. Note: it is important that we call parseUnaryExpression - // and not parseExpression here. If the user has: - // - // - // - // We do *not* want to consume the `>` as we're consuming the expression for "". - expression = parseUnaryExpressionOrHigher(); - } - } - - const defaultType = parseOptional(SyntaxKind.EqualsToken) ? parseType() : undefined; - const node = factory.createTypeParameterDeclaration(modifiers, name, constraint, defaultType); - node.expression = expression; - return finishNode(node, pos); - } - - function parseTypeParameters(): NodeArray | undefined { - if (token() === SyntaxKind.LessThanToken) { - return parseBracketedList(ParsingContext.TypeParameters, parseTypeParameter, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); - } - } - - function isStartOfParameter(isJSDocParameter: boolean): boolean { - return token() === SyntaxKind.DotDotDotToken || - isBindingIdentifierOrPrivateIdentifierOrPattern() || - isModifierKind(token()) || - token() === SyntaxKind.AtToken || - isStartOfType(/*inStartOfParameter*/ !isJSDocParameter); - } - - function parseNameOfParameter(modifiers: NodeArray | undefined) { - // FormalParameter [Yield,Await]: - // BindingElement[?Yield,?Await] - const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_cannot_be_used_as_parameters); - if (getFullWidth(name) === 0 && !some(modifiers) && isModifierKind(token())) { - // in cases like - // 'use strict' - // function foo(static) - // isParameter('static') === true, because of isModifier('static') - // however 'static' is not a legal identifier in a strict mode. - // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined) - // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM) - // to avoid this we'll advance cursor to the next token. - nextToken(); - } - return name; - } - - function isParameterNameStart() { - // Be permissive about await and yield by calling isBindingIdentifier instead of isIdentifier; disallowing - // them during a speculative parse leads to many more follow-on errors than allowing the function to parse then later - // complaining about the use of the keywords. - return isBindingIdentifier() || token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken; - } - - function parseParameter(inOuterAwaitContext: boolean): ParameterDeclaration { - return parseParameterWorker(inOuterAwaitContext); - } - - function parseParameterForSpeculation(inOuterAwaitContext: boolean): ParameterDeclaration | undefined { - return parseParameterWorker(inOuterAwaitContext, /*allowAmbiguity*/ false); - } - - function parseParameterWorker(inOuterAwaitContext: boolean): ParameterDeclaration; - function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity: false): ParameterDeclaration | undefined; - function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity = true): ParameterDeclaration | undefined { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - - // FormalParameter [Yield,Await]: - // BindingElement[?Yield,?Await] - - // Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context. - const modifiers = inOuterAwaitContext ? - doInAwaitContext(() => parseModifiers(/*allowDecorators*/ true)) : - doOutsideOfAwaitContext(() => parseModifiers(/*allowDecorators*/ true)); - - if (token() === SyntaxKind.ThisKeyword) { - const node = factory.createParameterDeclaration( - modifiers, - /*dotDotDotToken*/ undefined, - createIdentifier(/*isIdentifier*/ true), - /*questionToken*/ undefined, - parseTypeAnnotation(), - /*initializer*/ undefined, - ); - - const modifier = firstOrUndefined(modifiers); - if (modifier) { - parseErrorAtRange(modifier, Diagnostics.Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters); - } - - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - const savedTopLevel = topLevel; - topLevel = false; - - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - - if (!allowAmbiguity && !isParameterNameStart()) { - return undefined; - } - - const node = withJSDoc( - finishNode( - factory.createParameterDeclaration( - modifiers, - dotDotDotToken, - parseNameOfParameter(modifiers), - parseOptionalToken(SyntaxKind.QuestionToken), - parseTypeAnnotation(), - parseInitializer(), - ), - pos, - ), - hasJSDoc, - ); - topLevel = savedTopLevel; - return node; - } - - function parseReturnType(returnToken: SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode; - function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined; - function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean) { - if (shouldParseReturnType(returnToken, isType)) { - return allowConditionalTypesAnd(parseTypeOrTypePredicate); - } - } - - function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { - if (returnToken === SyntaxKind.EqualsGreaterThanToken) { - parseExpected(returnToken); - return true; - } - else if (parseOptional(SyntaxKind.ColonToken)) { - return true; - } - else if (isType && token() === SyntaxKind.EqualsGreaterThanToken) { - // This is easy to get backward, especially in type contexts, so parse the type anyway - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); - nextToken(); - return true; - } - return false; - } - - function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: true): NodeArray; - function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: false): NodeArray | undefined; - function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: boolean): NodeArray | undefined { - // FormalParameters [Yield,Await]: (modified) - // [empty] - // FormalParameterList[?Yield,Await] - // - // FormalParameter[Yield,Await]: (modified) - // BindingElement[?Yield,Await] - // - // BindingElement [Yield,Await]: (modified) - // SingleNameBinding[?Yield,?Await] - // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - // - // SingleNameBinding [Yield,Await]: - // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - const savedYieldContext = inYieldContext(); - const savedAwaitContext = inAwaitContext(); - - setYieldContext(!!(flags & SignatureFlags.Yield)); - setAwaitContext(!!(flags & SignatureFlags.Await)); - - const parameters = flags & SignatureFlags.JSDoc ? - parseDelimitedList(ParsingContext.JSDocParameters, parseJSDocParameter) : - parseDelimitedList(ParsingContext.Parameters, () => allowAmbiguity ? parseParameter(savedAwaitContext) : parseParameterForSpeculation(savedAwaitContext)); - - setYieldContext(savedYieldContext); - setAwaitContext(savedAwaitContext); - - return parameters; - } - - function parseParameters(flags: SignatureFlags): NodeArray { - // FormalParameters [Yield,Await]: (modified) - // [empty] - // FormalParameterList[?Yield,Await] - // - // FormalParameter[Yield,Await]: (modified) - // BindingElement[?Yield,Await] - // - // BindingElement [Yield,Await]: (modified) - // SingleNameBinding[?Yield,?Await] - // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - // - // SingleNameBinding [Yield,Await]: - // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt - if (!parseExpected(SyntaxKind.OpenParenToken)) { - return createMissingList(); - } - - const parameters = parseParametersWorker(flags, /*allowAmbiguity*/ true); - parseExpected(SyntaxKind.CloseParenToken); - return parameters; - } - - function parseTypeMemberSemicolon() { - // We allow type members to be separated by commas or (possibly ASI) semicolons. - // First check if it was a comma. If so, we're done with the member. - if (parseOptional(SyntaxKind.CommaToken)) { - return; - } - - // Didn't have a comma. We must have a (possible ASI) semicolon. - parseSemicolon(); - } - - function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - if (kind === SyntaxKind.ConstructSignature) { - parseExpected(SyntaxKind.NewKeyword); - } - - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(SignatureFlags.Type); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); - parseTypeMemberSemicolon(); - const node = kind === SyntaxKind.CallSignature - ? factory.createCallSignature(typeParameters, parameters, type) - : factory.createConstructSignature(typeParameters, parameters, type); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function isIndexSignature(): boolean { - return token() === SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); - } - - function isUnambiguouslyIndexSignature() { - // The only allowed sequence is: - // - // [id: - // - // However, for error recovery, we also check the following cases: - // - // [... - // [id, - // [id?, - // [id?: - // [id?] - // [public id - // [private id - // [protected id - // [] - // - nextToken(); - if (token() === SyntaxKind.DotDotDotToken || token() === SyntaxKind.CloseBracketToken) { - return true; - } - - if (isModifierKind(token())) { - nextToken(); - if (isIdentifier()) { - return true; - } - } - else if (!isIdentifier()) { - return false; - } - else { - // Skip the identifier - nextToken(); - } - - // A colon signifies a well formed indexer - // A comma should be a badly formed indexer because comma expressions are not allowed - // in computed properties. - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken) { - return true; - } - - // Question mark could be an indexer with an optional property, - // or it could be a conditional expression in a computed property. - if (token() !== SyntaxKind.QuestionToken) { - return false; - } - - // If any of the following tokens are after the question mark, it cannot - // be a conditional expression, so treat it as an indexer. - nextToken(); - return token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBracketToken; - } - - function parseIndexSignatureDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): IndexSignatureDeclaration { - const parameters = parseBracketedList(ParsingContext.Parameters, () => parseParameter(/*inOuterAwaitContext*/ false), SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); - const type = parseTypeAnnotation(); - parseTypeMemberSemicolon(); - const node = factory.createIndexSignature(modifiers, parameters, type); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parsePropertyOrMethodSignature(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): PropertySignature | MethodSignature { - const name = parsePropertyName(); - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - let node: PropertySignature | MethodSignature; - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - // Method signatures don't exist in expression contexts. So they have neither - // [Yield] nor [Await] - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(SignatureFlags.Type); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); - node = factory.createMethodSignature(modifiers, name, questionToken, typeParameters, parameters, type); - } - else { - const type = parseTypeAnnotation(); - node = factory.createPropertySignature(modifiers, name, questionToken, type); - // Although type literal properties cannot not have initializers, we attempt - // to parse an initializer so we can report in the checker that an interface - // property or type literal property cannot have an initializer. - if (token() === SyntaxKind.EqualsToken) (node as Mutable).initializer = parseInitializer(); - } - parseTypeMemberSemicolon(); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function isTypeMemberStart(): boolean { - // Return true if we have the start of a signature member - if ( - token() === SyntaxKind.OpenParenToken || - token() === SyntaxKind.LessThanToken || - token() === SyntaxKind.GetKeyword || - token() === SyntaxKind.SetKeyword - ) { - return true; - } - let idToken = false; - // Eat up all modifiers, but hold on to the last one in case it is actually an identifier - while (isModifierKind(token())) { - idToken = true; - nextToken(); - } - // Index signatures and computed property names are type members - if (token() === SyntaxKind.OpenBracketToken) { - return true; - } - // Try to get the first property-like token following all modifiers - if (isLiteralPropertyName()) { - idToken = true; - nextToken(); - } - // If we were able to get any potential identifier, check that it is - // the start of a member declaration - if (idToken) { - return token() === SyntaxKind.OpenParenToken || - token() === SyntaxKind.LessThanToken || - token() === SyntaxKind.QuestionToken || - token() === SyntaxKind.ColonToken || - token() === SyntaxKind.CommaToken || - canParseSemicolon(); - } - return false; - } - - function parseTypeMember(): TypeElement { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseSignatureMember(SyntaxKind.CallSignature); - } - if (token() === SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { - return parseSignatureMember(SyntaxKind.ConstructSignature); - } - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const modifiers = parseModifiers(/*allowDecorators*/ false); - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.GetAccessor, SignatureFlags.Type); - } - - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.SetAccessor, SignatureFlags.Type); - } - - if (isIndexSignature()) { - return parseIndexSignatureDeclaration(pos, hasJSDoc, modifiers); - } - return parsePropertyOrMethodSignature(pos, hasJSDoc, modifiers); - } - - function nextTokenIsOpenParenOrLessThan() { - nextToken(); - return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken; - } - - function nextTokenIsDot() { - return nextToken() === SyntaxKind.DotToken; - } - - function nextTokenIsOpenParenOrLessThanOrDot() { - switch (nextToken()) { - case SyntaxKind.OpenParenToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.DotToken: - return true; - } - return false; - } - - function parseTypeLiteral(): TypeLiteralNode { - const pos = getNodePos(); - return finishNode(factory.createTypeLiteralNode(parseObjectTypeMembers()), pos); - } - - function parseObjectTypeMembers(): NodeArray { - let members: NodeArray; - if (parseExpected(SyntaxKind.OpenBraceToken)) { - members = parseList(ParsingContext.TypeMembers, parseTypeMember); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - members = createMissingList(); - } - - return members; - } - - function isStartOfMappedType() { - nextToken(); - if (token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - return nextToken() === SyntaxKind.ReadonlyKeyword; - } - if (token() === SyntaxKind.ReadonlyKeyword) { - nextToken(); - } - return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword; - } - - function parseMappedTypeParameter() { - const pos = getNodePos(); - const name = parseIdentifierName(); - parseExpected(SyntaxKind.InKeyword); - const type = parseType(); - return finishNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, type, /*defaultType*/ undefined), pos); - } - - function parseMappedType() { - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); - let readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined; - if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - readonlyToken = parseTokenNode(); - if (readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { - parseExpected(SyntaxKind.ReadonlyKeyword); - } - } - parseExpected(SyntaxKind.OpenBracketToken); - const typeParameter = parseMappedTypeParameter(); - const nameType = parseOptional(SyntaxKind.AsKeyword) ? parseType() : undefined; - parseExpected(SyntaxKind.CloseBracketToken); - let questionToken: QuestionToken | PlusToken | MinusToken | undefined; - if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { - questionToken = parseTokenNode(); - if (questionToken.kind !== SyntaxKind.QuestionToken) { - parseExpected(SyntaxKind.QuestionToken); - } - } - const type = parseTypeAnnotation(); - parseSemicolon(); - const members = parseList(ParsingContext.TypeMembers, parseTypeMember); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type, members), pos); - } - - function parseTupleElementType() { - const pos = getNodePos(); - if (parseOptional(SyntaxKind.DotDotDotToken)) { - return finishNode(factory.createRestTypeNode(parseType()), pos); - } - const type = parseType(); - if (isJSDocNullableType(type) && type.pos === type.type.pos) { - const node = factory.createOptionalTypeNode(type.type); - setTextRange(node, type); - (node as Mutable).flags = type.flags; - return node; - } - return type; - } - - function isNextTokenColonOrQuestionColon() { - return nextToken() === SyntaxKind.ColonToken || (token() === SyntaxKind.QuestionToken && nextToken() === SyntaxKind.ColonToken); - } - - function isTupleElementName() { - if (token() === SyntaxKind.DotDotDotToken) { - return tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon(); - } - return tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon(); - } - - function parseTupleElementNameOrTupleElementType() { - if (lookAhead(isTupleElementName)) { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - const name = parseIdentifierName(); - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - parseExpected(SyntaxKind.ColonToken); - const type = parseTupleElementType(); - const node = factory.createNamedTupleMember(dotDotDotToken, name, questionToken, type); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - return parseTupleElementType(); - } - - function parseTupleType(): TupleTypeNode { - const pos = getNodePos(); - return finishNode( - factory.createTupleTypeNode( - parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken), - ), - pos, - ); - } - - function parseParenthesizedType(): TypeNode { - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenParenToken); - const type = parseType(); - parseExpected(SyntaxKind.CloseParenToken); - return finishNode(factory.createParenthesizedType(type), pos); - } - - function parseModifiersForConstructorType(): NodeArray | undefined { - let modifiers: NodeArray | undefined; - if (token() === SyntaxKind.AbstractKeyword) { - const pos = getNodePos(); - nextToken(); - const modifier = finishNode(factoryCreateToken(SyntaxKind.AbstractKeyword), pos); - modifiers = createNodeArray([modifier], pos); - } - return modifiers; - } - - function parseFunctionOrConstructorType(): TypeNode { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const modifiers = parseModifiersForConstructorType(); - const isConstructorType = parseOptional(SyntaxKind.NewKeyword); - Debug.assert(!modifiers || isConstructorType, "Per isStartOfFunctionOrConstructorType, a function type cannot have modifiers."); - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(SignatureFlags.Type); - const type = parseReturnType(SyntaxKind.EqualsGreaterThanToken, /*isType*/ false); - const node = isConstructorType - ? factory.createConstructorTypeNode(modifiers, typeParameters, parameters, type) - : factory.createFunctionTypeNode(typeParameters, parameters, type); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseKeywordAndNoDot(): TypeNode | undefined { - const node = parseTokenNode(); - return token() === SyntaxKind.DotToken ? undefined : node; - } - - function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode { - const pos = getNodePos(); - if (negative) { - nextToken(); - } - let expression: BooleanLiteral | NullLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword || token() === SyntaxKind.NullKeyword ? - parseTokenNode() : - parseLiteralLikeNode(token()) as LiteralExpression; - if (negative) { - expression = finishNode(factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, expression), pos); - } - return finishNode(factory.createLiteralTypeNode(expression), pos); - } - - function isStartOfTypeOfImportType() { - nextToken(); - return token() === SyntaxKind.ImportKeyword; - } - - function parseImportType(): ImportTypeNode { - sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; - const pos = getNodePos(); - const isTypeOf = parseOptional(SyntaxKind.TypeOfKeyword); - parseExpected(SyntaxKind.ImportKeyword); - parseExpected(SyntaxKind.OpenParenToken); - const type = parseType(); - let attributes: ImportAttributes | undefined; - if (parseOptional(SyntaxKind.CommaToken)) { - const openBracePosition = scanner.getTokenStart(); - parseExpected(SyntaxKind.OpenBraceToken); - const currentToken = token(); - if (currentToken === SyntaxKind.WithKeyword || currentToken === SyntaxKind.AssertKeyword) { - nextToken(); - } - else { - parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.WithKeyword)); - } - parseExpected(SyntaxKind.ColonToken); - attributes = parseImportAttributes(currentToken as SyntaxKind.WithKeyword | SyntaxKind.AssertKeyword, /*skipKeyword*/ true); - parseOptional(SyntaxKind.CommaToken); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, sourceText, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}"), - ); - } - } - } - parseExpected(SyntaxKind.CloseParenToken); - const qualifier = parseOptional(SyntaxKind.DotToken) ? parseEntityNameOfTypeReference() : undefined; - const typeArguments = parseTypeArgumentsOfTypeReference(); - return finishNode(factory.createImportTypeNode(type, attributes, qualifier, typeArguments, isTypeOf), pos); - } - - function nextTokenIsNumericOrBigIntLiteral() { - nextToken(); - return token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral; - } - - function parseNonArrayType(): TypeNode { - switch (token()) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.ObjectKeyword: - // If these are followed by a dot, then parse these out as a dotted type reference instead. - return tryParse(parseKeywordAndNoDot) || parseTypeReference(); - case SyntaxKind.AsteriskEqualsToken: - // If there is '*=', treat it as * followed by postfix = - scanner.reScanAsteriskEqualsToken(); - // falls through - case SyntaxKind.AsteriskToken: - return parseJSDocAllType(); - case SyntaxKind.QuestionQuestionToken: - // If there is '??', treat it as prefix-'?' in JSDoc type. - scanner.reScanQuestionToken(); - // falls through - case SyntaxKind.QuestionToken: - return parseJSDocUnknownOrNullableType(); - case SyntaxKind.FunctionKeyword: - return parseJSDocFunctionType(); - case SyntaxKind.ExclamationToken: - return parseJSDocNonNullableType(); - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NullKeyword: - return parseLiteralTypeNode(); - case SyntaxKind.MinusToken: - return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); - case SyntaxKind.VoidKeyword: - return parseTokenNode(); - case SyntaxKind.ThisKeyword: { - const thisKeyword = parseThisTypeNode(); - if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { - return parseThisTypePredicate(thisKeyword); - } - else { - return thisKeyword; - } - } - case SyntaxKind.TypeOfKeyword: - return lookAhead(isStartOfTypeOfImportType) ? parseImportType() : parseTypeQuery(); - case SyntaxKind.OpenBraceToken: - return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral(); - case SyntaxKind.OpenBracketToken: - return parseTupleType(); - case SyntaxKind.OpenParenToken: - return parseParenthesizedType(); - case SyntaxKind.ImportKeyword: - return parseImportType(); - case SyntaxKind.AssertsKeyword: - return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference(); - case SyntaxKind.TemplateHead: - return parseTemplateType(); - default: - return parseTypeReference(); - } - } - - function isStartOfType(inStartOfParameter?: boolean): boolean { - switch (token()) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.UnknownKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.BigIntKeyword: - case SyntaxKind.BooleanKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.SymbolKeyword: - case SyntaxKind.UniqueKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.UndefinedKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.ThisKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.NeverKeyword: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.BarToken: - case SyntaxKind.AmpersandToken: - case SyntaxKind.NewKeyword: - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.ObjectKeyword: - case SyntaxKind.AsteriskToken: - case SyntaxKind.QuestionToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DotDotDotToken: - case SyntaxKind.InferKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.AssertsKeyword: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - return true; - case SyntaxKind.FunctionKeyword: - return !inStartOfParameter; - case SyntaxKind.MinusToken: - return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral); - case SyntaxKind.OpenParenToken: - // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, - // or something that starts a type. We don't want to consider things like '(1)' a type. - return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); - default: - return isIdentifier(); - } - } - - function isStartOfParenthesizedOrFunctionType() { - nextToken(); - return token() === SyntaxKind.CloseParenToken || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType(); - } - - function parsePostfixTypeOrHigher(): TypeNode { - const pos = getNodePos(); - let type = parseNonArrayType(); - while (!scanner.hasPrecedingLineBreak()) { - switch (token()) { - case SyntaxKind.ExclamationToken: - nextToken(); - type = finishNode(factory.createJSDocNonNullableType(type, /*postfix*/ true), pos); - break; - case SyntaxKind.QuestionToken: - // If next token is start of a type we have a conditional type - if (lookAhead(nextTokenIsStartOfType)) { - return type; - } - nextToken(); - type = finishNode(factory.createJSDocNullableType(type, /*postfix*/ true), pos); - break; - case SyntaxKind.OpenBracketToken: - parseExpected(SyntaxKind.OpenBracketToken); - if (isStartOfType()) { - const indexType = parseType(); - parseExpected(SyntaxKind.CloseBracketToken); - type = finishNode(factory.createIndexedAccessTypeNode(type, indexType), pos); - } - else { - parseExpected(SyntaxKind.CloseBracketToken); - type = finishNode(factory.createArrayTypeNode(type), pos); - } - break; - default: - return type; - } - } - return type; - } - - function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) { - const pos = getNodePos(); - parseExpected(operator); - return finishNode(factory.createTypeOperatorNode(operator, parseTypeOperatorOrHigher()), pos); - } - - function tryParseConstraintOfInferType() { - if (parseOptional(SyntaxKind.ExtendsKeyword)) { - const constraint = disallowConditionalTypesAnd(parseType); - if (inDisallowConditionalTypesContext() || token() !== SyntaxKind.QuestionToken) { - return constraint; - } - } - } - - function parseTypeParameterOfInferType(): TypeParameterDeclaration { - const pos = getNodePos(); - const name = parseIdentifier(); - const constraint = tryParse(tryParseConstraintOfInferType); - const node = factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, constraint); - return finishNode(node, pos); - } - - function parseInferType(): InferTypeNode { - const pos = getNodePos(); - parseExpected(SyntaxKind.InferKeyword); - return finishNode(factory.createInferTypeNode(parseTypeParameterOfInferType()), pos); - } - - function parseTypeOperatorOrHigher(): TypeNode { - const operator = token(); - switch (operator) { - case SyntaxKind.KeyOfKeyword: - case SyntaxKind.UniqueKeyword: - case SyntaxKind.ReadonlyKeyword: - return parseTypeOperator(operator); - case SyntaxKind.InferKeyword: - return parseInferType(); - } - return allowConditionalTypesAnd(parsePostfixTypeOrHigher); - } - - function parseFunctionOrConstructorTypeToError( - isInUnionType: boolean, - ): TypeNode | undefined { - // the function type and constructor type shorthand notation - // are not allowed directly in unions and intersections, but we'll - // try to parse them gracefully and issue a helpful message. - if (isStartOfFunctionTypeOrConstructorType()) { - const type = parseFunctionOrConstructorType(); - let diagnostic: DiagnosticMessage; - if (isFunctionTypeNode(type)) { - diagnostic = isInUnionType - ? Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type - : Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; - } - else { - diagnostic = isInUnionType - ? Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type - : Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; - } - parseErrorAtRange(type, diagnostic); - return type; - } - return undefined; - } - - function parseUnionOrIntersectionType( - operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken, - parseConstituentType: () => TypeNode, - createTypeNode: (types: NodeArray) => UnionOrIntersectionTypeNode, - ): TypeNode { - const pos = getNodePos(); - const isUnionType = operator === SyntaxKind.BarToken; - const hasLeadingOperator = parseOptional(operator); - let type = hasLeadingOperator && parseFunctionOrConstructorTypeToError(isUnionType) - || parseConstituentType(); - if (token() === operator || hasLeadingOperator) { - const types = [type]; - while (parseOptional(operator)) { - types.push(parseFunctionOrConstructorTypeToError(isUnionType) || parseConstituentType()); - } - type = finishNode(createTypeNode(createNodeArray(types, pos)), pos); - } - return type; - } - - function parseIntersectionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.AmpersandToken, parseTypeOperatorOrHigher, factory.createIntersectionTypeNode); - } - - function parseUnionTypeOrHigher(): TypeNode { - return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); - } - - function nextTokenIsNewKeyword(): boolean { - nextToken(); - return token() === SyntaxKind.NewKeyword; - } - - function isStartOfFunctionTypeOrConstructorType(): boolean { - if (token() === SyntaxKind.LessThanToken) { - return true; - } - if (token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) { - return true; - } - return token() === SyntaxKind.NewKeyword || - token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsNewKeyword); - } - - function skipParameterStart(): boolean { - if (isModifierKind(token())) { - // Skip modifiers - parseModifiers(/*allowDecorators*/ false); - } - if (isIdentifier() || token() === SyntaxKind.ThisKeyword) { - nextToken(); - return true; - } - if (token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken) { - // Return true if we can parse an array or object binding pattern with no errors - const previousErrorCount = parseDiagnostics.length; - parseIdentifierOrPattern(); - return previousErrorCount === parseDiagnostics.length; - } - return false; - } - - function isUnambiguouslyStartOfFunctionType() { - nextToken(); - if (token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.DotDotDotToken) { - // ( ) - // ( ... - return true; - } - if (skipParameterStart()) { - // We successfully skipped modifiers (if any) and an identifier or binding pattern, - // now see if we have something that indicates a parameter declaration - if ( - token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || - token() === SyntaxKind.QuestionToken || token() === SyntaxKind.EqualsToken - ) { - // ( xxx : - // ( xxx , - // ( xxx ? - // ( xxx = - return true; - } - if (token() === SyntaxKind.CloseParenToken) { - nextToken(); - if (token() === SyntaxKind.EqualsGreaterThanToken) { - // ( xxx ) => - return true; - } - } - } - return false; - } - - function parseTypeOrTypePredicate(): TypeNode { - const pos = getNodePos(); - const typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); - const type = parseType(); - if (typePredicateVariable) { - return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, typePredicateVariable, type), pos); - } - else { - return type; - } - } - - function parseTypePredicatePrefix() { - const id = parseIdentifier(); - if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { - nextToken(); - return id; - } - } - - function parseAssertsTypePredicate(): TypeNode { - const pos = getNodePos(); - const assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); - const parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); - const type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; - return finishNode(factory.createTypePredicateNode(assertsModifier, parameterName, type), pos); - } - - function parseType(): TypeNode { - if (contextFlags & NodeFlags.TypeExcludesFlags) { - return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseType); - } - if (isStartOfFunctionTypeOrConstructorType()) { - return parseFunctionOrConstructorType(); - } - const pos = getNodePos(); - const type = parseUnionTypeOrHigher(); - if (!inDisallowConditionalTypesContext() && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.ExtendsKeyword)) { - // The type following 'extends' is not permitted to be another conditional type - const extendsType = disallowConditionalTypesAnd(parseType); - parseExpected(SyntaxKind.QuestionToken); - const trueType = allowConditionalTypesAnd(parseType); - parseExpected(SyntaxKind.ColonToken); - const falseType = allowConditionalTypesAnd(parseType); - return finishNode(factory.createConditionalTypeNode(type, extendsType, trueType, falseType), pos); - } - return type; - } - - function parseTypeAnnotation(): TypeNode | undefined { - return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined; - } - - // EXPRESSIONS - function isStartOfLeftHandSideExpression(): boolean { - switch (token()) { - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.StringLiteral: - case SyntaxKind.NoSubstitutionTemplateLiteral: - case SyntaxKind.TemplateHead: - case SyntaxKind.OpenParenToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.NewKeyword: - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - case SyntaxKind.Identifier: - return true; - case SyntaxKind.ImportKeyword: - return lookAhead(nextTokenIsOpenParenOrLessThanOrDot); - default: - return isIdentifier(); - } - } - - function isStartOfExpression(): boolean { - if (isStartOfLeftHandSideExpression()) { - return true; - } - - switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DeleteKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.PlusPlusToken: - case SyntaxKind.MinusMinusToken: - case SyntaxKind.LessThanToken: - case SyntaxKind.AwaitKeyword: - case SyntaxKind.YieldKeyword: - case SyntaxKind.PrivateIdentifier: - case SyntaxKind.AtToken: - // Yield/await always starts an expression. Either it is an identifier (in which case - // it is definitely an expression). Or it's a keyword (either because we're in - // a generator or async function, or in strict mode (or both)) and it started a yield or await expression. - return true; - default: - // Error tolerance. If we see the start of some binary operator, we consider - // that the start of an expression. That way we'll parse out a missing identifier, - // give a good message about an identifier being missing, and then consume the - // rest of the binary expression. - if (isBinaryOperator()) { - return true; - } - - return isIdentifier(); - } - } - - function isStartOfExpressionStatement(): boolean { - // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. - return token() !== SyntaxKind.OpenBraceToken && - token() !== SyntaxKind.FunctionKeyword && - token() !== SyntaxKind.ClassKeyword && - token() !== SyntaxKind.AtToken && - isStartOfExpression(); - } - - function parseExpression(): Expression { - // Expression[in]: - // AssignmentExpression[in] - // Expression[in] , AssignmentExpression[in] - - // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator - const saveDecoratorContext = inDecoratorContext(); - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ false); - } - - const pos = getNodePos(); - let expr = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); - let operatorToken: BinaryOperatorToken; - while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { - expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true), pos); - } - - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ true); - } - return expr; - } - - function parseInitializer(): Expression | undefined { - return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true) : undefined; - } - - function parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction: boolean): Expression { - // AssignmentExpression[in,yield]: - // 1) ConditionalExpression[?in,?yield] - // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] - // 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield] - // 4) ArrowFunctionExpression[?in,?yield] - // 5) AsyncArrowFunctionExpression[in,yield,await] - // 6) [+Yield] YieldExpression[?In] - // - // Note: for ease of implementation we treat productions '2' and '3' as the same thing. - // (i.e. they're both BinaryExpressions with an assignment operator in it). - - // First, do the simple check if we have a YieldExpression (production '6'). - if (isYieldExpression()) { - return parseYieldExpression(); - } - - // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized - // parameter list or is an async arrow function. - // AsyncArrowFunctionExpression: - // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] - // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] - // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression". - // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". - // - // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is - // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done - // with AssignmentExpression if we see one. - const arrowExpression = tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction) || tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction); - if (arrowExpression) { - return arrowExpression; - } - - // Now try to see if we're in production '1', '2' or '3'. A conditional expression can - // start with a LogicalOrExpression, while the assignment productions can only start with - // LeftHandSideExpressions. - // - // So, first, we try to just parse out a BinaryExpression. If we get something that is a - // LeftHandSide or higher, then we can try to parse out the assignment expression part. - // Otherwise, we try to parse out the conditional expression bit. We want to allow any - // binary expression here, so we pass in the 'lowest' precedence here so that it matches - // and consumes anything. - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); - - // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized - // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single - // identifier and the current token is an arrow. - if (expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { - return parseSimpleArrowFunctionExpression(pos, expr as Identifier, allowReturnTypeInArrowFunction, hasJSDoc, /*asyncModifier*/ undefined); - } - - // Now see if we might be in cases '2' or '3'. - // If the expression was a LHS expression, and we have an assignment operator, then - // we're in '2' or '3'. Consume the assignment and return. - // - // Note: we call reScanGreaterToken so that we get an appropriately merged token - // for cases like `> > =` becoming `>>=` - if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { - return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction), pos); - } - - // It wasn't an assignment or a lambda. This is a conditional expression: - return parseConditionalExpressionRest(expr, pos, allowReturnTypeInArrowFunction); - } - - function isYieldExpression(): boolean { - if (token() === SyntaxKind.YieldKeyword) { - // If we have a 'yield' keyword, and this is a context where yield expressions are - // allowed, then definitely parse out a yield expression. - if (inYieldContext()) { - return true; - } - - // We're in a context where 'yield expr' is not allowed. However, if we can - // definitely tell that the user was trying to parse a 'yield expr' and not - // just a normal expr that start with a 'yield' identifier, then parse out - // a 'yield expr'. We can then report an error later that they are only - // allowed in generator expressions. - // - // for example, if we see 'yield(foo)', then we'll have to treat that as an - // invocation expression of something called 'yield'. However, if we have - // 'yield foo' then that is not legal as a normal expression, so we can - // definitely recognize this as a yield expression. - // - // for now we just check if the next token is an identifier. More heuristics - // can be added here later as necessary. We just need to make sure that we - // don't accidentally consume something legal. - return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); - } - - return false; - } - - function nextTokenIsIdentifierOnSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && isIdentifier(); - } - - function parseYieldExpression(): YieldExpression { - const pos = getNodePos(); - - // YieldExpression[In] : - // yield - // yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] - // yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] - nextToken(); - - if ( - !scanner.hasPrecedingLineBreak() && - (token() === SyntaxKind.AsteriskToken || isStartOfExpression()) - ) { - return finishNode( - factory.createYieldExpression( - parseOptionalToken(SyntaxKind.AsteriskToken), - parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true), - ), - pos, - ); - } - else { - // if the next token is not on the same line as yield. or we don't have an '*' or - // the start of an expression, then this is just a simple "yield" expression. - return finishNode(factory.createYieldExpression(/*asteriskToken*/ undefined, /*expression*/ undefined), pos); - } - } - - function parseSimpleArrowFunctionExpression(pos: number, identifier: Identifier, allowReturnTypeInArrowFunction: boolean, hasJSDoc: boolean, asyncModifier?: NodeArray | undefined): ArrowFunction { - Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); - const parameter = factory.createParameterDeclaration( - /*modifiers*/ undefined, - /*dotDotDotToken*/ undefined, - identifier, - /*questionToken*/ undefined, - /*type*/ undefined, - /*initializer*/ undefined, - ); - finishNode(parameter, identifier.pos); - - const parameters = createNodeArray([parameter], parameter.pos, parameter.end); - const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - const body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier, allowReturnTypeInArrowFunction); - const node = factory.createArrowFunction(asyncModifier, /*typeParameters*/ undefined, parameters, /*type*/ undefined, equalsGreaterThanToken, body); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction: boolean): Expression | undefined { - const triState = isParenthesizedArrowFunctionExpression(); - if (triState === Tristate.False) { - // It's definitely not a parenthesized arrow function expression. - return undefined; - } - - // If we definitely have an arrow function, then we can just parse one, not requiring a - // following => or { token. Otherwise, we *might* have an arrow function. Try to parse - // it out, but don't allow any ambiguity, and return 'undefined' if this could be an - // expression instead. - return triState === Tristate.True ? - parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true, /*allowReturnTypeInArrowFunction*/ true) : - tryParse(() => parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction)); - } - - // True -> We definitely expect a parenthesized arrow function here. - // False -> There *cannot* be a parenthesized arrow function here. - // Unknown -> There *might* be a parenthesized arrow function here. - // Speculatively look ahead to be sure, and rollback if not. - function isParenthesizedArrowFunctionExpression(): Tristate { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken || token() === SyntaxKind.AsyncKeyword) { - return lookAhead(isParenthesizedArrowFunctionExpressionWorker); - } - - if (token() === SyntaxKind.EqualsGreaterThanToken) { - // ERROR RECOVERY TWEAK: - // If we see a standalone => try to parse it as an arrow function expression as that's - // likely what the user intended to write. - return Tristate.True; - } - // Definitely not a parenthesized arrow function. - return Tristate.False; - } - - function isParenthesizedArrowFunctionExpressionWorker() { - if (token() === SyntaxKind.AsyncKeyword) { - nextToken(); - if (scanner.hasPrecedingLineBreak()) { - return Tristate.False; - } - if (token() !== SyntaxKind.OpenParenToken && token() !== SyntaxKind.LessThanToken) { - return Tristate.False; - } - } - - const first = token(); - const second = nextToken(); - - if (first === SyntaxKind.OpenParenToken) { - if (second === SyntaxKind.CloseParenToken) { - // Simple cases: "() =>", "(): ", and "() {". - // This is an arrow function with no parameters. - // The last one is not actually an arrow function, - // but this is probably what the user intended. - const third = nextToken(); - switch (third) { - case SyntaxKind.EqualsGreaterThanToken: - case SyntaxKind.ColonToken: - case SyntaxKind.OpenBraceToken: - return Tristate.True; - default: - return Tristate.False; - } - } - - // If encounter "([" or "({", this could be the start of a binding pattern. - // Examples: - // ([ x ]) => { } - // ({ x }) => { } - // ([ x ]) - // ({ x }) - if (second === SyntaxKind.OpenBracketToken || second === SyntaxKind.OpenBraceToken) { - return Tristate.Unknown; - } - - // Simple case: "(..." - // This is an arrow function with a rest parameter. - if (second === SyntaxKind.DotDotDotToken) { - return Tristate.True; - } - - // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This - // isn't actually allowed, but we want to treat it as a lambda so we can provide - // a good error message. - if (isModifierKind(second) && second !== SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsIdentifier)) { - if (nextToken() === SyntaxKind.AsKeyword) { - // https://github.com/microsoft/TypeScript/issues/44466 - return Tristate.False; - } - return Tristate.True; - } - - // If we had "(" followed by something that's not an identifier, - // then this definitely doesn't look like a lambda. "this" is not - // valid, but we want to parse it and then give a semantic error. - if (!isIdentifier() && second !== SyntaxKind.ThisKeyword) { - return Tristate.False; - } - - switch (nextToken()) { - case SyntaxKind.ColonToken: - // If we have something like "(a:", then we must have a - // type-annotated parameter in an arrow function expression. - return Tristate.True; - case SyntaxKind.QuestionToken: - nextToken(); - // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda. - if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.EqualsToken || token() === SyntaxKind.CloseParenToken) { - return Tristate.True; - } - // Otherwise it is definitely not a lambda. - return Tristate.False; - case SyntaxKind.CommaToken: - case SyntaxKind.EqualsToken: - case SyntaxKind.CloseParenToken: - // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function - return Tristate.Unknown; - } - // It is definitely not an arrow function - return Tristate.False; - } - else { - Debug.assert(first === SyntaxKind.LessThanToken); - - // If we have "<" not followed by an identifier, - // then this definitely is not an arrow function. - if (!isIdentifier() && token() !== SyntaxKind.ConstKeyword) { - return Tristate.False; - } - - // JSX overrides - if (languageVariant === LanguageVariant.JSX) { - const isArrowFunctionInJsx = lookAhead(() => { - parseOptional(SyntaxKind.ConstKeyword); - const third = nextToken(); - if (third === SyntaxKind.ExtendsKeyword) { - const fourth = nextToken(); - switch (fourth) { - case SyntaxKind.EqualsToken: - case SyntaxKind.GreaterThanToken: - case SyntaxKind.SlashToken: - return false; - default: - return true; - } - } - else if (third === SyntaxKind.CommaToken || third === SyntaxKind.EqualsToken) { - return true; - } - return false; - }); - - if (isArrowFunctionInJsx) { - return Tristate.True; - } - - return Tristate.False; - } - - // This *could* be a parenthesized arrow function. - return Tristate.Unknown; - } - } - - function parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined { - const tokenPos = scanner.getTokenStart(); - if (notParenthesizedArrow?.has(tokenPos)) { - return undefined; - } - - const result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false, allowReturnTypeInArrowFunction); - if (!result) { - (notParenthesizedArrow || (notParenthesizedArrow = new Set())).add(tokenPos); - } - - return result; - } - - function tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined { - // We do a check here so that we won't be doing unnecessarily call to "lookAhead" - if (token() === SyntaxKind.AsyncKeyword) { - if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const asyncModifier = parseModifiersForArrowFunction(); - const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); - return parseSimpleArrowFunctionExpression(pos, expr as Identifier, allowReturnTypeInArrowFunction, hasJSDoc, asyncModifier); - } - } - return undefined; - } - - function isUnParenthesizedAsyncArrowFunctionWorker(): Tristate { - // AsyncArrowFunctionExpression: - // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] - // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] - if (token() === SyntaxKind.AsyncKeyword) { - nextToken(); - // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function - // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher" - if (scanner.hasPrecedingLineBreak() || token() === SyntaxKind.EqualsGreaterThanToken) { - return Tristate.False; - } - // Check for un-parenthesized AsyncArrowFunction - const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); - if (!scanner.hasPrecedingLineBreak() && expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { - return Tristate.True; - } - } - - return Tristate.False; - } - - function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean, allowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const modifiers = parseModifiersForArrowFunction(); - const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; - // Arrow functions are never generators. - // - // If we're speculatively parsing a signature for a parenthesized arrow function, then - // we have to have a complete parameter list. Otherwise we might see something like - // a => (b => c) - // And think that "(b =>" was actually a parenthesized arrow function with a missing - // close paren. - const typeParameters = parseTypeParameters(); - - let parameters: NodeArray; - if (!parseExpected(SyntaxKind.OpenParenToken)) { - if (!allowAmbiguity) { - return undefined; - } - parameters = createMissingList(); - } - else { - if (!allowAmbiguity) { - const maybeParameters = parseParametersWorker(isAsync, allowAmbiguity); - if (!maybeParameters) { - return undefined; - } - parameters = maybeParameters; - } - else { - parameters = parseParametersWorker(isAsync, allowAmbiguity); - } - if (!parseExpected(SyntaxKind.CloseParenToken) && !allowAmbiguity) { - return undefined; - } - } - - const hasReturnColon = token() === SyntaxKind.ColonToken; - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { - return undefined; - } - - // Parsing a signature isn't enough. - // Parenthesized arrow signatures often look like other valid expressions. - // For instance: - // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. - // - "(x,y)" is a comma expression parsed as a signature with two parameters. - // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. - // - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type. - // - "a ? (b): (function() {})" as well, but inside of a parenthesized type with an arbitrary amount of nesting. - // - // So we need just a bit of lookahead to ensure that it can only be a signature. - - let unwrappedType = type; - while (unwrappedType?.kind === SyntaxKind.ParenthesizedType) { - unwrappedType = (unwrappedType as ParenthesizedTypeNode).type; // Skip parens if need be - } - - const hasJSDocFunctionType = unwrappedType && isJSDocFunctionType(unwrappedType); - if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && (hasJSDocFunctionType || token() !== SyntaxKind.OpenBraceToken)) { - // Returning undefined here will cause our caller to rewind to where we started from. - return undefined; - } - - // If we have an arrow, then try to parse the body. Even if not, try to parse if we - // have an opening brace, just in case we're in an error state. - const lastToken = token(); - const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); - const body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) - ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier), allowReturnTypeInArrowFunction) - : parseIdentifier(); - - // Given: - // x ? y => ({ y }) : z => ({ z }) - // We try to parse the body of the first arrow function by looking at: - // ({ y }) : z => ({ z }) - // This is a valid arrow function with "z" as the return type. - // - // But, if we're in the true side of a conditional expression, this colon - // terminates the expression, so we cannot allow a return type if we aren't - // certain whether or not the preceding text was parsed as a parameter list. - // - // For example, - // a() ? (b: number, c?: string): void => d() : e - // is determined by isParenthesizedArrowFunctionExpression to unambiguously - // be an arrow expression, so we allow a return type. - if (!allowReturnTypeInArrowFunction && hasReturnColon) { - // However, if the arrow function we were able to parse is followed by another colon - // as in: - // a ? (x): string => x : null - // Then allow the arrow function, and treat the second colon as terminating - // the conditional expression. It's okay to do this because this code would - // be a syntax error in JavaScript (as the second colon shouldn't be there). - if (token() !== SyntaxKind.ColonToken) { - return undefined; - } - } - - const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseArrowFunctionExpressionBody(isAsync: boolean, allowReturnTypeInArrowFunction: boolean): Block | Expression { - if (token() === SyntaxKind.OpenBraceToken) { - return parseFunctionBlock(isAsync ? SignatureFlags.Await : SignatureFlags.None); - } - - if ( - token() !== SyntaxKind.SemicolonToken && - token() !== SyntaxKind.FunctionKeyword && - token() !== SyntaxKind.ClassKeyword && - isStartOfStatement() && - !isStartOfExpressionStatement() - ) { - // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) - // - // Here we try to recover from a potential error situation in the case where the - // user meant to supply a block. For example, if the user wrote: - // - // a => - // let v = 0; - // } - // - // they may be missing an open brace. Check to see if that's the case so we can - // try to recover better. If we don't do this, then the next close curly we see may end - // up preemptively closing the containing construct. - // - // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error. - return parseFunctionBlock(SignatureFlags.IgnoreMissingOpenBrace | (isAsync ? SignatureFlags.Await : SignatureFlags.None)); - } - - const savedYieldContext = inYieldContext(); - setYieldContext(false); - const savedTopLevel = topLevel; - topLevel = false; - const node = isAsync - ? doInAwaitContext(() => parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction)) - : doOutsideOfAwaitContext(() => parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction)); - topLevel = savedTopLevel; - setYieldContext(savedYieldContext); - return node; - } - - function parseConditionalExpressionRest(leftOperand: Expression, pos: number, allowReturnTypeInArrowFunction: boolean): Expression { - // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (!questionToken) { - return leftOperand; - } - - // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and - // we do not that for the 'whenFalse' part. - let colonToken; - return finishNode( - factory.createConditionalExpression( - leftOperand, - questionToken, - doOutsideOfContext(disallowInAndDecoratorContext, () => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ false)), - colonToken = parseExpectedToken(SyntaxKind.ColonToken), - nodeIsPresent(colonToken) - ? parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction) - : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)), - ), - pos, - ); - } - - function parseBinaryExpressionOrHigher(precedence: OperatorPrecedence): Expression { - const pos = getNodePos(); - const leftOperand = parseUnaryExpressionOrHigher(); - return parseBinaryExpressionRest(precedence, leftOperand, pos); - } - - function isInOrOfKeyword(t: SyntaxKind) { - return t === SyntaxKind.InKeyword || t === SyntaxKind.OfKeyword; - } - - function parseBinaryExpressionRest(precedence: OperatorPrecedence, leftOperand: Expression, pos: number): Expression { - while (true) { - // We either have a binary operator here, or we're finished. We call - // reScanGreaterToken so that we merge token sequences like > and = into >= - - reScanGreaterToken(); - const newPrecedence = getBinaryOperatorPrecedence(token()); - - // Check the precedence to see if we should "take" this operator - // - For left associative operator (all operator but **), consume the operator, - // recursively call the function below, and parse binaryExpression as a rightOperand - // of the caller if the new precedence of the operator is greater then or equal to the current precedence. - // For example: - // a - b - c; - // ^token; leftOperand = b. Return b to the caller as a rightOperand - // a * b - c - // ^token; leftOperand = b. Return b to the caller as a rightOperand - // a - b * c; - // ^token; leftOperand = b. Return b * c to the caller as a rightOperand - // - For right associative operator (**), consume the operator, recursively call the function - // and parse binaryExpression as a rightOperand of the caller if the new precedence of - // the operator is strictly grater than the current precedence - // For example: - // a ** b ** c; - // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand - // a - b ** c; - // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand - // a ** b - c - // ^token; leftOperand = b. Return b to the caller as a rightOperand - const consumeCurrentOperator = token() === SyntaxKind.AsteriskAsteriskToken ? - newPrecedence >= precedence : - newPrecedence > precedence; - - if (!consumeCurrentOperator) { - break; - } - - if (token() === SyntaxKind.InKeyword && inDisallowInContext()) { - break; - } - - if (token() === SyntaxKind.AsKeyword || token() === SyntaxKind.SatisfiesKeyword) { - // Make sure we *do* perform ASI for constructs like this: - // var x = foo - // as (Bar) - // This should be parsed as an initialized variable, followed - // by a function call to 'as' with the argument 'Bar' - if (scanner.hasPrecedingLineBreak()) { - break; - } - else { - const keywordKind = token(); - nextToken(); - leftOperand = keywordKind === SyntaxKind.SatisfiesKeyword ? makeSatisfiesExpression(leftOperand, parseType()) : - makeAsExpression(leftOperand, parseType()); - } - } - else { - leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence), pos); - } - } - - return leftOperand; - } - - function isBinaryOperator() { - if (inDisallowInContext() && token() === SyntaxKind.InKeyword) { - return false; - } - - return getBinaryOperatorPrecedence(token()) > 0; - } - - function makeSatisfiesExpression(left: Expression, right: TypeNode): SatisfiesExpression { - return finishNode(factory.createSatisfiesExpression(left, right), left.pos); - } - - function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression, pos: number): BinaryExpression { - return finishNode(factory.createBinaryExpression(left, operatorToken, right), pos); - } - - function makeAsExpression(left: Expression, right: TypeNode): AsExpression { - return finishNode(factory.createAsExpression(left, right), left.pos); - } - - function parsePrefixUnaryExpression() { - const pos = getNodePos(); - return finishNode(factory.createPrefixUnaryExpression(token() as PrefixUnaryOperator, nextTokenAnd(parseSimpleUnaryExpression)), pos); - } - - function parseDeleteExpression() { - const pos = getNodePos(); - return finishNode(factory.createDeleteExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); - } - - function parseTypeOfExpression() { - const pos = getNodePos(); - return finishNode(factory.createTypeOfExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); - } - - function parseVoidExpression() { - const pos = getNodePos(); - return finishNode(factory.createVoidExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); - } - - function isAwaitExpression(): boolean { - if (token() === SyntaxKind.AwaitKeyword) { - if (inAwaitContext()) { - return true; - } - - // here we are using similar heuristics as 'isYieldExpression' - return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); - } - - return false; - } - - function parseAwaitExpression() { - const pos = getNodePos(); - return finishNode(factory.createAwaitExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); - } - - /** - * Parse ES7 exponential expression and await expression - * - * ES7 ExponentiationExpression: - * 1) UnaryExpression[?Yield] - * 2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield] - */ - function parseUnaryExpressionOrHigher(): UnaryExpression | BinaryExpression { - /** - * ES7 UpdateExpression: - * 1) LeftHandSideExpression[?Yield] - * 2) LeftHandSideExpression[?Yield][no LineTerminator here]++ - * 3) LeftHandSideExpression[?Yield][no LineTerminator here]-- - * 4) ++UnaryExpression[?Yield] - * 5) --UnaryExpression[?Yield] - */ - if (isUpdateExpression()) { - const pos = getNodePos(); - const updateExpression = parseUpdateExpression(); - return token() === SyntaxKind.AsteriskAsteriskToken ? - parseBinaryExpressionRest(getBinaryOperatorPrecedence(token()), updateExpression, pos) as BinaryExpression : - updateExpression; - } - - /** - * ES7 UnaryExpression: - * 1) UpdateExpression[?yield] - * 2) delete UpdateExpression[?yield] - * 3) void UpdateExpression[?yield] - * 4) typeof UpdateExpression[?yield] - * 5) + UpdateExpression[?yield] - * 6) - UpdateExpression[?yield] - * 7) ~ UpdateExpression[?yield] - * 8) ! UpdateExpression[?yield] - */ - const unaryOperator = token(); - const simpleUnaryExpression = parseSimpleUnaryExpression(); - if (token() === SyntaxKind.AsteriskAsteriskToken) { - const pos = skipTrivia(sourceText, simpleUnaryExpression.pos); - const { end } = simpleUnaryExpression; - if (simpleUnaryExpression.kind === SyntaxKind.TypeAssertionExpression) { - parseErrorAt(pos, end, Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); - } - else { - Debug.assert(isKeywordOrPunctuation(unaryOperator)); - parseErrorAt(pos, end, Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, tokenToString(unaryOperator)); - } - } - return simpleUnaryExpression; - } - - /** - * Parse ES7 simple-unary expression or higher: - * - * ES7 UnaryExpression: - * 1) UpdateExpression[?yield] - * 2) delete UnaryExpression[?yield] - * 3) void UnaryExpression[?yield] - * 4) typeof UnaryExpression[?yield] - * 5) + UnaryExpression[?yield] - * 6) - UnaryExpression[?yield] - * 7) ~ UnaryExpression[?yield] - * 8) ! UnaryExpression[?yield] - * 9) [+Await] await UnaryExpression[?yield] - */ - function parseSimpleUnaryExpression(): UnaryExpression { - switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - return parsePrefixUnaryExpression(); - case SyntaxKind.DeleteKeyword: - return parseDeleteExpression(); - case SyntaxKind.TypeOfKeyword: - return parseTypeOfExpression(); - case SyntaxKind.VoidKeyword: - return parseVoidExpression(); - case SyntaxKind.LessThanToken: - // Just like in parseUpdateExpression, we need to avoid parsing type assertions when - // in JSX and we see an expression like "+ bar". - if (languageVariant === LanguageVariant.JSX) { - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, /*topInvalidNodePosition*/ undefined, /*openingTag*/ undefined, /*mustBeUnary*/ true); - } - // This is modified UnaryExpression grammar in TypeScript - // UnaryExpression (modified): - // < type > UnaryExpression - return parseTypeAssertion(); - case SyntaxKind.AwaitKeyword: - if (isAwaitExpression()) { - return parseAwaitExpression(); - } - // falls through - default: - return parseUpdateExpression(); - } - } - - /** - * Check if the current token can possibly be an ES7 increment expression. - * - * ES7 UpdateExpression: - * LeftHandSideExpression[?Yield] - * LeftHandSideExpression[?Yield][no LineTerminator here]++ - * LeftHandSideExpression[?Yield][no LineTerminator here]-- - * ++LeftHandSideExpression[?Yield] - * --LeftHandSideExpression[?Yield] - */ - function isUpdateExpression(): boolean { - // This function is called inside parseUnaryExpression to decide - // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly - switch (token()) { - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - case SyntaxKind.TildeToken: - case SyntaxKind.ExclamationToken: - case SyntaxKind.DeleteKeyword: - case SyntaxKind.TypeOfKeyword: - case SyntaxKind.VoidKeyword: - case SyntaxKind.AwaitKeyword: - return false; - case SyntaxKind.LessThanToken: - // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression - if (languageVariant !== LanguageVariant.JSX) { - return false; - } - // We are in JSX context and the token is part of JSXElement. - // falls through - default: - return true; - } - } - - /** - * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression. - * - * ES7 UpdateExpression[yield]: - * 1) LeftHandSideExpression[?yield] - * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++ - * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]-- - * 4) ++LeftHandSideExpression[?yield] - * 5) --LeftHandSideExpression[?yield] - * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression - */ - function parseUpdateExpression(): UpdateExpression { - if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) { - const pos = getNodePos(); - return finishNode(factory.createPrefixUnaryExpression(token() as PrefixUnaryOperator, nextTokenAnd(parseLeftHandSideExpressionOrHigher)), pos); - } - else if (languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { - // JSXElement is part of primaryExpression - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); - } - - const expression = parseLeftHandSideExpressionOrHigher(); - - Debug.assert(isLeftHandSideExpression(expression)); - if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { - const operator = token() as PostfixUnaryOperator; - nextToken(); - return finishNode(factory.createPostfixUnaryExpression(expression, operator), expression.pos); - } - - return expression; - } - - function parseLeftHandSideExpressionOrHigher(): LeftHandSideExpression { - // Original Ecma: - // LeftHandSideExpression: See 11.2 - // NewExpression - // CallExpression - // - // Our simplification: - // - // LeftHandSideExpression: See 11.2 - // MemberExpression - // CallExpression - // - // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with - // MemberExpression to make our lives easier. - // - // to best understand the below code, it's important to see how CallExpression expands - // out into its own productions: - // - // CallExpression: - // MemberExpression Arguments - // CallExpression Arguments - // CallExpression[Expression] - // CallExpression.IdentifierName - // import (AssignmentExpression) - // super Arguments - // super.IdentifierName - // - // Because of the recursion in these calls, we need to bottom out first. There are three - // bottom out states we can run into: 1) We see 'super' which must start either of - // the last two CallExpression productions. 2) We see 'import' which must start import call. - // 3)we have a MemberExpression which either completes the LeftHandSideExpression, - // or starts the beginning of the first four CallExpression productions. - const pos = getNodePos(); - let expression: MemberExpression; - if (token() === SyntaxKind.ImportKeyword) { - if (lookAhead(nextTokenIsOpenParenOrLessThan)) { - // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "(" - // For example: - // var foo3 = require("subfolder - // import * as foo1 from "module-from-node - // We want this import to be a statement rather than import call expression - sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; - expression = parseTokenNode(); - } - else if (lookAhead(nextTokenIsDot)) { - // This is an 'import.*' metaproperty (i.e. 'import.meta') - nextToken(); // advance past the 'import' - nextToken(); // advance past the dot - expression = finishNode(factory.createMetaProperty(SyntaxKind.ImportKeyword, parseIdentifierName()), pos); - - if ((expression as MetaProperty).name.escapedText === "defer") { - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; - } - } - else { - sourceFlags |= NodeFlags.PossiblyContainsImportMeta; - } - } - else { - expression = parseMemberExpressionOrHigher(); - } - } - else { - expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher(); - } - - // Now, we *may* be complete. However, we might have consumed the start of a - // CallExpression or OptionalExpression. As such, we need to consume the rest - // of it here to be complete. - return parseCallExpressionRest(pos, expression); - } - - function parseMemberExpressionOrHigher(): MemberExpression { - // Note: to make our lives simpler, we decompose the NewExpression productions and - // place ObjectCreationExpression and FunctionExpression into PrimaryExpression. - // like so: - // - // PrimaryExpression : See 11.1 - // this - // Identifier - // Literal - // ArrayLiteral - // ObjectLiteral - // (Expression) - // FunctionExpression - // new MemberExpression Arguments? - // - // MemberExpression : See 11.2 - // PrimaryExpression - // MemberExpression[Expression] - // MemberExpression.IdentifierName - // - // CallExpression : See 11.2 - // MemberExpression - // CallExpression Arguments - // CallExpression[Expression] - // CallExpression.IdentifierName - // - // Technically this is ambiguous. i.e. CallExpression defines: - // - // CallExpression: - // CallExpression Arguments - // - // If you see: "new Foo()" - // - // Then that could be treated as a single ObjectCreationExpression, or it could be - // treated as the invocation of "new Foo". We disambiguate that in code (to match - // the original grammar) by making sure that if we see an ObjectCreationExpression - // we always consume arguments if they are there. So we treat "new Foo()" as an - // object creation only, and not at all as an invocation. Another way to think - // about this is that for every "new" that we see, we will consume an argument list if - // it is there as part of the *associated* object creation node. Any additional - // argument lists we see, will become invocation expressions. - // - // Because there are no other places in the grammar now that refer to FunctionExpression - // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression - // production. - // - // Because CallExpression and MemberExpression are left recursive, we need to bottom out - // of the recursion immediately. So we parse out a primary expression to start with. - const pos = getNodePos(); - const expression = parsePrimaryExpression(); - return parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); - } - - function parseSuperExpression(): MemberExpression { - const pos = getNodePos(); - let expression = parseTokenNode(); - if (token() === SyntaxKind.LessThanToken) { - const startPos = getNodePos(); - const typeArguments = tryParse(parseTypeArgumentsInExpression); - if (typeArguments !== undefined) { - parseErrorAt(startPos, getNodePos(), Diagnostics.super_may_not_use_type_arguments); - if (!isTemplateStartOfTaggedTemplate()) { - expression = factory.createExpressionWithTypeArguments(expression, typeArguments); - } - } - } - - if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.DotToken || token() === SyntaxKind.OpenBracketToken) { - return expression; - } - - // If we have seen "super" it must be followed by '(' or '.'. - // If it wasn't then just try to parse out a '.' and report an error. - parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); - // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic - return finishNode(factoryCreatePropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true, /*allowUnicodeEscapeSequenceInIdentifierName*/ true)), pos); - } - - function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment, mustBeUnary = false): JsxElement | JsxSelfClosingElement | JsxFragment { - const pos = getNodePos(); - const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); - let result: JsxElement | JsxSelfClosingElement | JsxFragment; - if (opening.kind === SyntaxKind.JsxOpeningElement) { - let children = parseJsxChildren(opening); - let closingElement: JsxClosingElement; - - const lastChild: JsxChild | undefined = children[children.length - 1]; - if ( - lastChild?.kind === SyntaxKind.JsxElement - && !tagNamesAreEquivalent(lastChild.openingElement.tagName, lastChild.closingElement.tagName) - && tagNamesAreEquivalent(opening.tagName, lastChild.closingElement.tagName) - ) { - // when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement, - // restructure (
(......
)) --> (
(......)
) - // (no need to error; the parent will error) - const end = lastChild.children.end; - const newLast = finishNode( - factory.createJsxElement( - lastChild.openingElement, - lastChild.children, - finishNode(factory.createJsxClosingElement(finishNode(factoryCreateIdentifier(""), end, end)), end, end), - ), - lastChild.openingElement.pos, - end, - ); - - children = createNodeArray([...children.slice(0, children.length - 1), newLast], children.pos, end); - closingElement = lastChild.closingElement; - } - else { - closingElement = parseJsxClosingElement(opening, inExpressionContext); - if (!tagNamesAreEquivalent(opening.tagName, closingElement.tagName)) { - if (openingTag && isJsxOpeningElement(openingTag) && tagNamesAreEquivalent(closingElement.tagName, openingTag.tagName)) { - // opening incorrectly matched with its parent's closing -- put error on opening - parseErrorAtRange(opening.tagName, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, opening.tagName)); - } - else { - // other opening/closing mismatches -- put error on closing - parseErrorAtRange(closingElement.tagName, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, opening.tagName)); - } - } - } - result = finishNode(factory.createJsxElement(opening, children, closingElement), pos); - } - else if (opening.kind === SyntaxKind.JsxOpeningFragment) { - result = finishNode(factory.createJsxFragment(opening, parseJsxChildren(opening), parseJsxClosingFragment(inExpressionContext)), pos); - } - else { - Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); - // Nothing else to do for self-closing elements - result = opening; - } - - // If the user writes the invalid code '
' in an expression context (i.e. not wrapped in - // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag - // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX - // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter - // does less damage and we can report a better error. - // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios - // of one sort or another. - // If we are in a unary context, we can't do this recovery; the binary expression we return here is not - // a valid UnaryExpression and will cause problems later. - if (!mustBeUnary && inExpressionContext && token() === SyntaxKind.LessThanToken) { - const topBadPos = typeof topInvalidNodePosition === "undefined" ? result.pos : topInvalidNodePosition; - const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, topBadPos)); - if (invalidElement) { - const operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false); - setTextRangePosWidth(operatorToken, invalidElement.pos, 0); - parseErrorAt(skipTrivia(sourceText, topBadPos), invalidElement.end, Diagnostics.JSX_expressions_must_have_one_parent_element); - return finishNode(factory.createBinaryExpression(result, operatorToken as Token, invalidElement), pos) as Node as JsxElement; - } - } - - return result; - } - - function parseJsxText(): JsxText { - const pos = getNodePos(); - const node = factory.createJsxText(scanner.getTokenValue(), currentToken === SyntaxKind.JsxTextAllWhiteSpaces); - currentToken = scanner.scanJsxToken(); - return finishNode(node, pos); - } - - function parseJsxChild(openingTag: JsxOpeningElement | JsxOpeningFragment, token: JsxTokenSyntaxKind): JsxChild | undefined { - switch (token) { - case SyntaxKind.EndOfFileToken: - // If we hit EOF, issue the error at the tag that lacks the closing element - // rather than at the end of the file (which is useless) - if (isJsxOpeningFragment(openingTag)) { - parseErrorAtRange(openingTag, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); - } - else { - // We want the error span to cover only 'Foo.Bar' in < Foo.Bar > - // or to cover only 'Foo' in < Foo > - const tag = openingTag.tagName; - const start = Math.min(skipTrivia(sourceText, tag.pos), tag.end); - parseErrorAt(start, tag.end, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTag.tagName)); - } - return undefined; - case SyntaxKind.LessThanSlashToken: - case SyntaxKind.ConflictMarkerTrivia: - return undefined; - case SyntaxKind.JsxText: - case SyntaxKind.JsxTextAllWhiteSpaces: - return parseJsxText(); - case SyntaxKind.OpenBraceToken: - return parseJsxExpression(/*inExpressionContext*/ false); - case SyntaxKind.LessThanToken: - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false, /*topInvalidNodePosition*/ undefined, openingTag); - default: - return Debug.assertNever(token); - } - } - - function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray { - const list = []; - const listPos = getNodePos(); - const saveParsingContext = parsingContext; - parsingContext |= 1 << ParsingContext.JsxChildren; - - while (true) { - const child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken()); - if (!child) break; - list.push(child); - if ( - isJsxOpeningElement(openingTag) - && child?.kind === SyntaxKind.JsxElement - && !tagNamesAreEquivalent(child.openingElement.tagName, child.closingElement.tagName) - && tagNamesAreEquivalent(openingTag.tagName, child.closingElement.tagName) - ) { - // stop after parsing a mismatched child like
...(
) in order to reattach the higher - break; - } - } - - parsingContext = saveParsingContext; - return createNodeArray(list, listPos); - } - - function parseJsxAttributes(): JsxAttributes { - const pos = getNodePos(); - return finishNode(factory.createJsxAttributes(parseList(ParsingContext.JsxAttributes, parseJsxAttribute)), pos); - } - - function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment { - const pos = getNodePos(); - - parseExpected(SyntaxKind.LessThanToken); - - if (token() === SyntaxKind.GreaterThanToken) { - // See below for explanation of scanJsxText - scanJsxText(); - return finishNode(factory.createJsxOpeningFragment(), pos); - } - const tagName = parseJsxElementName(); - const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined; - const attributes = parseJsxAttributes(); - - let node: JsxOpeningLikeElement; - - if (token() === SyntaxKind.GreaterThanToken) { - // Closing tag, so scan the immediately-following text with the JSX scanning instead - // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate - // scanning errors - scanJsxText(); - node = factory.createJsxOpeningElement(tagName, typeArguments, attributes); - } - else { - parseExpected(SyntaxKind.SlashToken); - if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnosticMessage*/ undefined, /*shouldAdvance*/ false)) { - // manually advance the scanner in order to look for jsx text inside jsx - if (inExpressionContext) { - nextToken(); - } - else { - scanJsxText(); - } - } - node = factory.createJsxSelfClosingElement(tagName, typeArguments, attributes); - } - - return finishNode(node, pos); - } - - function parseJsxElementName(): JsxTagNameExpression { - const pos = getNodePos(); - // JsxElement can have name in the form of - // propertyAccessExpression - // primaryExpression in the form of an identifier and "this" keyword - // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword - // We only want to consider "this" as a primaryExpression - const initialExpression = parseJsxTagName(); - if (isJsxNamespacedName(initialExpression)) { - return initialExpression; // `a:b.c` is invalid syntax, don't even look for the `.` if we parse `a:b`, and let `parseAttribute` report "unexpected :" instead. - } - let expression: PropertyAccessExpression | Identifier | ThisExpression = initialExpression; - while (parseOptional(SyntaxKind.DotToken)) { - expression = finishNode(factoryCreatePropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false, /*allowUnicodeEscapeSequenceInIdentifierName*/ false)), pos); - } - return expression as JsxTagNameExpression; - } - - function parseJsxTagName(): Identifier | JsxNamespacedName | ThisExpression { - const pos = getNodePos(); - scanJsxIdentifier(); - - const isThis = token() === SyntaxKind.ThisKeyword; - const tagName = parseIdentifierNameErrorOnUnicodeEscapeSequence(); - if (parseOptional(SyntaxKind.ColonToken)) { - scanJsxIdentifier(); - return finishNode(factory.createJsxNamespacedName(tagName, parseIdentifierNameErrorOnUnicodeEscapeSequence()), pos); - } - return isThis ? finishNode(factory.createToken(SyntaxKind.ThisKeyword), pos) : tagName; - } - - function parseJsxExpression(inExpressionContext: boolean): JsxExpression | undefined { - const pos = getNodePos(); - if (!parseExpected(SyntaxKind.OpenBraceToken)) { - return undefined; - } - - let dotDotDotToken: DotDotDotToken | undefined; - let expression: Expression | undefined; - if (token() !== SyntaxKind.CloseBraceToken) { - if (!inExpressionContext) { - dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - } - // Only an AssignmentExpression is valid here per the JSX spec, - // but we can unambiguously parse a comma sequence and provide - // a better error message in grammar checking. - expression = parseExpression(); - } - if (inExpressionContext) { - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - if (parseExpected(SyntaxKind.CloseBraceToken, /*diagnosticMessage*/ undefined, /*shouldAdvance*/ false)) { - scanJsxText(); - } - } - - return finishNode(factory.createJsxExpression(dotDotDotToken, expression), pos); - } - - function parseJsxAttribute(): JsxAttribute | JsxSpreadAttribute { - if (token() === SyntaxKind.OpenBraceToken) { - return parseJsxSpreadAttribute(); - } - - const pos = getNodePos(); - return finishNode(factory.createJsxAttribute(parseJsxAttributeName(), parseJsxAttributeValue()), pos); - } - - function parseJsxAttributeValue(): JsxAttributeValue | undefined { - if (token() === SyntaxKind.EqualsToken) { - if (scanJsxAttributeValue() === SyntaxKind.StringLiteral) { - return parseLiteralNode() as StringLiteral; - } - if (token() === SyntaxKind.OpenBraceToken) { - return parseJsxExpression(/*inExpressionContext*/ true); - } - if (token() === SyntaxKind.LessThanToken) { - return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); - } - parseErrorAtCurrentToken(Diagnostics.or_JSX_element_expected); - } - return undefined; - } - - function parseJsxAttributeName() { - const pos = getNodePos(); - scanJsxIdentifier(); - - const attrName = parseIdentifierNameErrorOnUnicodeEscapeSequence(); - if (parseOptional(SyntaxKind.ColonToken)) { - scanJsxIdentifier(); - return finishNode(factory.createJsxNamespacedName(attrName, parseIdentifierNameErrorOnUnicodeEscapeSequence()), pos); - } - return attrName; - } - - function parseJsxSpreadAttribute(): JsxSpreadAttribute { - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); - parseExpected(SyntaxKind.DotDotDotToken); - const expression = parseExpression(); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(factory.createJsxSpreadAttribute(expression), pos); - } - - function parseJsxClosingElement(open: JsxOpeningElement, inExpressionContext: boolean): JsxClosingElement { - const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanSlashToken); - const tagName = parseJsxElementName(); - if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnosticMessage*/ undefined, /*shouldAdvance*/ false)) { - // manually advance the scanner in order to look for jsx text inside jsx - if (inExpressionContext || !tagNamesAreEquivalent(open.tagName, tagName)) { - nextToken(); - } - else { - scanJsxText(); - } - } - return finishNode(factory.createJsxClosingElement(tagName), pos); - } - - function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment { - const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanSlashToken); - if (parseExpected(SyntaxKind.GreaterThanToken, Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment, /*shouldAdvance*/ false)) { - // manually advance the scanner in order to look for jsx text inside jsx - if (inExpressionContext) { - nextToken(); - } - else { - scanJsxText(); - } - } - return finishNode(factory.createJsxJsxClosingFragment(), pos); - } - - function parseTypeAssertion(): TypeAssertion { - Debug.assert(languageVariant !== LanguageVariant.JSX, "Type assertions should never be parsed in JSX; they should be parsed as comparisons or JSX elements/fragments."); - const pos = getNodePos(); - parseExpected(SyntaxKind.LessThanToken); - const type = parseType(); - parseExpected(SyntaxKind.GreaterThanToken); - const expression = parseSimpleUnaryExpression(); - return finishNode(factory.createTypeAssertion(type, expression), pos); - } - - function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() { - nextToken(); - return tokenIsIdentifierOrKeyword(token()) - || token() === SyntaxKind.OpenBracketToken - || isTemplateStartOfTaggedTemplate(); - } - - function isStartOfOptionalPropertyOrElementAccessChain() { - return token() === SyntaxKind.QuestionDotToken - && lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate); - } - - function tryReparseOptionalChain(node: Expression) { - if (node.flags & NodeFlags.OptionalChain) { - return true; - } - // check for an optional chain in a non-null expression - if (isNonNullExpression(node)) { - let expr = node.expression; - while (isNonNullExpression(expr) && !(expr.flags & NodeFlags.OptionalChain)) { - expr = expr.expression; - } - if (expr.flags & NodeFlags.OptionalChain) { - // this is part of an optional chain. Walk down from `node` to `expression` and set the flag. - while (isNonNullExpression(node)) { - (node as Mutable).flags |= NodeFlags.OptionalChain; - node = node.expression; - } - return true; - } - } - return false; - } - - function parsePropertyAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { - const name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true, /*allowUnicodeEscapeSequenceInIdentifierName*/ true); - const isOptionalChain = questionDotToken || tryReparseOptionalChain(expression); - const propertyAccess = isOptionalChain ? - factoryCreatePropertyAccessChain(expression, questionDotToken, name) : - factoryCreatePropertyAccessExpression(expression, name); - if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { - parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); - } - if (isExpressionWithTypeArguments(expression) && expression.typeArguments) { - const pos = expression.typeArguments.pos - 1; - const end = skipTrivia(sourceText, expression.typeArguments.end) + 1; - parseErrorAt(pos, end, Diagnostics.An_instantiation_expression_cannot_be_followed_by_a_property_access); - } - return finishNode(propertyAccess, pos); - } - - function parseElementAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { - let argumentExpression: Expression; - if (token() === SyntaxKind.CloseBracketToken) { - argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument); - } - else { - const argument = allowInAnd(parseExpression); - if (isStringOrNumericLiteralLike(argument)) { - argument.text = internIdentifier(argument.text); - } - argumentExpression = argument; - } - - parseExpected(SyntaxKind.CloseBracketToken); - - const indexedAccess = questionDotToken || tryReparseOptionalChain(expression) ? - factoryCreateElementAccessChain(expression, questionDotToken, argumentExpression) : - factoryCreateElementAccessExpression(expression, argumentExpression); - return finishNode(indexedAccess, pos); - } - - function parseMemberExpressionRest(pos: number, expression: LeftHandSideExpression, allowOptionalChain: boolean): MemberExpression { - while (true) { - let questionDotToken: QuestionDotToken | undefined; - let isPropertyAccess = false; - if (allowOptionalChain && isStartOfOptionalPropertyOrElementAccessChain()) { - questionDotToken = parseExpectedToken(SyntaxKind.QuestionDotToken); - isPropertyAccess = tokenIsIdentifierOrKeyword(token()); - } - else { - isPropertyAccess = parseOptional(SyntaxKind.DotToken); - } - - if (isPropertyAccess) { - expression = parsePropertyAccessExpressionRest(pos, expression, questionDotToken); - continue; - } - - // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName - if ((questionDotToken || !inDecoratorContext()) && parseOptional(SyntaxKind.OpenBracketToken)) { - expression = parseElementAccessExpressionRest(pos, expression, questionDotToken); - continue; - } - - if (isTemplateStartOfTaggedTemplate()) { - // Absorb type arguments into TemplateExpression when preceding expression is ExpressionWithTypeArguments - expression = !questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments ? - parseTaggedTemplateRest(pos, (expression as ExpressionWithTypeArguments).expression, questionDotToken, (expression as ExpressionWithTypeArguments).typeArguments) : - parseTaggedTemplateRest(pos, expression, questionDotToken, /*typeArguments*/ undefined); - continue; - } - - if (!questionDotToken) { - if (token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - nextToken(); - expression = finishNode(factory.createNonNullExpression(expression), pos); - continue; - } - const typeArguments = tryParse(parseTypeArgumentsInExpression); - if (typeArguments) { - expression = finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); - continue; - } - } - - return expression as MemberExpression; - } - } - - function isTemplateStartOfTaggedTemplate() { - return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead; - } - - function parseTaggedTemplateRest(pos: number, tag: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray | undefined) { - const tagExpression = factory.createTaggedTemplateExpression( - tag, - typeArguments, - token() === SyntaxKind.NoSubstitutionTemplateLiteral ? - (reScanTemplateToken(/*isTaggedTemplate*/ true), parseLiteralNode() as NoSubstitutionTemplateLiteral) : - parseTemplateExpression(/*isTaggedTemplate*/ true), - ); - if (questionDotToken || tag.flags & NodeFlags.OptionalChain) { - (tagExpression as Mutable).flags |= NodeFlags.OptionalChain; - } - tagExpression.questionDotToken = questionDotToken; - return finishNode(tagExpression, pos); - } - - function parseCallExpressionRest(pos: number, expression: LeftHandSideExpression): LeftHandSideExpression { - while (true) { - expression = parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); - let typeArguments: NodeArray | undefined; - const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken); - if (questionDotToken) { - typeArguments = tryParse(parseTypeArgumentsInExpression); - if (isTemplateStartOfTaggedTemplate()) { - expression = parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments); - continue; - } - } - if (typeArguments || token() === SyntaxKind.OpenParenToken) { - // Absorb type arguments into CallExpression when preceding expression is ExpressionWithTypeArguments - if (!questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments) { - typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; - expression = (expression as ExpressionWithTypeArguments).expression; - } - const argumentList = parseArgumentList(); - const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? - factoryCreateCallChain(expression, questionDotToken, typeArguments, argumentList) : - factoryCreateCallExpression(expression, typeArguments, argumentList); - expression = finishNode(callExpr, pos); - continue; - } - if (questionDotToken) { - // We parsed `?.` but then failed to parse anything, so report a missing identifier here. - const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected); - expression = finishNode(factoryCreatePropertyAccessChain(expression, questionDotToken, name), pos); - } - break; - } - return expression; - } - - function parseArgumentList() { - parseExpected(SyntaxKind.OpenParenToken); - const result = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression); - parseExpected(SyntaxKind.CloseParenToken); - return result; - } - - function parseTypeArgumentsInExpression() { - if ((contextFlags & NodeFlags.JavaScriptFile) !== 0) { - // TypeArguments must not be parsed in JavaScript files to avoid ambiguity with binary operators. - return undefined; - } - - if (reScanLessThanToken() !== SyntaxKind.LessThanToken) { - return undefined; - } - nextToken(); - - const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); - if (reScanGreaterToken() !== SyntaxKind.GreaterThanToken) { - // If it doesn't have the closing `>` then it's definitely not an type argument list. - return undefined; - } - nextToken(); - - // We successfully parsed a type argument list. The next token determines whether we want to - // treat it as such. If the type argument list is followed by `(` or a template literal, as in - // `f(42)`, we favor the type argument interpretation even though JavaScript would view - // it as a relational expression. - return typeArguments && canFollowTypeArgumentsInExpression() ? typeArguments : undefined; - } - - function canFollowTypeArgumentsInExpression(): boolean { - switch (token()) { - // These tokens can follow a type argument list in a call expression. - case SyntaxKind.OpenParenToken: // foo( - case SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` - case SyntaxKind.TemplateHead: // foo `...${100}...` - return true; - // A type argument list followed by `<` never makes sense, and a type argument list followed - // by `>` is ambiguous with a (re-scanned) `>>` operator, so we disqualify both. Also, in - // this context, `+` and `-` are unary operators, not binary operators. - case SyntaxKind.LessThanToken: - case SyntaxKind.GreaterThanToken: - case SyntaxKind.PlusToken: - case SyntaxKind.MinusToken: - return false; - } - // We favor the type argument list interpretation when it is immediately followed by - // a line break, a binary operator, or something that can't start an expression. - return scanner.hasPrecedingLineBreak() || isBinaryOperator() || !isStartOfExpression(); - } - - function parsePrimaryExpression(): PrimaryExpression { - switch (token()) { - case SyntaxKind.NoSubstitutionTemplateLiteral: - if (scanner.getTokenFlags() & TokenFlags.IsInvalid) { - reScanTemplateToken(/*isTaggedTemplate*/ false); - } - // falls through - case SyntaxKind.NumericLiteral: - case SyntaxKind.BigIntLiteral: - case SyntaxKind.StringLiteral: - return parseLiteralNode(); - case SyntaxKind.ThisKeyword: - case SyntaxKind.SuperKeyword: - case SyntaxKind.NullKeyword: - case SyntaxKind.TrueKeyword: - case SyntaxKind.FalseKeyword: - return parseTokenNode(); - case SyntaxKind.OpenParenToken: - return parseParenthesizedExpression(); - case SyntaxKind.OpenBracketToken: - return parseArrayLiteralExpression(); - case SyntaxKind.OpenBraceToken: - return parseObjectLiteralExpression(); - case SyntaxKind.AsyncKeyword: - // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher. - // If we encounter `async [no LineTerminator here] function` then this is an async - // function; otherwise, its an identifier. - if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) { - break; - } - - return parseFunctionExpression(); - case SyntaxKind.AtToken: - return parseDecoratedExpression(); - case SyntaxKind.ClassKeyword: - return parseClassExpression(); - case SyntaxKind.FunctionKeyword: - return parseFunctionExpression(); - case SyntaxKind.NewKeyword: - return parseNewExpressionOrNewDotTarget(); - case SyntaxKind.SlashToken: - case SyntaxKind.SlashEqualsToken: - if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { - return parseLiteralNode(); - } - break; - case SyntaxKind.TemplateHead: - return parseTemplateExpression(/*isTaggedTemplate*/ false); - case SyntaxKind.PrivateIdentifier: - return parsePrivateIdentifier(); - } - - return parseIdentifier(Diagnostics.Expression_expected); - } - - function parseParenthesizedExpression(): ParenthesizedExpression { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.OpenParenToken); - const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - return withJSDoc(finishNode(factoryCreateParenthesizedExpression(expression), pos), hasJSDoc); - } - - function parseSpreadElement(): Expression { - const pos = getNodePos(); - parseExpected(SyntaxKind.DotDotDotToken); - const expression = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); - return finishNode(factory.createSpreadElement(expression), pos); - } - - function parseArgumentOrArrayLiteralElement(): Expression { - return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() : - token() === SyntaxKind.CommaToken ? finishNode(factory.createOmittedExpression(), getNodePos()) : - parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); - } - - function parseArgumentExpression(): Expression { - return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement); - } - - function parseArrayLiteralExpression(): ArrayLiteralExpression { - const pos = getNodePos(); - const openBracketPosition = scanner.getTokenStart(); - const openBracketParsed = parseExpected(SyntaxKind.OpenBracketToken); - const multiLine = scanner.hasPrecedingLineBreak(); - const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); - parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketParsed, openBracketPosition); - return finishNode(factoryCreateArrayLiteralExpression(elements, multiLine), pos); - } - - function parseObjectLiteralElement(): ObjectLiteralElementLike { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - - if (parseOptionalToken(SyntaxKind.DotDotDotToken)) { - const expression = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); - return withJSDoc(finishNode(factory.createSpreadAssignment(expression), pos), hasJSDoc); - } - - const modifiers = parseModifiers(/*allowDecorators*/ true); - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.GetAccessor, SignatureFlags.None); - } - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.SetAccessor, SignatureFlags.None); - } - - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - const tokenIsIdentifier = isIdentifier(); - const name = parsePropertyName(); - - // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - const exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken); - - if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(pos, hasJSDoc, modifiers, asteriskToken, name, questionToken, exclamationToken); - } - - // check if it is short-hand property assignment or normal property assignment - // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production - // CoverInitializedName[Yield] : - // IdentifierReference[?Yield] Initializer[In, ?Yield] - // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern - let node: Mutable; - const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken); - if (isShorthandPropertyAssignment) { - const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken); - const objectAssignmentInitializer = equalsToken ? allowInAnd(() => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true)) : undefined; - node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer); - // Save equals token for error reporting. - // TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful. - node.equalsToken = equalsToken; - } - else { - parseExpected(SyntaxKind.ColonToken); - const initializer = allowInAnd(() => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true)); - node = factory.createPropertyAssignment(name, initializer); - } - // Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker - node.modifiers = modifiers; - node.questionToken = questionToken; - node.exclamationToken = exclamationToken; - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseObjectLiteralExpression(): ObjectLiteralExpression { - const pos = getNodePos(); - const openBracePosition = scanner.getTokenStart(); - const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken); - const multiLine = scanner.hasPrecedingLineBreak(); - const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); - parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); - return finishNode(factoryCreateObjectLiteralExpression(properties, multiLine), pos); - } - - function parseFunctionExpression(): FunctionExpression { - // GeneratorExpression: - // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody } - // - // FunctionExpression: - // function BindingIdentifier[opt](FormalParameters){ FunctionBody } - const savedDecoratorContext = inDecoratorContext(); - setDecoratorContext(/*val*/ false); - - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const modifiers = parseModifiers(/*allowDecorators*/ false); - parseExpected(SyntaxKind.FunctionKeyword); - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; - const name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalBindingIdentifier) : - isGenerator ? doInYieldContext(parseOptionalBindingIdentifier) : - isAsync ? doInAwaitContext(parseOptionalBindingIdentifier) : - parseOptionalBindingIdentifier(); - - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(isGenerator | isAsync); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlock(isGenerator | isAsync); - - setDecoratorContext(savedDecoratorContext); - - const node = factory.createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseOptionalBindingIdentifier(): Identifier | undefined { - return isBindingIdentifier() ? parseBindingIdentifier() : undefined; - } - - function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty { - const pos = getNodePos(); - parseExpected(SyntaxKind.NewKeyword); - if (parseOptional(SyntaxKind.DotToken)) { - const name = parseIdentifierName(); - return finishNode(factory.createMetaProperty(SyntaxKind.NewKeyword, name), pos); - } - const expressionPos = getNodePos(); - let expression: LeftHandSideExpression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); - let typeArguments: NodeArray | undefined; - // Absorb type arguments into NewExpression when preceding expression is ExpressionWithTypeArguments - if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { - typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; - expression = (expression as ExpressionWithTypeArguments).expression; - } - if (token() === SyntaxKind.QuestionDotToken) { - parseErrorAtCurrentToken(Diagnostics.Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0, getTextOfNodeFromSourceText(sourceText, expression)); - } - const argumentList = token() === SyntaxKind.OpenParenToken ? parseArgumentList() : undefined; - return finishNode(factoryCreateNewExpression(expression, typeArguments, argumentList), pos); - } - - // STATEMENTS - function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const openBracePosition = scanner.getTokenStart(); - const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage); - if (openBraceParsed || ignoreMissingOpenBrace) { - const multiLine = scanner.hasPrecedingLineBreak(); - const statements = parseList(ParsingContext.BlockStatements, parseStatement); - parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); - const result = withJSDoc(finishNode(factoryCreateBlock(statements, multiLine), pos), hasJSDoc); - if (token() === SyntaxKind.EqualsToken) { - parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_whole_assignment_in_parentheses); - nextToken(); - } - - return result; - } - else { - const statements = createMissingList(); - return withJSDoc(finishNode(factoryCreateBlock(statements, /*multiLine*/ undefined), pos), hasJSDoc); - } - } - - function parseFunctionBlock(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block { - const savedYieldContext = inYieldContext(); - setYieldContext(!!(flags & SignatureFlags.Yield)); - - const savedAwaitContext = inAwaitContext(); - setAwaitContext(!!(flags & SignatureFlags.Await)); - - const savedTopLevel = topLevel; - topLevel = false; - - // We may be in a [Decorator] context when parsing a function expression or - // arrow function. The body of the function is not in [Decorator] context. - const saveDecoratorContext = inDecoratorContext(); - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ false); - } - - const block = parseBlock(!!(flags & SignatureFlags.IgnoreMissingOpenBrace), diagnosticMessage); - - if (saveDecoratorContext) { - setDecoratorContext(/*val*/ true); - } - - topLevel = savedTopLevel; - setYieldContext(savedYieldContext); - setAwaitContext(savedAwaitContext); - - return block; - } - - function parseEmptyStatement(): Statement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.SemicolonToken); - return withJSDoc(finishNode(factory.createEmptyStatement(), pos), hasJSDoc); - } - - function parseIfStatement(): IfStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.IfKeyword); - const openParenPosition = scanner.getTokenStart(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); - const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); - const thenStatement = parseStatement(); - const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; - return withJSDoc(finishNode(factoryCreateIfStatement(expression, thenStatement, elseStatement), pos), hasJSDoc); - } - - function parseDoStatement(): DoStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.DoKeyword); - const statement = parseStatement(); - parseExpected(SyntaxKind.WhileKeyword); - const openParenPosition = scanner.getTokenStart(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); - const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); - - // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html - // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in - // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby - // do;while(0)x will have a semicolon inserted before x. - parseOptional(SyntaxKind.SemicolonToken); - return withJSDoc(finishNode(factory.createDoStatement(statement, expression), pos), hasJSDoc); - } - - function parseWhileStatement(): WhileStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.WhileKeyword); - const openParenPosition = scanner.getTokenStart(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); - const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); - const statement = parseStatement(); - return withJSDoc(finishNode(factoryCreateWhileStatement(expression, statement), pos), hasJSDoc); - } - - function parseForOrForInOrForOfStatement(): Statement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.ForKeyword); - const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword); - parseExpected(SyntaxKind.OpenParenToken); - - let initializer!: VariableDeclarationList | Expression; - if (token() !== SyntaxKind.SemicolonToken) { - if ( - token() === SyntaxKind.VarKeyword || token() === SyntaxKind.LetKeyword || token() === SyntaxKind.ConstKeyword || - token() === SyntaxKind.UsingKeyword && lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLineDisallowOf) || - // this one is meant to allow of - token() === SyntaxKind.AwaitKeyword && lookAhead(nextTokenIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine) - ) { - initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true); - } - else { - initializer = disallowInAnd(parseExpression); - } - } - - let node: IterationStatement; - if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) { - const expression = allowInAnd(() => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true)); - parseExpected(SyntaxKind.CloseParenToken); - node = factoryCreateForOfStatement(awaitToken, initializer, expression, parseStatement()); - } - else if (parseOptional(SyntaxKind.InKeyword)) { - const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - node = factory.createForInStatement(initializer, expression, parseStatement()); - } - else { - parseExpected(SyntaxKind.SemicolonToken); - const condition = token() !== SyntaxKind.SemicolonToken && token() !== SyntaxKind.CloseParenToken - ? allowInAnd(parseExpression) - : undefined; - parseExpected(SyntaxKind.SemicolonToken); - const incrementor = token() !== SyntaxKind.CloseParenToken - ? allowInAnd(parseExpression) - : undefined; - parseExpected(SyntaxKind.CloseParenToken); - node = factoryCreateForStatement(initializer, condition, incrementor, parseStatement()); - } - - return withJSDoc(finishNode(node, pos) as ForStatement | ForInOrOfStatement, hasJSDoc); - } - - function parseBreakOrContinueStatement(kind: SyntaxKind): BreakOrContinueStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - - parseExpected(kind === SyntaxKind.BreakStatement ? SyntaxKind.BreakKeyword : SyntaxKind.ContinueKeyword); - const label = canParseSemicolon() ? undefined : parseIdentifier(); - - parseSemicolon(); - const node = kind === SyntaxKind.BreakStatement - ? factory.createBreakStatement(label) - : factory.createContinueStatement(label); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseReturnStatement(): ReturnStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.ReturnKeyword); - const expression = canParseSemicolon() ? undefined : allowInAnd(parseExpression); - parseSemicolon(); - return withJSDoc(finishNode(factory.createReturnStatement(expression), pos), hasJSDoc); - } - - function parseWithStatement(): WithStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.WithKeyword); - const openParenPosition = scanner.getTokenStart(); - const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); - const expression = allowInAnd(parseExpression); - parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); - const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); - return withJSDoc(finishNode(factory.createWithStatement(expression, statement), pos), hasJSDoc); - } - - function parseCaseClause(): CaseClause { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.CaseKeyword); - const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.ColonToken); - const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); - return withJSDoc(finishNode(factory.createCaseClause(expression, statements), pos), hasJSDoc); - } - - function parseDefaultClause(): DefaultClause { - const pos = getNodePos(); - parseExpected(SyntaxKind.DefaultKeyword); - parseExpected(SyntaxKind.ColonToken); - const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); - return finishNode(factory.createDefaultClause(statements), pos); - } - - function parseCaseOrDefaultClause(): CaseOrDefaultClause { - return token() === SyntaxKind.CaseKeyword ? parseCaseClause() : parseDefaultClause(); - } - - function parseCaseBlock(): CaseBlock { - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); - const clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(factory.createCaseBlock(clauses), pos); - } - - function parseSwitchStatement(): SwitchStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.SwitchKeyword); - parseExpected(SyntaxKind.OpenParenToken); - const expression = allowInAnd(parseExpression); - parseExpected(SyntaxKind.CloseParenToken); - const caseBlock = parseCaseBlock(); - return withJSDoc(finishNode(factory.createSwitchStatement(expression, caseBlock), pos), hasJSDoc); - } - - function parseThrowStatement(): ThrowStatement { - // ThrowStatement[Yield] : - // throw [no LineTerminator here]Expression[In, ?Yield]; - - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.ThrowKeyword); - - // Because of automatic semicolon insertion, we need to report error if this - // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' - // directly as that might consume an expression on the following line. - // Instead, we create a "missing" identifier, but don't report an error. The actual error - // will be reported in the grammar walker. - let expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); - if (expression === undefined) { - identifierCount++; - expression = finishNode(factoryCreateIdentifier(""), getNodePos()); - } - if (!tryParseSemicolon()) { - parseErrorForMissingSemicolonAfter(expression); - } - return withJSDoc(finishNode(factory.createThrowStatement(expression), pos), hasJSDoc); - } - - // TODO: Review for error recovery - function parseTryStatement(): TryStatement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - - parseExpected(SyntaxKind.TryKeyword); - const tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); - const catchClause = token() === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; - - // If we don't have a catch clause, then we must have a finally clause. Try to parse - // one out no matter what. - let finallyBlock: Block | undefined; - if (!catchClause || token() === SyntaxKind.FinallyKeyword) { - parseExpected(SyntaxKind.FinallyKeyword, Diagnostics.catch_or_finally_expected); - finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); - } - - return withJSDoc(finishNode(factory.createTryStatement(tryBlock, catchClause, finallyBlock), pos), hasJSDoc); - } - - function parseCatchClause(): CatchClause { - const pos = getNodePos(); - parseExpected(SyntaxKind.CatchKeyword); - - let variableDeclaration; - if (parseOptional(SyntaxKind.OpenParenToken)) { - variableDeclaration = parseVariableDeclaration(); - parseExpected(SyntaxKind.CloseParenToken); - } - else { - // Keep shape of node to avoid degrading performance. - variableDeclaration = undefined; - } - - const block = parseBlock(/*ignoreMissingOpenBrace*/ false); - return finishNode(factory.createCatchClause(variableDeclaration, block), pos); - } - - function parseDebuggerStatement(): Statement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - parseExpected(SyntaxKind.DebuggerKeyword); - parseSemicolon(); - return withJSDoc(finishNode(factory.createDebuggerStatement(), pos), hasJSDoc); - } - - function parseExpressionOrLabeledStatement(): ExpressionStatement | LabeledStatement { - // Avoiding having to do the lookahead for a labeled statement by just trying to parse - // out an expression, seeing if it is identifier and then seeing if it is followed by - // a colon. - const pos = getNodePos(); - let hasJSDoc = hasPrecedingJSDocComment(); - let node: ExpressionStatement | LabeledStatement; - const hasParen = token() === SyntaxKind.OpenParenToken; - const expression = allowInAnd(parseExpression); - if (isIdentifierNode(expression) && parseOptional(SyntaxKind.ColonToken)) { - node = factory.createLabeledStatement(expression, parseStatement()); - } - else { - if (!tryParseSemicolon()) { - parseErrorForMissingSemicolonAfter(expression); - } - node = factoryCreateExpressionStatement(expression); - if (hasParen) { - // do not parse the same jsdoc twice - hasJSDoc = false; - } - } - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function nextTokenIsIdentifierOrKeywordOnSameLine() { - nextToken(); - return tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak(); - } - - function nextTokenIsClassKeywordOnSameLine() { - nextToken(); - return token() === SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak(); - } - - function nextTokenIsFunctionKeywordOnSameLine() { - nextToken(); - return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak(); - } - - function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() { - nextToken(); - return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak(); - } - - function isDeclaration(): boolean { - while (true) { - switch (token()) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: - return true; - case SyntaxKind.UsingKeyword: - return isUsingDeclaration(); - case SyntaxKind.AwaitKeyword: - return isAwaitUsingDeclaration(); - - // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; - // however, an identifier cannot be followed by another identifier on the same line. This is what we - // count on to parse out the respective declarations. For instance, we exploit this to say that - // - // namespace n - // - // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees - // - // namespace - // n - // - // as the identifier 'namespace' on one line followed by the identifier 'n' on another. - // We need to look one token ahead to see if it permissible to try parsing a declaration. - // - // *Note*: 'interface' is actually a strict mode reserved word. So while - // - // "use strict" - // interface - // I {} - // - // could be legal, it would add complexity for very little gain. - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.DeferKeyword: - return nextTokenIsIdentifierOnSameLine(); - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - return nextTokenIsIdentifierOrStringLiteralOnSameLine(); - case SyntaxKind.AbstractKeyword: - case SyntaxKind.AccessorKeyword: - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.ReadonlyKeyword: - const previousToken = token(); - nextToken(); - // ASI takes effect for this modifier. - if (scanner.hasPrecedingLineBreak()) { - return false; - } - if (previousToken === SyntaxKind.DeclareKeyword && token() === SyntaxKind.TypeKeyword) { - // If we see 'declare type', then commit to parsing a type alias. parseTypeAliasDeclaration will - // report Line_break_not_permitted_here if needed. - return true; - } - continue; - - case SyntaxKind.GlobalKeyword: - nextToken(); - return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.Identifier || token() === SyntaxKind.ExportKeyword; - - case SyntaxKind.ImportKeyword: - nextToken(); - return token() === SyntaxKind.DeferKeyword || token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token()); - case SyntaxKind.ExportKeyword: - let currentToken = nextToken(); - if (currentToken === SyntaxKind.TypeKeyword) { - currentToken = lookAhead(nextToken); - } - if ( - currentToken === SyntaxKind.EqualsToken || currentToken === SyntaxKind.AsteriskToken || - currentToken === SyntaxKind.OpenBraceToken || currentToken === SyntaxKind.DefaultKeyword || - currentToken === SyntaxKind.AsKeyword || currentToken === SyntaxKind.AtToken - ) { - return true; - } - continue; - - case SyntaxKind.StaticKeyword: - nextToken(); - continue; - - default: - return false; - } - } - } - - function isStartOfDeclaration(): boolean { - return lookAhead(isDeclaration); - } - - function isStartOfStatement(): boolean { - switch (token()) { - case SyntaxKind.AtToken: - case SyntaxKind.SemicolonToken: - case SyntaxKind.OpenBraceToken: - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.UsingKeyword: - case SyntaxKind.FunctionKeyword: - case SyntaxKind.ClassKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.IfKeyword: - case SyntaxKind.DoKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.ForKeyword: - case SyntaxKind.ContinueKeyword: - case SyntaxKind.BreakKeyword: - case SyntaxKind.ReturnKeyword: - case SyntaxKind.WithKeyword: - case SyntaxKind.SwitchKeyword: - case SyntaxKind.ThrowKeyword: - case SyntaxKind.TryKeyword: - case SyntaxKind.DebuggerKeyword: - // 'catch' and 'finally' do not actually indicate that the code is part of a statement, - // however, we say they are here so that we may gracefully parse them and error later. - // falls through - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: - return true; - - case SyntaxKind.ImportKeyword: - return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot); - - case SyntaxKind.ConstKeyword: - case SyntaxKind.ExportKeyword: - return isStartOfDeclaration(); - - case SyntaxKind.AsyncKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.GlobalKeyword: - case SyntaxKind.DeferKeyword: - // When these don't start a declaration, they're an identifier in an expression statement - return true; - - case SyntaxKind.AccessorKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: - // When these don't start a declaration, they may be the start of a class member if an identifier - // immediately follows. Otherwise they're an identifier in an expression statement. - return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); - - default: - return isStartOfExpression(); - } - } - - function nextTokenIsBindingIdentifierOrStartOfDestructuring() { - nextToken(); - return isBindingIdentifier() || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken; - } - - function isLetDeclaration() { - // In ES6 'let' always starts a lexical declaration if followed by an identifier or { - // or [. - return lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuring); - } - - function nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLineDisallowOf() { - return nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(/*disallowOf*/ true); - } - - function nextTokenIsEqualsOrSemicolonOrColonToken() { - nextToken(); - return token() === SyntaxKind.EqualsToken || token() === SyntaxKind.SemicolonToken || token() === SyntaxKind.ColonToken; - } - - function nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(disallowOf?: boolean) { - nextToken(); - if (disallowOf && token() === SyntaxKind.OfKeyword) { - return lookAhead(nextTokenIsEqualsOrSemicolonOrColonToken); - } - return (isBindingIdentifier() || token() === SyntaxKind.OpenBraceToken) && !scanner.hasPrecedingLineBreak(); - } - - function isUsingDeclaration() { - // 'using' always starts a lexical declaration if followed by an identifier. We also eagerly parse - // |ObjectBindingPattern| so that we can report a grammar error during check. We don't parse out - // |ArrayBindingPattern| since it potentially conflicts with element access (i.e., `using[x]`). - return lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine); - } - - function nextTokenIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine(disallowOf?: boolean) { - if (nextToken() === SyntaxKind.UsingKeyword) { - return nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(disallowOf); - } - return false; - } - - function isAwaitUsingDeclaration() { - // 'await using' always starts a lexical declaration if followed by an identifier. We also eagerly parse - // |ObjectBindingPattern| so that we can report a grammar error during check. We don't parse out - // |ArrayBindingPattern| since it potentially conflicts with element access (i.e., `await using[x]`). - return lookAhead(nextTokenIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine); - } - - function parseStatement(): Statement { - switch (token()) { - case SyntaxKind.SemicolonToken: - return parseEmptyStatement(); - case SyntaxKind.OpenBraceToken: - return parseBlock(/*ignoreMissingOpenBrace*/ false); - case SyntaxKind.VarKeyword: - return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); - case SyntaxKind.LetKeyword: - if (isLetDeclaration()) { - return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); - } - break; - case SyntaxKind.AwaitKeyword: - if (isAwaitUsingDeclaration()) { - return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); - } - break; - case SyntaxKind.UsingKeyword: - if (isUsingDeclaration()) { - return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); - } - break; - case SyntaxKind.FunctionKeyword: - return parseFunctionDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); - case SyntaxKind.ClassKeyword: - return parseClassDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); - case SyntaxKind.IfKeyword: - return parseIfStatement(); - case SyntaxKind.DoKeyword: - return parseDoStatement(); - case SyntaxKind.WhileKeyword: - return parseWhileStatement(); - case SyntaxKind.ForKeyword: - return parseForOrForInOrForOfStatement(); - case SyntaxKind.ContinueKeyword: - return parseBreakOrContinueStatement(SyntaxKind.ContinueStatement); - case SyntaxKind.BreakKeyword: - return parseBreakOrContinueStatement(SyntaxKind.BreakStatement); - case SyntaxKind.ReturnKeyword: - return parseReturnStatement(); - case SyntaxKind.WithKeyword: - return parseWithStatement(); - case SyntaxKind.SwitchKeyword: - return parseSwitchStatement(); - case SyntaxKind.ThrowKeyword: - return parseThrowStatement(); - case SyntaxKind.TryKeyword: - // Include 'catch' and 'finally' for error recovery. - // falls through - case SyntaxKind.CatchKeyword: - case SyntaxKind.FinallyKeyword: - return parseTryStatement(); - case SyntaxKind.DebuggerKeyword: - return parseDebuggerStatement(); - case SyntaxKind.AtToken: - return parseDeclaration(); - case SyntaxKind.AsyncKeyword: - case SyntaxKind.InterfaceKeyword: - case SyntaxKind.TypeKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - case SyntaxKind.DeclareKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.EnumKeyword: - case SyntaxKind.ExportKeyword: - case SyntaxKind.ImportKeyword: - case SyntaxKind.PrivateKeyword: - case SyntaxKind.ProtectedKeyword: - case SyntaxKind.PublicKeyword: - case SyntaxKind.AbstractKeyword: - case SyntaxKind.AccessorKeyword: - case SyntaxKind.StaticKeyword: - case SyntaxKind.ReadonlyKeyword: - case SyntaxKind.GlobalKeyword: - if (isStartOfDeclaration()) { - return parseDeclaration(); - } - break; - } - return parseExpressionOrLabeledStatement(); - } - - function isDeclareModifier(modifier: ModifierLike) { - return modifier.kind === SyntaxKind.DeclareKeyword; - } - - function parseDeclaration(): Statement { - // `parseListElement` attempted to get the reused node at this position, - // but the ambient context flag was not yet set, so the node appeared - // not reusable in that context. - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const modifiers = parseModifiers(/*allowDecorators*/ true); - const isAmbient = some(modifiers, isDeclareModifier); - if (isAmbient) { - const node = tryReuseAmbientDeclaration(pos); - if (node) { - return node; - } - - for (const m of modifiers!) { - (m as Mutable).flags |= NodeFlags.Ambient; - } - return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(pos, hasJSDoc, modifiers)); - } - else { - return parseDeclarationWorker(pos, hasJSDoc, modifiers); - } - } - - function tryReuseAmbientDeclaration(pos: number): Statement | undefined { - return doInsideOfContext(NodeFlags.Ambient, () => { - // TODO(jakebailey): this is totally wrong; `parsingContext` is the result of ORing a bunch of `1 << ParsingContext.XYZ`. - // The enum should really be a bunch of flags. - const node = currentNode(parsingContext, pos); - if (node) { - return consumeNode(node) as Statement; - } - }); - } - - function parseDeclarationWorker(pos: number, hasJSDoc: boolean, modifiersIn: NodeArray | undefined): Statement { - switch (token()) { - case SyntaxKind.VarKeyword: - case SyntaxKind.LetKeyword: - case SyntaxKind.ConstKeyword: - case SyntaxKind.UsingKeyword: - return parseVariableStatement(pos, hasJSDoc, modifiersIn); - case SyntaxKind.AwaitKeyword: - if (!isAwaitUsingDeclaration()) { - break; - } - return parseVariableStatement(pos, hasJSDoc, modifiersIn); - case SyntaxKind.FunctionKeyword: - return parseFunctionDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.ClassKeyword: - return parseClassDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.InterfaceKeyword: - return parseInterfaceDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.TypeKeyword: - return parseTypeAliasDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.EnumKeyword: - return parseEnumDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.GlobalKeyword: - case SyntaxKind.ModuleKeyword: - case SyntaxKind.NamespaceKeyword: - return parseModuleDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.ImportKeyword: - return parseImportDeclarationOrImportEqualsDeclaration(pos, hasJSDoc, modifiersIn); - case SyntaxKind.ExportKeyword: - nextToken(); - switch (token()) { - case SyntaxKind.DefaultKeyword: - case SyntaxKind.EqualsToken: - return parseExportAssignment(pos, hasJSDoc, modifiersIn); - case SyntaxKind.AsKeyword: - return parseNamespaceExportDeclaration(pos, hasJSDoc, modifiersIn); - default: - return parseExportDeclaration(pos, hasJSDoc, modifiersIn); - } - } - if (modifiersIn) { - // We reached this point because we encountered decorators and/or modifiers and assumed a declaration - // would follow. For recovery and error reporting purposes, return an incomplete declaration. - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - setTextRangePos(missing, pos); - (missing as Mutable).modifiers = modifiersIn; - return missing; - } - return undefined!; // TODO: GH#18217 - } - - function nextTokenIsStringLiteral() { - return nextToken() === SyntaxKind.StringLiteral; - } - - function nextTokenIsFromKeywordOrEqualsToken() { - nextToken(); - return token() === SyntaxKind.FromKeyword || token() === SyntaxKind.EqualsToken; - } - - function nextTokenIsIdentifierOrStringLiteralOnSameLine() { - nextToken(); - return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === SyntaxKind.StringLiteral); - } - - function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block | undefined { - if (token() !== SyntaxKind.OpenBraceToken) { - if (flags & SignatureFlags.Type) { - parseTypeMemberSemicolon(); - return; - } - if (canParseSemicolon()) { - parseSemicolon(); - return; - } - } - return parseFunctionBlock(flags, diagnosticMessage); - } - - // DECLARATIONS - - function parseArrayBindingElement(): ArrayBindingElement { - const pos = getNodePos(); - if (token() === SyntaxKind.CommaToken) { - return finishNode(factory.createOmittedExpression(), pos); - } - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - const name = parseIdentifierOrPattern(); - const initializer = parseInitializer(); - return finishNode(factory.createBindingElement(dotDotDotToken, /*propertyName*/ undefined, name, initializer), pos); - } - - function parseObjectBindingElement(): BindingElement { - const pos = getNodePos(); - const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); - const tokenIsIdentifier = isBindingIdentifier(); - let propertyName: PropertyName | undefined = parsePropertyName(); - let name: BindingName; - if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) { - name = propertyName as Identifier; - propertyName = undefined; - } - else { - parseExpected(SyntaxKind.ColonToken); - name = parseIdentifierOrPattern(); - } - const initializer = parseInitializer(); - return finishNode(factory.createBindingElement(dotDotDotToken, propertyName, name, initializer), pos); - } - - function parseObjectBindingPattern(): ObjectBindingPattern { - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBraceToken); - const elements = allowInAnd(() => parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement)); - parseExpected(SyntaxKind.CloseBraceToken); - return finishNode(factory.createObjectBindingPattern(elements), pos); - } - - function parseArrayBindingPattern(): ArrayBindingPattern { - const pos = getNodePos(); - parseExpected(SyntaxKind.OpenBracketToken); - const elements = allowInAnd(() => parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement)); - parseExpected(SyntaxKind.CloseBracketToken); - return finishNode(factory.createArrayBindingPattern(elements), pos); - } - - function isBindingIdentifierOrPrivateIdentifierOrPattern() { - return token() === SyntaxKind.OpenBraceToken - || token() === SyntaxKind.OpenBracketToken - || token() === SyntaxKind.PrivateIdentifier - || isBindingIdentifier(); - } - - function parseIdentifierOrPattern(privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier | BindingPattern { - if (token() === SyntaxKind.OpenBracketToken) { - return parseArrayBindingPattern(); - } - if (token() === SyntaxKind.OpenBraceToken) { - return parseObjectBindingPattern(); - } - return parseBindingIdentifier(privateIdentifierDiagnosticMessage); - } - - function parseVariableDeclarationAllowExclamation() { - return parseVariableDeclaration(/*allowExclamation*/ true); - } - - function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations); - let exclamationToken: ExclamationToken | undefined; - if ( - allowExclamation && name.kind === SyntaxKind.Identifier && - token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak() - ) { - exclamationToken = parseTokenNode>(); - } - const type = parseTypeAnnotation(); - const initializer = isInOrOfKeyword(token()) ? undefined : parseInitializer(); - const node = factoryCreateVariableDeclaration(name, exclamationToken, type, initializer); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseVariableDeclarationList(inForStatementInitializer: boolean): VariableDeclarationList { - const pos = getNodePos(); - - let flags: NodeFlags = 0; - switch (token()) { - case SyntaxKind.VarKeyword: - break; - case SyntaxKind.LetKeyword: - flags |= NodeFlags.Let; - break; - case SyntaxKind.ConstKeyword: - flags |= NodeFlags.Const; - break; - case SyntaxKind.UsingKeyword: - flags |= NodeFlags.Using; - break; - case SyntaxKind.AwaitKeyword: - if (!isAwaitUsingDeclaration()) { - break; - } - flags |= NodeFlags.AwaitUsing; - nextToken(); - break; - default: - Debug.fail(); - } - - nextToken(); - - // The user may have written the following: - // - // for (let of X) { } - // - // In this case, we want to parse an empty declaration list, and then parse 'of' - // as a keyword. The reason this is not automatic is that 'of' is a valid identifier. - // So we need to look ahead to determine if 'of' should be treated as a keyword in - // this context. - // The checker will then give an error that there is an empty declaration list. - let declarations: readonly VariableDeclaration[]; - if (token() === SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) { - declarations = createMissingList(); - } - else { - const savedDisallowIn = inDisallowInContext(); - setDisallowInContext(inForStatementInitializer); - - declarations = parseDelimitedList( - ParsingContext.VariableDeclarations, - inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation, - ); - - setDisallowInContext(savedDisallowIn); - } - - return finishNode(factoryCreateVariableDeclarationList(declarations, flags), pos); - } - - function canFollowContextualOfKeyword(): boolean { - return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken; - } - - function parseVariableStatement(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): VariableStatement { - const declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); - parseSemicolon(); - const node = factoryCreateVariableStatement(modifiers, declarationList); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseFunctionDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): FunctionDeclaration { - const savedAwaitContext = inAwaitContext(); - const modifierFlags = modifiersToFlags(modifiers); - parseExpected(SyntaxKind.FunctionKeyword); - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - // We don't parse the name here in await context, instead we will report a grammar error in the checker. - const name = modifierFlags & ModifierFlags.Default ? parseOptionalBindingIdentifier() : parseBindingIdentifier(); - const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = modifierFlags & ModifierFlags.Async ? SignatureFlags.Await : SignatureFlags.None; - const typeParameters = parseTypeParameters(); - if (modifierFlags & ModifierFlags.Export) setAwaitContext(/*value*/ true); - const parameters = parseParameters(isGenerator | isAsync); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected); - setAwaitContext(savedAwaitContext); - const node = factory.createFunctionDeclaration(modifiers, asteriskToken, name, typeParameters, parameters, type, body); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseConstructorName() { - if (token() === SyntaxKind.ConstructorKeyword) { - return parseExpected(SyntaxKind.ConstructorKeyword); - } - if (token() === SyntaxKind.StringLiteral && lookAhead(nextToken) === SyntaxKind.OpenParenToken) { - return tryParse(() => { - const literalNode = parseLiteralNode(); - return literalNode.text === "constructor" ? literalNode : undefined; - }); - } - } - - function tryParseConstructorDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ConstructorDeclaration | undefined { - return tryParse(() => { - if (parseConstructorName()) { - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(SignatureFlags.None); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); - const node = factory.createConstructorDeclaration(modifiers, parameters, body); - - // Attach invalid nodes if they exist so that we can report them in the grammar checker. - (node as Mutable).typeParameters = typeParameters; - (node as Mutable).type = type; - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - }); - } - - function parseMethodDeclaration( - pos: number, - hasJSDoc: boolean, - modifiers: NodeArray | undefined, - asteriskToken: AsteriskToken | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - exclamationToken: ExclamationToken | undefined, - diagnosticMessage?: DiagnosticMessage, - ): MethodDeclaration { - const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; - const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(isGenerator | isAsync); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); - const node = factory.createMethodDeclaration( - modifiers, - asteriskToken, - name, - questionToken, - typeParameters, - parameters, - type, - body, - ); - - // An exclamation token on a method is invalid syntax and will be handled by the grammar checker - (node as Mutable).exclamationToken = exclamationToken; - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parsePropertyDeclaration( - pos: number, - hasJSDoc: boolean, - modifiers: NodeArray | undefined, - name: PropertyName, - questionToken: QuestionToken | undefined, - ): PropertyDeclaration { - const exclamationToken = !questionToken && !scanner.hasPrecedingLineBreak() ? parseOptionalToken(SyntaxKind.ExclamationToken) : undefined; - const type = parseTypeAnnotation(); - const initializer = doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext | NodeFlags.DisallowInContext, parseInitializer); - parseSemicolonAfterPropertyName(name, type, initializer); - const node = factory.createPropertyDeclaration( - modifiers, - name, - questionToken || exclamationToken, - type, - initializer, - ); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parsePropertyOrMethodDeclaration( - pos: number, - hasJSDoc: boolean, - modifiers: NodeArray | undefined, - ): PropertyDeclaration | MethodDeclaration { - const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); - const name = parsePropertyName(); - // Note: this is not legal as per the grammar. But we allow it in the parser and - // report an error in the grammar checker. - const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); - if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { - return parseMethodDeclaration(pos, hasJSDoc, modifiers, asteriskToken, name, questionToken, /*exclamationToken*/ undefined, Diagnostics.or_expected); - } - return parsePropertyDeclaration(pos, hasJSDoc, modifiers, name, questionToken); - } - - function parseAccessorDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, kind: AccessorDeclaration["kind"], flags: SignatureFlags): AccessorDeclaration { - const name = parsePropertyName(); - const typeParameters = parseTypeParameters(); - const parameters = parseParameters(SignatureFlags.None); - const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); - const body = parseFunctionBlockOrSemicolon(flags); - const node = kind === SyntaxKind.GetAccessor - ? factory.createGetAccessorDeclaration(modifiers, name, parameters, type, body) - : factory.createSetAccessorDeclaration(modifiers, name, parameters, body); - // Keep track of `typeParameters` (for both) and `type` (for setters) if they were parsed those indicate grammar errors - (node as Mutable).typeParameters = typeParameters; - if (isSetAccessorDeclaration(node)) (node as Mutable).type = type; - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function isClassMemberStart(): boolean { - let idToken: SyntaxKind | undefined; - - if (token() === SyntaxKind.AtToken) { - return true; - } - - // Eat up all modifiers, but hold on to the last one in case it is actually an identifier. - while (isModifierKind(token())) { - idToken = token(); - // If the idToken is a class modifier (protected, private, public, and static), it is - // certain that we are starting to parse class member. This allows better error recovery - // Example: - // public foo() ... // true - // public @dec blah ... // true; we will then report an error later - // export public ... // true; we will then report an error later - if (isClassMemberModifier(idToken)) { - return true; - } - - nextToken(); - } - - if (token() === SyntaxKind.AsteriskToken) { - return true; - } - - // Try to get the first property-like token following all modifiers. - // This can either be an identifier or the 'get' or 'set' keywords. - if (isLiteralPropertyName()) { - idToken = token(); - nextToken(); - } - - // Index signatures and computed properties are class members; we can parse. - if (token() === SyntaxKind.OpenBracketToken) { - return true; - } - - // If we were able to get any potential identifier... - if (idToken !== undefined) { - // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse. - if (!isKeyword(idToken) || idToken === SyntaxKind.SetKeyword || idToken === SyntaxKind.GetKeyword) { - return true; - } - - // If it *is* a keyword, but not an accessor, check a little farther along - // to see if it should actually be parsed as a class member. - switch (token()) { - case SyntaxKind.OpenParenToken: // Method declaration - case SyntaxKind.LessThanToken: // Generic Method declaration - case SyntaxKind.ExclamationToken: // Non-null assertion on property name - case SyntaxKind.ColonToken: // Type Annotation for declaration - case SyntaxKind.EqualsToken: // Initializer for declaration - case SyntaxKind.QuestionToken: // Not valid, but permitted so that it gets caught later on. - return true; - default: - // Covers - // - Semicolons (declaration termination) - // - Closing braces (end-of-class, must be declaration) - // - End-of-files (not valid, but permitted so that it gets caught later on) - // - Line-breaks (enabling *automatic semicolon insertion*) - return canParseSemicolon(); - } - } - - return false; - } - - function parseClassStaticBlockDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ClassStaticBlockDeclaration { - parseExpectedToken(SyntaxKind.StaticKeyword); - const body = parseClassStaticBlockBody(); - const node = withJSDoc(finishNode(factory.createClassStaticBlockDeclaration(body), pos), hasJSDoc); - (node as Mutable).modifiers = modifiers; - return node; - } - - function parseClassStaticBlockBody() { - const savedYieldContext = inYieldContext(); - const savedAwaitContext = inAwaitContext(); - - setYieldContext(false); - setAwaitContext(true); - - const body = parseBlock(/*ignoreMissingOpenBrace*/ false); - - setYieldContext(savedYieldContext); - setAwaitContext(savedAwaitContext); - - return body; - } - - function parseDecoratorExpression() { - if (inAwaitContext() && token() === SyntaxKind.AwaitKeyword) { - // `@await` is is disallowed in an [Await] context, but can cause parsing to go off the rails - // This simply parses the missing identifier and moves on. - const pos = getNodePos(); - const awaitExpression = parseIdentifier(Diagnostics.Expression_expected); - nextToken(); - const memberExpression = parseMemberExpressionRest(pos, awaitExpression, /*allowOptionalChain*/ true); - return parseCallExpressionRest(pos, memberExpression); - } - return parseLeftHandSideExpressionOrHigher(); - } - - function tryParseDecorator(): Decorator | undefined { - const pos = getNodePos(); - if (!parseOptional(SyntaxKind.AtToken)) { - return undefined; - } - const expression = doInDecoratorContext(parseDecoratorExpression); - return finishNode(factory.createDecorator(expression), pos); - } - - function tryParseModifier(hasSeenStaticModifier: boolean, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): Modifier | undefined { - const pos = getNodePos(); - const kind = token(); - - if (token() === SyntaxKind.ConstKeyword && permitConstAsModifier) { - // We need to ensure that any subsequent modifiers appear on the same line - // so that when 'const' is a standalone declaration, we don't issue an error. - if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { - return undefined; - } - } - else if (stopOnStartOfClassStaticBlock && token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { - return undefined; - } - else if (hasSeenStaticModifier && token() === SyntaxKind.StaticKeyword) { - return undefined; - } - else { - if (!parseAnyContextualModifier()) { - return undefined; - } - } - - return finishNode(factoryCreateToken(kind as Modifier["kind"]), pos); - } - - /* - * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member. - * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect - * and turns it into a standalone declaration), then it is better to parse it and report an error later. - * - * In such situations, 'permitConstAsModifier' should be set to true. - */ - function parseModifiers(allowDecorators: false, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined; - function parseModifiers(allowDecorators: true, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined; - function parseModifiers(allowDecorators: boolean, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined { - const pos = getNodePos(); - let list: ModifierLike[] | undefined; - let decorator, modifier, hasSeenStaticModifier = false, hasLeadingModifier = false, hasTrailingDecorator = false; - - // Decorators should be contiguous in a list of modifiers but can potentially appear in two places (i.e., `[...leadingDecorators, ...leadingModifiers, ...trailingDecorators, ...trailingModifiers]`). - // The leading modifiers *should* only contain `export` and `default` when trailingDecorators are present, but we'll handle errors for any other leading modifiers in the checker. - // It is illegal to have both leadingDecorators and trailingDecorators, but we will report that as a grammar check in the checker. - - // parse leading decorators - if (allowDecorators && token() === SyntaxKind.AtToken) { - while (decorator = tryParseDecorator()) { - list = append(list, decorator); - } - } - - // parse leading modifiers - while (modifier = tryParseModifier(hasSeenStaticModifier, permitConstAsModifier, stopOnStartOfClassStaticBlock)) { - if (modifier.kind === SyntaxKind.StaticKeyword) hasSeenStaticModifier = true; - list = append(list, modifier); - hasLeadingModifier = true; - } - - // parse trailing decorators, but only if we parsed any leading modifiers - if (hasLeadingModifier && allowDecorators && token() === SyntaxKind.AtToken) { - while (decorator = tryParseDecorator()) { - list = append(list, decorator); - hasTrailingDecorator = true; - } - } - - // parse trailing modifiers, but only if we parsed any trailing decorators - if (hasTrailingDecorator) { - while (modifier = tryParseModifier(hasSeenStaticModifier, permitConstAsModifier, stopOnStartOfClassStaticBlock)) { - if (modifier.kind === SyntaxKind.StaticKeyword) hasSeenStaticModifier = true; - list = append(list, modifier); - } - } - - return list && createNodeArray(list, pos); - } - - function parseModifiersForArrowFunction(): NodeArray | undefined { - let modifiers: NodeArray | undefined; - if (token() === SyntaxKind.AsyncKeyword) { - const pos = getNodePos(); - nextToken(); - const modifier = finishNode(factoryCreateToken(SyntaxKind.AsyncKeyword), pos); - modifiers = createNodeArray([modifier], pos); - } - return modifiers; - } - - function parseClassElement(): ClassElement { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - if (token() === SyntaxKind.SemicolonToken) { - nextToken(); - return withJSDoc(finishNode(factory.createSemicolonClassElement(), pos), hasJSDoc); - } - - const modifiers = parseModifiers(/*allowDecorators*/ true, /*permitConstAsModifier*/ true, /*stopOnStartOfClassStaticBlock*/ true); - if (token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { - return parseClassStaticBlockDeclaration(pos, hasJSDoc, modifiers); - } - - if (parseContextualModifier(SyntaxKind.GetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.GetAccessor, SignatureFlags.None); - } - - if (parseContextualModifier(SyntaxKind.SetKeyword)) { - return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.SetAccessor, SignatureFlags.None); - } - - if (token() === SyntaxKind.ConstructorKeyword || token() === SyntaxKind.StringLiteral) { - const constructorDeclaration = tryParseConstructorDeclaration(pos, hasJSDoc, modifiers); - if (constructorDeclaration) { - return constructorDeclaration; - } - } - - if (isIndexSignature()) { - return parseIndexSignatureDeclaration(pos, hasJSDoc, modifiers); - } - - // It is very important that we check this *after* checking indexers because - // the [ token can start an index signature or a computed property name - if ( - tokenIsIdentifierOrKeyword(token()) || - token() === SyntaxKind.StringLiteral || - token() === SyntaxKind.NumericLiteral || - token() === SyntaxKind.BigIntLiteral || - token() === SyntaxKind.AsteriskToken || - token() === SyntaxKind.OpenBracketToken - ) { - const isAmbient = some(modifiers, isDeclareModifier); - if (isAmbient) { - for (const m of modifiers!) { - (m as Mutable).flags |= NodeFlags.Ambient; - } - return doInsideOfContext(NodeFlags.Ambient, () => parsePropertyOrMethodDeclaration(pos, hasJSDoc, modifiers)); - } - else { - return parsePropertyOrMethodDeclaration(pos, hasJSDoc, modifiers); - } - } - - if (modifiers) { - // treat this as a property declaration with a missing name. - const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - return parsePropertyDeclaration(pos, hasJSDoc, modifiers, name, /*questionToken*/ undefined); - } - - // 'isClassMemberStart' should have hinted not to attempt parsing. - return Debug.fail("Should not have attempted to parse class member declaration."); - } - - function parseDecoratedExpression(): PrimaryExpression { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const modifiers = parseModifiers(/*allowDecorators*/ true); - if (token() === SyntaxKind.ClassKeyword) { - return parseClassDeclarationOrExpression(pos, hasJSDoc, modifiers, SyntaxKind.ClassExpression) as ClassExpression; - } - - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Expression_expected); - setTextRangePos(missing, pos); - (missing as Mutable).modifiers = modifiers; - return missing; - } - - function parseClassExpression(): ClassExpression { - return parseClassDeclarationOrExpression(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined, SyntaxKind.ClassExpression) as ClassExpression; - } - - function parseClassDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ClassDeclaration { - return parseClassDeclarationOrExpression(pos, hasJSDoc, modifiers, SyntaxKind.ClassDeclaration) as ClassDeclaration; - } - - function parseClassDeclarationOrExpression(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, kind: ClassLikeDeclaration["kind"]): ClassLikeDeclaration { - const savedAwaitContext = inAwaitContext(); - parseExpected(SyntaxKind.ClassKeyword); - - // We don't parse the name here in await context, instead we will report a grammar error in the checker. - const name = parseNameOfClassDeclarationOrExpression(); - const typeParameters = parseTypeParameters(); - if (some(modifiers, isExportModifier)) setAwaitContext(/*value*/ true); - const heritageClauses = parseHeritageClauses(); - - let members; - if (parseExpected(SyntaxKind.OpenBraceToken)) { - // ClassTail[Yield,Await] : (Modified) See 14.5 - // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } - members = parseClassMembers(); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - members = createMissingList(); - } - setAwaitContext(savedAwaitContext); - const node = kind === SyntaxKind.ClassDeclaration - ? factory.createClassDeclaration(modifiers, name, typeParameters, heritageClauses, members) - : factory.createClassExpression(modifiers, name, typeParameters, heritageClauses, members); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseNameOfClassDeclarationOrExpression(): Identifier | undefined { - // implements is a future reserved word so - // 'class implements' might mean either - // - class expression with omitted name, 'implements' starts heritage clause - // - class with name 'implements' - // 'isImplementsClause' helps to disambiguate between these two cases - return isBindingIdentifier() && !isImplementsClause() - ? createIdentifier(isBindingIdentifier()) - : undefined; - } - - function isImplementsClause() { - return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword); - } - - function parseHeritageClauses(): NodeArray | undefined { - // ClassTail[Yield,Await] : (Modified) See 14.5 - // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } - - if (isHeritageClause()) { - return parseList(ParsingContext.HeritageClauses, parseHeritageClause); - } - - return undefined; - } - - function parseHeritageClause(): HeritageClause { - const pos = getNodePos(); - const tok = token(); - Debug.assert(tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword); // isListElement() should ensure this. - nextToken(); - const types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); - return finishNode(factory.createHeritageClause(tok, types), pos); - } - - function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments { - const pos = getNodePos(); - const expression = parseLeftHandSideExpressionOrHigher(); - if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { - return expression as ExpressionWithTypeArguments; - } - const typeArguments = tryParseTypeArguments(); - return finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); - } - - function tryParseTypeArguments(): NodeArray | undefined { - return token() === SyntaxKind.LessThanToken ? - parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) : undefined; - } - - function isHeritageClause(): boolean { - return token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; - } - - function parseClassMembers(): NodeArray { - return parseList(ParsingContext.ClassMembers, parseClassElement); - } - - function parseInterfaceDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): InterfaceDeclaration { - parseExpected(SyntaxKind.InterfaceKeyword); - const name = parseIdentifier(); - const typeParameters = parseTypeParameters(); - const heritageClauses = parseHeritageClauses(); - const members = parseObjectTypeMembers(); - const node = factory.createInterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, members); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseTypeAliasDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): TypeAliasDeclaration { - parseExpected(SyntaxKind.TypeKeyword); - if (scanner.hasPrecedingLineBreak()) { - parseErrorAtCurrentToken(Diagnostics.Line_break_not_permitted_here); - } - const name = parseIdentifier(); - const typeParameters = parseTypeParameters(); - parseExpected(SyntaxKind.EqualsToken); - const type = token() === SyntaxKind.IntrinsicKeyword && tryParse(parseKeywordAndNoDot) || parseType(); - parseSemicolon(); - const node = factory.createTypeAliasDeclaration(modifiers, name, typeParameters, type); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - // In an ambient declaration, the grammar only allows integer literals as initializers. - // In a non-ambient declaration, the grammar allows uninitialized members only in a - // ConstantEnumMemberSection, which starts at the beginning of an enum declaration - // or any time an integer literal initializer is encountered. - function parseEnumMember(): EnumMember { - const pos = getNodePos(); - const hasJSDoc = hasPrecedingJSDocComment(); - const name = parsePropertyName(); - const initializer = allowInAnd(parseInitializer); - return withJSDoc(finishNode(factory.createEnumMember(name, initializer), pos), hasJSDoc); - } - - function parseEnumDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): EnumDeclaration { - parseExpected(SyntaxKind.EnumKeyword); - const name = parseIdentifier(); - let members; - if (parseExpected(SyntaxKind.OpenBraceToken)) { - members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember)); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - members = createMissingList(); - } - const node = factory.createEnumDeclaration(modifiers, name, members); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseModuleBlock(): ModuleBlock { - const pos = getNodePos(); - let statements; - if (parseExpected(SyntaxKind.OpenBraceToken)) { - statements = parseList(ParsingContext.BlockStatements, parseStatement); - parseExpected(SyntaxKind.CloseBraceToken); - } - else { - statements = createMissingList(); - } - return finishNode(factory.createModuleBlock(statements), pos); - } - - function parseModuleOrNamespaceDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, flags: NodeFlags): ModuleDeclaration { - // If we are parsing a dotted namespace name, we want to - // propagate the 'Namespace' flag across the names if set. - const namespaceFlag = flags & NodeFlags.Namespace; - const name = flags & NodeFlags.NestedNamespace ? parseIdentifierName() : parseIdentifier(); - const body = parseOptional(SyntaxKind.DotToken) - ? parseModuleOrNamespaceDeclaration(getNodePos(), /*hasJSDoc*/ false, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) as NamespaceDeclaration - : parseModuleBlock(); - const node = factory.createModuleDeclaration(modifiers, name, body, flags); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseAmbientExternalModuleDeclaration(pos: number, hasJSDoc: boolean, modifiersIn: NodeArray | undefined): ModuleDeclaration { - let flags: NodeFlags = 0; - let name; - if (token() === SyntaxKind.GlobalKeyword) { - // parse 'global' as name of global scope augmentation - name = parseIdentifier(); - flags |= NodeFlags.GlobalAugmentation; - } - else { - name = parseLiteralNode() as StringLiteral; - name.text = internIdentifier(name.text); - } - let body: ModuleBlock | undefined; - if (token() === SyntaxKind.OpenBraceToken) { - body = parseModuleBlock(); - } - else { - parseSemicolon(); - } - const node = factory.createModuleDeclaration(modifiersIn, name, body, flags); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseModuleDeclaration(pos: number, hasJSDoc: boolean, modifiersIn: NodeArray | undefined): ModuleDeclaration { - let flags: NodeFlags = 0; - if (token() === SyntaxKind.GlobalKeyword) { - // global augmentation - return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, modifiersIn); - } - else if (parseOptional(SyntaxKind.NamespaceKeyword)) { - flags |= NodeFlags.Namespace; - } - else { - parseExpected(SyntaxKind.ModuleKeyword); - if (token() === SyntaxKind.StringLiteral) { - return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, modifiersIn); - } - } - return parseModuleOrNamespaceDeclaration(pos, hasJSDoc, modifiersIn, flags); - } - - function isExternalModuleReference() { - return token() === SyntaxKind.RequireKeyword && - lookAhead(nextTokenIsOpenParen); - } - - function nextTokenIsOpenParen() { - return nextToken() === SyntaxKind.OpenParenToken; - } - - function nextTokenIsOpenBrace() { - return nextToken() === SyntaxKind.OpenBraceToken; - } - - function nextTokenIsSlash() { - return nextToken() === SyntaxKind.SlashToken; - } - - function parseNamespaceExportDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): NamespaceExportDeclaration { - parseExpected(SyntaxKind.AsKeyword); - parseExpected(SyntaxKind.NamespaceKeyword); - const name = parseIdentifier(); - parseSemicolon(); - const node = factory.createNamespaceExportDeclaration(name); - // NamespaceExportDeclaration nodes cannot have decorators or modifiers, so we attach them here so we can report them in the grammar checker - (node as Mutable).modifiers = modifiers; - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseImportDeclarationOrImportEqualsDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ImportEqualsDeclaration | ImportDeclaration { - parseExpected(SyntaxKind.ImportKeyword); - - const afterImportPos = scanner.getTokenFullStart(); - - // We don't parse the identifier here in await context, instead we will report a grammar error in the checker. - let identifier: Identifier | undefined; - if (isIdentifier()) { - identifier = parseIdentifier(); - } - - let phaseModifier: ImportPhaseModifierSyntaxKind | undefined; - if ( - identifier?.escapedText === "type" && - (token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) && - (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration()) - ) { - phaseModifier = SyntaxKind.TypeKeyword; - identifier = isIdentifier() ? parseIdentifier() : undefined; - } - else if ( - identifier?.escapedText === "defer" && - (token() === SyntaxKind.FromKeyword ? !lookAhead(nextTokenIsStringLiteral) : token() !== SyntaxKind.CommaToken && token() !== SyntaxKind.EqualsToken) - ) { - phaseModifier = SyntaxKind.DeferKeyword; - identifier = isIdentifier() ? parseIdentifier() : undefined; - } - - if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier !== SyntaxKind.DeferKeyword) { - return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, phaseModifier === SyntaxKind.TypeKeyword); - } - - const importClause = tryParseImportClause(identifier, afterImportPos, phaseModifier, /*skipJsDocLeadingAsterisks*/ undefined); - const moduleSpecifier = parseModuleSpecifier(); - const attributes = tryParseImportAttributes(); - - parseSemicolon(); - const node = factory.createImportDeclaration(modifiers, importClause, moduleSpecifier, attributes); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifierSyntaxKind, skipJsDocLeadingAsterisks = false) { - // ImportDeclaration: - // import ImportClause from ModuleSpecifier ; - // import ModuleSpecifier; - let importClause: ImportClause | undefined; - if ( - identifier || // import id - token() === SyntaxKind.AsteriskToken || // import * - token() === SyntaxKind.OpenBraceToken // import { - ) { - importClause = parseImportClause(identifier, pos, phaseModifier, skipJsDocLeadingAsterisks); - parseExpected(SyntaxKind.FromKeyword); - } - return importClause; - } - - function tryParseImportAttributes() { - const currentToken = token(); - if (currentToken === SyntaxKind.WithKeyword || (currentToken === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak())) { - return parseImportAttributes(currentToken); - } - } - - function parseImportAttribute() { - const pos = getNodePos(); - const name = tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral; - parseExpected(SyntaxKind.ColonToken); - const value = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); - return finishNode(factory.createImportAttribute(name, value), pos); - } - - function parseImportAttributes(token: SyntaxKind.AssertKeyword | SyntaxKind.WithKeyword, skipKeyword?: true) { - const pos = getNodePos(); - if (!skipKeyword) { - parseExpected(token); - } - const openBracePosition = scanner.getTokenStart(); - if (parseExpected(SyntaxKind.OpenBraceToken)) { - const multiLine = scanner.hasPrecedingLineBreak(); - const elements = parseDelimitedList(ParsingContext.ImportAttributes, parseImportAttribute, /*considerSemicolonAsDelimiter*/ true); - if (!parseExpected(SyntaxKind.CloseBraceToken)) { - const lastError = lastOrUndefined(parseDiagnostics); - if (lastError && lastError.code === Diagnostics._0_expected.code) { - addRelatedInfo( - lastError, - createDetachedDiagnostic(fileName, sourceText, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}"), - ); - } - } - return finishNode(factory.createImportAttributes(elements, multiLine, token), pos); - } - else { - const elements = createNodeArray([], getNodePos(), /*end*/ undefined, /*hasTrailingComma*/ false); - return finishNode(factory.createImportAttributes(elements, /*multiLine*/ false, token), pos); - } - } - - function tokenAfterImportDefinitelyProducesImportDeclaration() { - return token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken; - } - - function tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() { - // In `import id ___`, the current token decides whether to produce - // an ImportDeclaration or ImportEqualsDeclaration. - return token() === SyntaxKind.CommaToken || token() === SyntaxKind.FromKeyword; - } - - function parseImportEqualsDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, identifier: Identifier, isTypeOnly: boolean): ImportEqualsDeclaration { - parseExpected(SyntaxKind.EqualsToken); - const moduleReference = parseModuleReference(); - parseSemicolon(); - const node = factory.createImportEqualsDeclaration(modifiers, isTypeOnly, identifier, moduleReference); - const finished = withJSDoc(finishNode(node, pos), hasJSDoc); - return finished; - } - - function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifierSyntaxKind, skipJsDocLeadingAsterisks: boolean) { - // ImportClause: - // ImportedDefaultBinding - // NameSpaceImport - // NamedImports - // ImportedDefaultBinding, NameSpaceImport - // ImportedDefaultBinding, NamedImports - - // If there was no default import or if there is comma token after default import - // parse namespace or named imports - let namedBindings: NamespaceImport | NamedImports | undefined; - if ( - !identifier || - parseOptional(SyntaxKind.CommaToken) - ) { - if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(true); - if (token() === SyntaxKind.AsteriskToken) { - namedBindings = parseNamespaceImport(); - } - else { - namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); - } - if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false); - } - - return finishNode(factory.createImportClause(phaseModifier, identifier, namedBindings), pos); - } - - function parseModuleReference() { - return isExternalModuleReference() - ? parseExternalModuleReference() - : parseEntityName(/*allowReservedWords*/ false); - } - - function parseExternalModuleReference() { - const pos = getNodePos(); - parseExpected(SyntaxKind.RequireKeyword); - parseExpected(SyntaxKind.OpenParenToken); - const expression = parseModuleSpecifier(); - parseExpected(SyntaxKind.CloseParenToken); - return finishNode(factory.createExternalModuleReference(expression), pos); - } - - function parseModuleSpecifier(): Expression { - if (token() === SyntaxKind.StringLiteral) { - const result = parseLiteralNode(); - result.text = internIdentifier(result.text); - return result; - } - else { - // We allow arbitrary expressions here, even though the grammar only allows string - // literals. We check to ensure that it is only a string literal later in the grammar - // check pass. - return parseExpression(); - } - } - - function parseNamespaceImport(): NamespaceImport { - // NameSpaceImport: - // * as ImportedBinding - const pos = getNodePos(); - parseExpected(SyntaxKind.AsteriskToken); - parseExpected(SyntaxKind.AsKeyword); - const name = parseIdentifier(); - return finishNode(factory.createNamespaceImport(name), pos); - } - - function canParseModuleExportName(): boolean { - return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral; - } - - function parseModuleExportName(parseName: () => Identifier): ModuleExportName { - return token() === SyntaxKind.StringLiteral ? parseLiteralNode() as StringLiteral : parseName(); - } - - function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports; - function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports; - function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports { - const pos = getNodePos(); - - // NamedImports: - // { } - // { ImportsList } - // { ImportsList, } - - // ImportsList: - // ImportSpecifier - // ImportsList, ImportSpecifier - const node = kind === SyntaxKind.NamedImports - ? factory.createNamedImports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseImportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)) - : factory.createNamedExports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseExportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)); - return finishNode(node, pos); - } - - function parseExportSpecifier() { - const hasJSDoc = hasPrecedingJSDocComment(); - return withJSDoc(parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier) as ExportSpecifier, hasJSDoc); - } - - function parseImportSpecifier() { - return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier) as ImportSpecifier; - } - - function parseImportOrExportSpecifier(kind: SyntaxKind): ImportOrExportSpecifier { - const pos = getNodePos(); - // ImportSpecifier: - // BindingIdentifier - // ModuleExportName as BindingIdentifier - // ExportSpecifier: - // ModuleExportName - // ModuleExportName as ModuleExportName - let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); - let checkIdentifierStart = scanner.getTokenStart(); - let checkIdentifierEnd = scanner.getTokenEnd(); - let isTypeOnly = false; - let propertyName: ModuleExportName | undefined; - let canParseAsKeyword = true; - let name = parseModuleExportName(parseIdentifierName); - if (name.kind === SyntaxKind.Identifier && name.escapedText === "type") { - // If the first token of an import specifier is 'type', there are a lot of possibilities, - // especially if we see 'as' afterwards: - // - // import { type } from "mod"; - isTypeOnly: false, name: type - // import { type as } from "mod"; - isTypeOnly: true, name: as - // import { type as as } from "mod"; - isTypeOnly: false, name: as, propertyName: type - // import { type as as as } from "mod"; - isTypeOnly: true, name: as, propertyName: as - if (token() === SyntaxKind.AsKeyword) { - // { type as ...? } - const firstAs = parseIdentifierName(); - if (token() === SyntaxKind.AsKeyword) { - // { type as as ...? } - const secondAs = parseIdentifierName(); - if (canParseModuleExportName()) { - // { type as as something } - // { type as as "something" } - isTypeOnly = true; - propertyName = firstAs; - name = parseModuleExportName(parseNameWithKeywordCheck); - canParseAsKeyword = false; - } - else { - // { type as as } - propertyName = name; - name = secondAs; - canParseAsKeyword = false; - } - } - else if (canParseModuleExportName()) { - // { type as something } - // { type as "something" } - propertyName = name; - canParseAsKeyword = false; - name = parseModuleExportName(parseNameWithKeywordCheck); - } - else { - // { type as } - isTypeOnly = true; - name = firstAs; - } - } - else if (canParseModuleExportName()) { - // { type something ...? } - // { type "something" ...? } - isTypeOnly = true; - name = parseModuleExportName(parseNameWithKeywordCheck); - } - } - - if (canParseAsKeyword && token() === SyntaxKind.AsKeyword) { - propertyName = name; - parseExpected(SyntaxKind.AsKeyword); - name = parseModuleExportName(parseNameWithKeywordCheck); - } - if (kind === SyntaxKind.ImportSpecifier) { - if (name.kind !== SyntaxKind.Identifier) { - // ImportSpecifier casts "name" to Identifier below, so make sure it's an identifier - parseErrorAt(skipTrivia(sourceText, name.pos), name.end, Diagnostics.Identifier_expected); - name = setTextRangePosEnd(createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false), name.pos, name.pos); - } - else if (checkIdentifierIsKeyword) { - parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected); - } - } - const node = kind === SyntaxKind.ImportSpecifier - ? factory.createImportSpecifier(isTypeOnly, propertyName, name as Identifier) - : factory.createExportSpecifier(isTypeOnly, propertyName, name); - return finishNode(node, pos); - - function parseNameWithKeywordCheck() { - checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); - checkIdentifierStart = scanner.getTokenStart(); - checkIdentifierEnd = scanner.getTokenEnd(); - return parseIdentifierName(); - } - } - - function parseNamespaceExport(pos: number): NamespaceExport { - return finishNode(factory.createNamespaceExport(parseModuleExportName(parseIdentifierName)), pos); - } - - function parseExportDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ExportDeclaration { - const savedAwaitContext = inAwaitContext(); - setAwaitContext(/*value*/ true); - let exportClause: NamedExportBindings | undefined; - let moduleSpecifier: Expression | undefined; - let attributes: ImportAttributes | undefined; - const isTypeOnly = parseOptional(SyntaxKind.TypeKeyword); - const namespaceExportPos = getNodePos(); - if (parseOptional(SyntaxKind.AsteriskToken)) { - if (parseOptional(SyntaxKind.AsKeyword)) { - exportClause = parseNamespaceExport(namespaceExportPos); - } - parseExpected(SyntaxKind.FromKeyword); - moduleSpecifier = parseModuleSpecifier(); - } - else { - exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); - // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, - // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) - // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. - if (token() === SyntaxKind.FromKeyword || (token() === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { - parseExpected(SyntaxKind.FromKeyword); - moduleSpecifier = parseModuleSpecifier(); - } - } - const currentToken = token(); - if (moduleSpecifier && (currentToken === SyntaxKind.WithKeyword || currentToken === SyntaxKind.AssertKeyword) && !scanner.hasPrecedingLineBreak()) { - attributes = parseImportAttributes(currentToken); - } - parseSemicolon(); - setAwaitContext(savedAwaitContext); - const node = factory.createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, attributes); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - function parseExportAssignment(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ExportAssignment { - const savedAwaitContext = inAwaitContext(); - setAwaitContext(/*value*/ true); - let isExportEquals: boolean | undefined; - if (parseOptional(SyntaxKind.EqualsToken)) { - isExportEquals = true; - } - else { - parseExpected(SyntaxKind.DefaultKeyword); - } - const expression = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); - parseSemicolon(); - setAwaitContext(savedAwaitContext); - const node = factory.createExportAssignment(modifiers, isExportEquals, expression); - return withJSDoc(finishNode(node, pos), hasJSDoc); - } - - // dprint-ignore - const enum ParsingContext { - SourceElements, // Elements in source file - BlockStatements, // Statements in block - SwitchClauses, // Clauses in switch statement - SwitchClauseStatements, // Statements in switch clause - TypeMembers, // Members in interface or type literal - ClassMembers, // Members in class declaration - EnumMembers, // Members in enum declaration - HeritageClauseElement, // Elements in a heritage clause - VariableDeclarations, // Variable declarations in variable statement - ObjectBindingElements, // Binding elements in object binding list - ArrayBindingElements, // Binding elements in array binding list - ArgumentExpressions, // Expressions in argument list - ObjectLiteralMembers, // Members in object literal - JsxAttributes, // Attributes in jsx element - JsxChildren, // Things between opening and closing JSX tags - ArrayLiteralMembers, // Members in array literal - Parameters, // Parameters in parameter list - JSDocParameters, // JSDoc parameters in parameter list of JSDoc function type - RestProperties, // Property names in a rest type list - TypeParameters, // Type parameters in type parameter list - TypeArguments, // Type arguments in type argument list - TupleElementTypes, // Element types in tuple element type list - HeritageClauses, // Heritage clauses for a class or interface declaration. - ImportOrExportSpecifiers, // Named import clause's import specifier list, - ImportAttributes, // Import attributes - JSDocComment, // Parsing via JSDocParser - Count, // Number of parsing contexts - } - - const enum Tristate { - False, - True, - Unknown, - } - - export namespace JSDocParser { - export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { jsDocTypeExpression: JSDocTypeExpression; diagnostics: Diagnostic[]; } | undefined { - initializeState("file.js", content, ScriptTarget.Latest, /*syntaxCursor*/ undefined, ScriptKind.JS, JSDocParsingMode.ParseAll); - scanner.setText(content, start, length); - currentToken = scanner.scan(); - const jsDocTypeExpression = parseJSDocTypeExpression(); - - const sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false, [], factoryCreateToken(SyntaxKind.EndOfFileToken), NodeFlags.None, noop); - const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); - if (jsDocDiagnostics) { - sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); - } - - clearState(); - - return jsDocTypeExpression ? { jsDocTypeExpression, diagnostics } : undefined; - } - - // Parses out a JSDoc type expression. - export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression { - const pos = getNodePos(); - const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken); - const type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); - if (!mayOmitBraces || hasBrace) { - parseExpectedJSDoc(SyntaxKind.CloseBraceToken); - } - - const result = factory.createJSDocTypeExpression(type); - fixupParentReferences(result); - return finishNode(result, pos); - } - - export function parseJSDocNameReference(): JSDocNameReference { - const pos = getNodePos(); - const hasBrace = parseOptional(SyntaxKind.OpenBraceToken); - const p2 = getNodePos(); - let entityName: EntityName | JSDocMemberName = parseEntityName(/*allowReservedWords*/ false); - while (token() === SyntaxKind.PrivateIdentifier) { - reScanHashToken(); // rescan #id as # id - nextTokenJSDoc(); // then skip the # - entityName = finishNode(factory.createJSDocMemberName(entityName, parseIdentifier()), p2); - } - if (hasBrace) { - parseExpectedJSDoc(SyntaxKind.CloseBraceToken); - } - - const result = factory.createJSDocNameReference(entityName); - fixupParentReferences(result); - return finishNode(result, pos); - } - - export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc; diagnostics: Diagnostic[]; } | undefined { - initializeState("", content, ScriptTarget.Latest, /*syntaxCursor*/ undefined, ScriptKind.JS, JSDocParsingMode.ParseAll); - const jsDoc = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); - - const sourceFile = { languageVariant: LanguageVariant.Standard, text: content } as SourceFile; - const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); - clearState(); - - return jsDoc ? { jsDoc, diagnostics } : undefined; - } - - export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc | undefined { - const saveToken = currentToken; - const saveParseDiagnosticsLength = parseDiagnostics.length; - const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; - - const comment = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); - setParent(comment, parent); - - if (contextFlags & NodeFlags.JavaScriptFile) { - if (!jsDocDiagnostics) { - jsDocDiagnostics = []; - } - addRange(jsDocDiagnostics, parseDiagnostics, saveParseDiagnosticsLength); - } - currentToken = saveToken; - parseDiagnostics.length = saveParseDiagnosticsLength; - parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; - return comment; - } - - const enum JSDocState { - BeginningOfLine, - SawAsterisk, - SavingComments, - SavingBackticks, // NOTE: Only used when parsing tag comments - } - - const enum PropertyLikeParse { - Property = 1 << 0, - Parameter = 1 << 1, - CallbackParameter = 1 << 2, - } - - function parseJSDocCommentWorker(start = 0, length: number | undefined): JSDoc | undefined { - const content = sourceText; - const end = length === undefined ? content.length : start + length; - length = end - start; - - Debug.assert(start >= 0); - Debug.assert(start <= end); - Debug.assert(end <= content.length); - - // Check for /** (JSDoc opening part) - if (!isJSDocLikeText(content, start)) { - return undefined; - } - - let tags: JSDocTag[]; - let tagsPos: number; - let tagsEnd: number; - let linkEnd: number; - let commentsPos: number | undefined; - let comments: string[] = []; - const parts: JSDocComment[] = []; - - const saveParsingContext = parsingContext; - parsingContext |= 1 << ParsingContext.JSDocComment; - - // + 3 for leading /**, - 5 in total for /** */ - const result = scanner.scanRange(start + 3, length - 5, doJSDocScan); - parsingContext = saveParsingContext; - return result; - - function doJSDocScan() { - // Initially we can parse out a tag. We also have seen a starting asterisk. - // This is so that /** * @type */ doesn't parse. - let state = JSDocState.SawAsterisk; - let margin: number | undefined; - // + 4 for leading '/** ' - // + 1 because the last index of \n is always one index before the first character in the line and coincidentally, if there is no \n before start, it is -1, which is also one index before the first character - let indent = start - (content.lastIndexOf("\n", start) + 1) + 4; - function pushComment(text: string) { - if (!margin) { - margin = indent; - } - comments.push(text); - indent += text.length; - } - - nextTokenJSDoc(); - while (parseOptionalJsdoc(SyntaxKind.WhitespaceTrivia)); - if (parseOptionalJsdoc(SyntaxKind.NewLineTrivia)) { - state = JSDocState.BeginningOfLine; - indent = 0; - } - loop: - while (true) { - switch (token()) { - case SyntaxKind.AtToken: - removeTrailingWhitespace(comments); - if (!commentsPos) commentsPos = getNodePos(); - addTag(parseTag(indent)); - // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. - // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning - // for malformed examples like `/** @param {string} x @returns {number} the length */` - state = JSDocState.BeginningOfLine; - margin = undefined; - break; - case SyntaxKind.NewLineTrivia: - comments.push(scanner.getTokenText()); - state = JSDocState.BeginningOfLine; - indent = 0; - break; - case SyntaxKind.AsteriskToken: - const asterisk = scanner.getTokenText(); - if (state === JSDocState.SawAsterisk) { - // If we've already seen an asterisk, then we can no longer parse a tag on this line - state = JSDocState.SavingComments; - pushComment(asterisk); - } - else { - Debug.assert(state === JSDocState.BeginningOfLine); - // Ignore the first asterisk on a line - state = JSDocState.SawAsterisk; - indent += asterisk.length; - } - break; - case SyntaxKind.WhitespaceTrivia: - Debug.assert(state !== JSDocState.SavingComments, "whitespace shouldn't come from the scanner while saving top-level comment text"); - // only collect whitespace if we're already saving comments or have just crossed the comment indent margin - const whitespace = scanner.getTokenText(); - if (margin !== undefined && indent + whitespace.length > margin) { - comments.push(whitespace.slice(margin - indent)); - } - indent += whitespace.length; - break; - case SyntaxKind.EndOfFileToken: - break loop; - case SyntaxKind.JSDocCommentTextToken: - state = JSDocState.SavingComments; - pushComment(scanner.getTokenValue()); - break; - case SyntaxKind.OpenBraceToken: - state = JSDocState.SavingComments; - const commentEnd = scanner.getTokenFullStart(); - const linkStart = scanner.getTokenEnd() - 1; - const link = parseJSDocLink(linkStart); - if (link) { - if (!linkEnd) { - removeLeadingNewlines(comments); - } - parts.push(finishNode(factory.createJSDocText(comments.join("")), linkEnd ?? start, commentEnd)); - parts.push(link); - comments = []; - linkEnd = scanner.getTokenEnd(); - break; - } - // fallthrough if it's not a {@link sequence - default: - // Anything else is doc comment text. We just save it. Because it - // wasn't a tag, we can no longer parse a tag on this line until we hit the next - // line break. - state = JSDocState.SavingComments; - pushComment(scanner.getTokenText()); - break; - } - if (state === JSDocState.SavingComments) { - nextJSDocCommentTextToken(/*inBackticks*/ false); - } - else { - nextTokenJSDoc(); - } - } - const trimmedComments = comments.join("").trimEnd(); - if (parts.length && trimmedComments.length) { - parts.push(finishNode(factory.createJSDocText(trimmedComments), linkEnd ?? start, commentsPos)); - } - if (parts.length && tags) Debug.assertIsDefined(commentsPos, "having parsed tags implies that the end of the comment span should be set"); - const tagsArray = tags && createNodeArray(tags, tagsPos, tagsEnd); - return finishNode(factory.createJSDocComment(parts.length ? createNodeArray(parts, start, commentsPos) : trimmedComments.length ? trimmedComments : undefined, tagsArray), start, end); - } - - function removeLeadingNewlines(comments: string[]) { - while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) { - comments.shift(); - } - } - - function removeTrailingWhitespace(comments: string[]) { - while (comments.length) { - const trimmed = comments[comments.length - 1].trimEnd(); - if (trimmed === "") { - comments.pop(); - } - else if (trimmed.length < comments[comments.length - 1].length) { - comments[comments.length - 1] = trimmed; - break; - } - else { - break; - } - } - } - - function isNextNonwhitespaceTokenEndOfFile(): boolean { - // We must use infinite lookahead, as there could be any number of newlines :( - while (true) { - nextTokenJSDoc(); - if (token() === SyntaxKind.EndOfFileToken) { - return true; - } - if (!(token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia)) { - return false; - } - } - } - - function skipWhitespace(): void { - if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { - if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { - return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range - } - } - while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { - nextTokenJSDoc(); - } - } - - function skipWhitespaceOrAsterisk(): string { - if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { - if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { - return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range - } - } - - let precedingLineBreak = scanner.hasPrecedingLineBreak(); - let seenLineBreak = false; - let indentText = ""; - while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { - indentText += scanner.getTokenText(); - if (token() === SyntaxKind.NewLineTrivia) { - precedingLineBreak = true; - seenLineBreak = true; - indentText = ""; - } - else if (token() === SyntaxKind.AsteriskToken) { - precedingLineBreak = false; - } - nextTokenJSDoc(); - } - return seenLineBreak ? indentText : ""; - } - - function parseTag(margin: number) { - Debug.assert(token() === SyntaxKind.AtToken); - const start = scanner.getTokenStart(); - nextTokenJSDoc(); - - const tagName = parseJSDocIdentifierName(/*message*/ undefined); - const indentText = skipWhitespaceOrAsterisk(); - - let tag: JSDocTag | undefined; - switch (tagName.escapedText) { - case "author": - tag = parseAuthorTag(start, tagName, margin, indentText); - break; - case "implements": - tag = parseImplementsTag(start, tagName, margin, indentText); - break; - case "augments": - case "extends": - tag = parseAugmentsTag(start, tagName, margin, indentText); - break; - case "class": - case "constructor": - tag = parseSimpleTag(start, factory.createJSDocClassTag, tagName, margin, indentText); - break; - case "public": - tag = parseSimpleTag(start, factory.createJSDocPublicTag, tagName, margin, indentText); - break; - case "private": - tag = parseSimpleTag(start, factory.createJSDocPrivateTag, tagName, margin, indentText); - break; - case "protected": - tag = parseSimpleTag(start, factory.createJSDocProtectedTag, tagName, margin, indentText); - break; - case "readonly": - tag = parseSimpleTag(start, factory.createJSDocReadonlyTag, tagName, margin, indentText); - break; - case "override": - tag = parseSimpleTag(start, factory.createJSDocOverrideTag, tagName, margin, indentText); - break; - case "deprecated": - hasDeprecatedTag = true; - tag = parseSimpleTag(start, factory.createJSDocDeprecatedTag, tagName, margin, indentText); - break; - case "this": - tag = parseThisTag(start, tagName, margin, indentText); - break; - case "enum": - tag = parseEnumTag(start, tagName, margin, indentText); - break; - case "arg": - case "argument": - case "param": - return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, margin); - case "return": - case "returns": - tag = parseReturnTag(start, tagName, margin, indentText); - break; - case "template": - tag = parseTemplateTag(start, tagName, margin, indentText); - break; - case "type": - tag = parseTypeTag(start, tagName, margin, indentText); - break; - case "typedef": - tag = parseTypedefTag(start, tagName, margin, indentText); - break; - case "callback": - tag = parseCallbackTag(start, tagName, margin, indentText); - break; - case "overload": - tag = parseOverloadTag(start, tagName, margin, indentText); - break; - case "satisfies": - tag = parseSatisfiesTag(start, tagName, margin, indentText); - break; - case "see": - tag = parseSeeTag(start, tagName, margin, indentText); - break; - case "exception": - case "throws": - tag = parseThrowsTag(start, tagName, margin, indentText); - break; - case "import": - tag = parseImportTag(start, tagName, margin, indentText); - break; - default: - tag = parseUnknownTag(start, tagName, margin, indentText); - break; - } - return tag; - } - - function parseTrailingTagComments(pos: number, end: number, margin: number, indentText: string) { - // some tags, like typedef and callback, have already parsed their comments earlier - if (!indentText) { - margin += end - pos; - } - return parseTagComments(margin, indentText.slice(margin)); - } - - function parseTagComments(indent: number, initialMargin?: string): string | NodeArray | undefined { - const commentsPos = getNodePos(); - let comments: string[] = []; - const parts: JSDocComment[] = []; - let linkEnd; - let state = JSDocState.BeginningOfLine; - let margin: number | undefined; - function pushComment(text: string) { - if (!margin) { - margin = indent; - } - comments.push(text); - indent += text.length; - } - if (initialMargin !== undefined) { - // jump straight to saving comments if there is some initial indentation - if (initialMargin !== "") { - pushComment(initialMargin); - } - state = JSDocState.SawAsterisk; - } - let tok = token() as JSDocSyntaxKind | SyntaxKind.JSDocCommentTextToken; - loop: - while (true) { - switch (tok) { - case SyntaxKind.NewLineTrivia: - state = JSDocState.BeginningOfLine; - // don't use pushComment here because we want to keep the margin unchanged - comments.push(scanner.getTokenText()); - indent = 0; - break; - case SyntaxKind.AtToken: - scanner.resetTokenState(scanner.getTokenEnd() - 1); - break loop; - case SyntaxKind.EndOfFileToken: - // Done - break loop; - case SyntaxKind.WhitespaceTrivia: - Debug.assert(state !== JSDocState.SavingComments && state !== JSDocState.SavingBackticks, "whitespace shouldn't come from the scanner while saving comment text"); - const whitespace = scanner.getTokenText(); - // if the whitespace crosses the margin, take only the whitespace that passes the margin - if (margin !== undefined && indent + whitespace.length > margin) { - comments.push(whitespace.slice(margin - indent)); - state = JSDocState.SavingComments; - } - indent += whitespace.length; - break; - case SyntaxKind.OpenBraceToken: - state = JSDocState.SavingComments; - const commentEnd = scanner.getTokenFullStart(); - const linkStart = scanner.getTokenEnd() - 1; - const link = parseJSDocLink(linkStart); - if (link) { - parts.push(finishNode(factory.createJSDocText(comments.join("")), linkEnd ?? commentsPos, commentEnd)); - parts.push(link); - comments = []; - linkEnd = scanner.getTokenEnd(); - } - else { - pushComment(scanner.getTokenText()); - } - break; - case SyntaxKind.BacktickToken: - if (state === JSDocState.SavingBackticks) { - state = JSDocState.SavingComments; - } - else { - state = JSDocState.SavingBackticks; - } - pushComment(scanner.getTokenText()); - break; - case SyntaxKind.JSDocCommentTextToken: - if (state !== JSDocState.SavingBackticks) { - state = JSDocState.SavingComments; // leading identifiers start recording as well - } - pushComment(scanner.getTokenValue()); - break; - case SyntaxKind.AsteriskToken: - if (state === JSDocState.BeginningOfLine) { - // leading asterisks start recording on the *next* (non-whitespace) token - state = JSDocState.SawAsterisk; - indent += 1; - break; - } - // record the * as a comment - // falls through - default: - if (state !== JSDocState.SavingBackticks) { - state = JSDocState.SavingComments; // leading identifiers start recording as well - } - pushComment(scanner.getTokenText()); - break; - } - if (state === JSDocState.SavingComments || state === JSDocState.SavingBackticks) { - tok = nextJSDocCommentTextToken(state === JSDocState.SavingBackticks); - } - else { - tok = nextTokenJSDoc(); - } - } - - removeLeadingNewlines(comments); - const trimmedComments = comments.join("").trimEnd(); - if (parts.length) { - if (trimmedComments.length) { - parts.push(finishNode(factory.createJSDocText(trimmedComments), linkEnd ?? commentsPos)); - } - return createNodeArray(parts, commentsPos, scanner.getTokenEnd()); - } - else if (trimmedComments.length) { - return trimmedComments; - } - } - - function parseJSDocLink(start: number) { - const linkType = tryParse(parseJSDocLinkPrefix); - if (!linkType) { - return undefined; - } - nextTokenJSDoc(); // start at token after link, then skip any whitespace - skipWhitespace(); - const name = parseJSDocLinkName(); - const text = []; - while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.NewLineTrivia && token() !== SyntaxKind.EndOfFileToken) { - text.push(scanner.getTokenText()); - nextTokenJSDoc(); - } - const create = linkType === "link" ? factory.createJSDocLink - : linkType === "linkcode" ? factory.createJSDocLinkCode - : factory.createJSDocLinkPlain; - return finishNode(create(name, text.join("")), start, scanner.getTokenEnd()); - } - - function parseJSDocLinkName() { - if (tokenIsIdentifierOrKeyword(token())) { - const pos = getNodePos(); - - let name: EntityName | JSDocMemberName = parseIdentifierName(); - while (parseOptional(SyntaxKind.DotToken)) { - name = finishNode(factory.createQualifiedName(name, token() === SyntaxKind.PrivateIdentifier ? createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false) : parseIdentifierName()), pos); - } - while (token() === SyntaxKind.PrivateIdentifier) { - reScanHashToken(); - nextTokenJSDoc(); - name = finishNode(factory.createJSDocMemberName(name, parseIdentifier()), pos); - } - return name; - } - return undefined; - } - - function parseJSDocLinkPrefix() { - skipWhitespaceOrAsterisk(); - if ( - token() === SyntaxKind.OpenBraceToken - && nextTokenJSDoc() === SyntaxKind.AtToken - && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) - ) { - const kind = scanner.getTokenValue(); - if (isJSDocLinkTag(kind)) return kind; - } - } - - function isJSDocLinkTag(kind: string) { - return kind === "link" || kind === "linkcode" || kind === "linkplain"; - } - - function parseUnknownTag(start: number, tagName: Identifier, indent: number, indentText: string) { - return finishNode(factory.createJSDocUnknownTag(tagName, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); - } - - function addTag(tag: JSDocTag | undefined): void { - if (!tag) { - return; - } - if (!tags) { - tags = [tag]; - tagsPos = tag.pos; - } - else { - tags.push(tag); - } - tagsEnd = tag.end; - } - - function tryParseTypeExpression(): JSDocTypeExpression | undefined { - skipWhitespaceOrAsterisk(); - return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; - } - - function parseBracketNameInPropertyAndParamTag(): { name: EntityName; isBracketed: boolean; } { - // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' - const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); - if (isBracketed) { - skipWhitespace(); - } - // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild - const isBackquoted = parseOptionalJsdoc(SyntaxKind.BacktickToken); - const name = parseJSDocEntityName(); - if (isBackquoted) { - parseExpectedTokenJSDoc(SyntaxKind.BacktickToken); - } - if (isBracketed) { - skipWhitespace(); - // May have an optional default, e.g. '[foo = 42]' - if (parseOptionalToken(SyntaxKind.EqualsToken)) { - parseExpression(); - } - - parseExpected(SyntaxKind.CloseBracketToken); - } - - return { name, isBracketed }; - } - - function isObjectOrObjectArrayTypeReference(node: TypeNode): boolean { - switch (node.kind) { - case SyntaxKind.ObjectKeyword: - return true; - case SyntaxKind.ArrayType: - return isObjectOrObjectArrayTypeReference((node as ArrayTypeNode).elementType); - default: - return isTypeReferenceNode(node) && isIdentifierNode(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments; - } - } - - function parseParameterOrPropertyTag(start: number, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag { - let typeExpression = tryParseTypeExpression(); - let isNameFirst = !typeExpression; - skipWhitespaceOrAsterisk(); - - const { name, isBracketed } = parseBracketNameInPropertyAndParamTag(); - const indentText = skipWhitespaceOrAsterisk(); - - if (isNameFirst && !lookAhead(parseJSDocLinkPrefix)) { - typeExpression = tryParseTypeExpression(); - } - - const comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); - - const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name, target, indent); - if (nestedTypeLiteral) { - typeExpression = nestedTypeLiteral; - isNameFirst = true; - } - const result = target === PropertyLikeParse.Property - ? factory.createJSDocPropertyTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment) - : factory.createJSDocParameterTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment); - return finishNode(result, start); - } - - function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) { - if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { - const pos = getNodePos(); - let child: JSDocPropertyLikeTag | JSDocTypeTag | JSDocTemplateTag | JSDocThisTag | false; - let children: JSDocPropertyLikeTag[] | undefined; - while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) { - if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) { - children = append(children, child); - } - else if (child.kind === SyntaxKind.JSDocTemplateTag) { - parseErrorAtRange(child.tagName, Diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag); - } - } - if (children) { - const literal = finishNode(factory.createJSDocTypeLiteral(children, typeExpression.type.kind === SyntaxKind.ArrayType), pos); - return finishNode(factory.createJSDocTypeExpression(literal), pos); - } - } - } - - function parseReturnTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocReturnTag { - if (some(tags, isJSDocReturnTag)) { - parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, unescapeLeadingUnderscores(tagName.escapedText)); - } - - const typeExpression = tryParseTypeExpression(); - return finishNode(factory.createJSDocReturnTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); - } - - function parseTypeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocTypeTag { - if (some(tags, isJSDocTypeTag)) { - parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, unescapeLeadingUnderscores(tagName.escapedText)); - } - - const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); - const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), indent, indentText) : undefined; - return finishNode(factory.createJSDocTypeTag(tagName, typeExpression, comments), start); - } - - function parseSeeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocSeeTag { - const isMarkdownOrJSDocLink = token() === SyntaxKind.OpenBracketToken - || lookAhead(() => nextTokenJSDoc() === SyntaxKind.AtToken && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && isJSDocLinkTag(scanner.getTokenValue())); - const nameExpression = isMarkdownOrJSDocLink ? undefined : parseJSDocNameReference(); - const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), indent, indentText) : undefined; - return finishNode(factory.createJSDocSeeTag(tagName, nameExpression, comments), start); - } - - function parseThrowsTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocThrowsTag { - const typeExpression = tryParseTypeExpression(); - const comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); - return finishNode(factory.createJSDocThrowsTag(tagName, typeExpression, comment), start); - } - - function parseAuthorTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocAuthorTag { - const commentStart = getNodePos(); - const textOnly = parseAuthorNameAndEmail(); - let commentEnd = scanner.getTokenFullStart(); - const comments = parseTrailingTagComments(start, commentEnd, indent, indentText); - if (!comments) { - commentEnd = scanner.getTokenFullStart(); - } - const allParts = typeof comments !== "string" - ? createNodeArray(concatenate([finishNode(textOnly, commentStart, commentEnd)], comments) as JSDocComment[], commentStart) // cast away readonly - : textOnly.text + comments; - return finishNode(factory.createJSDocAuthorTag(tagName, allParts), start); - } - - function parseAuthorNameAndEmail(): JSDocText { - const comments: string[] = []; - let inEmail = false; - let token = scanner.getToken(); - while (token !== SyntaxKind.EndOfFileToken && token !== SyntaxKind.NewLineTrivia) { - if (token === SyntaxKind.LessThanToken) { - inEmail = true; - } - else if (token === SyntaxKind.AtToken && !inEmail) { - break; - } - else if (token === SyntaxKind.GreaterThanToken && inEmail) { - comments.push(scanner.getTokenText()); - scanner.resetTokenState(scanner.getTokenEnd()); - break; - } - comments.push(scanner.getTokenText()); - token = nextTokenJSDoc(); - } - - return factory.createJSDocText(comments.join("")); - } - - function parseImplementsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocImplementsTag { - const className = parseExpressionWithTypeArgumentsForAugments(); - return finishNode(factory.createJSDocImplementsTag(tagName, className, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); - } - - function parseAugmentsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocAugmentsTag { - const className = parseExpressionWithTypeArgumentsForAugments(); - return finishNode(factory.createJSDocAugmentsTag(tagName, className, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); - } - - function parseSatisfiesTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocSatisfiesTag { - const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ false); - const comments = margin !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), margin, indentText) : undefined; - return finishNode(factory.createJSDocSatisfiesTag(tagName, typeExpression, comments), start); - } - - function parseImportTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocImportTag { - const afterImportTagPos = scanner.getTokenFullStart(); - - let identifier: Identifier | undefined; - if (isIdentifier()) { - identifier = parseIdentifier(); - } - - const importClause = tryParseImportClause(identifier, afterImportTagPos, SyntaxKind.TypeKeyword, /*skipJsDocLeadingAsterisks*/ true); - const moduleSpecifier = parseModuleSpecifier(); - const attributes = tryParseImportAttributes(); - - const comments = margin !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), margin, indentText) : undefined; - return finishNode(factory.createJSDocImportTag(tagName, importClause, moduleSpecifier, attributes, comments), start); - } - - function parseExpressionWithTypeArgumentsForAugments(): ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression; } { - const usedBrace = parseOptional(SyntaxKind.OpenBraceToken); - const pos = getNodePos(); - const expression = parsePropertyAccessEntityNameExpression(); - scanner.setSkipJsDocLeadingAsterisks(true); - const typeArguments = tryParseTypeArguments(); - scanner.setSkipJsDocLeadingAsterisks(false); - const node = factory.createExpressionWithTypeArguments(expression, typeArguments) as ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression; }; - const res = finishNode(node, pos); - if (usedBrace) { - skipWhitespace(); - parseExpected(SyntaxKind.CloseBraceToken); - } - return res; - } - - function parsePropertyAccessEntityNameExpression() { - const pos = getNodePos(); - let node: Identifier | PropertyAccessEntityNameExpression = parseJSDocIdentifierName(); - while (parseOptional(SyntaxKind.DotToken)) { - const name = parseJSDocIdentifierName(); - node = finishNode(factoryCreatePropertyAccessExpression(node, name), pos) as PropertyAccessEntityNameExpression; - } - return node; - } - - function parseSimpleTag(start: number, createTag: (tagName: Identifier | undefined, comment?: string | NodeArray) => JSDocTag, tagName: Identifier, margin: number, indentText: string): JSDocTag { - return finishNode(createTag(tagName, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); - } - - function parseThisTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocThisTag { - const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); - skipWhitespace(); - return finishNode(factory.createJSDocThisTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); - } - - function parseEnumTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocEnumTag { - const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); - skipWhitespace(); - return finishNode(factory.createJSDocEnumTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); - } - - function parseTypedefTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTypedefTag { - let typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined = tryParseTypeExpression(); - skipWhitespaceOrAsterisk(); - - const fullName = parseJSDocTypeNameWithNamespace(); - skipWhitespace(); - let comment = parseTagComments(indent); - - let end: number | undefined; - if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { - let child: JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false; - let childTypeTag: JSDocTypeTag | undefined; - let jsDocPropertyTags: JSDocPropertyTag[] | undefined; - let hasChildren = false; - while (child = tryParse(() => parseChildPropertyTag(indent))) { - if (child.kind === SyntaxKind.JSDocTemplateTag) { - break; - } - hasChildren = true; - if (child.kind === SyntaxKind.JSDocTypeTag) { - if (childTypeTag) { - const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); - if (lastError) { - addRelatedInfo(lastError, createDetachedDiagnostic(fileName, sourceText, 0, 0, Diagnostics.The_tag_was_first_specified_here)); - } - break; - } - else { - childTypeTag = child; - } - } - else { - jsDocPropertyTags = append(jsDocPropertyTags, child); - } - } - if (hasChildren) { - const isArrayType = typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType; - const jsdocTypeLiteral = factory.createJSDocTypeLiteral(jsDocPropertyTags, isArrayType); - typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? - childTypeTag.typeExpression : - finishNode(jsdocTypeLiteral, start); - end = typeExpression.end; - } - } - - // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace - end = end || comment !== undefined ? - getNodePos() : - (fullName ?? typeExpression ?? tagName).end; - - if (!comment) { - comment = parseTrailingTagComments(start, end, indent, indentText); - } - - const typedefTag = factory.createJSDocTypedefTag(tagName, typeExpression, fullName, comment); - return finishNode(typedefTag, start, end); - } - - function parseJSDocTypeNameWithNamespace(nested?: boolean) { - const start = scanner.getTokenStart(); - if (!tokenIsIdentifierOrKeyword(token())) { - return undefined; - } - const typeNameOrNamespaceName = parseJSDocIdentifierName(); - if (parseOptional(SyntaxKind.DotToken)) { - const body = parseJSDocTypeNameWithNamespace(/*nested*/ true); - const jsDocNamespaceNode = factory.createModuleDeclaration( - /*modifiers*/ undefined, - typeNameOrNamespaceName, - body, - nested ? NodeFlags.NestedNamespace : undefined, - ) as JSDocNamespaceDeclaration; - return finishNode(jsDocNamespaceNode, start); - } - - if (nested) { - (typeNameOrNamespaceName as Mutable).flags |= NodeFlags.IdentifierIsInJSDocNamespace; - } - return typeNameOrNamespaceName; - } - - function parseCallbackTagParameters(indent: number) { - const pos = getNodePos(); - let child: JSDocParameterTag | JSDocTemplateTag | false; - let parameters; - while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag | JSDocTemplateTag)) { - if (child.kind === SyntaxKind.JSDocTemplateTag) { - parseErrorAtRange(child.tagName, Diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag); - break; - } - parameters = append(parameters, child); - } - return createNodeArray(parameters || [], pos); - } - - function parseJSDocSignature(start: number, indent: number): JSDocSignature { - const parameters = parseCallbackTagParameters(indent); - const returnTag = tryParse(() => { - if (parseOptionalJsdoc(SyntaxKind.AtToken)) { - const tag = parseTag(indent); - if (tag && tag.kind === SyntaxKind.JSDocReturnTag) { - return tag as JSDocReturnTag; - } - } - }); - return finishNode(factory.createJSDocSignature(/*typeParameters*/ undefined, parameters, returnTag), start); - } - - function parseCallbackTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocCallbackTag { - const fullName = parseJSDocTypeNameWithNamespace(); - skipWhitespace(); - let comment = parseTagComments(indent); - const typeExpression = parseJSDocSignature(start, indent); - if (!comment) { - comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); - } - const end = comment !== undefined ? getNodePos() : typeExpression.end; - return finishNode(factory.createJSDocCallbackTag(tagName, typeExpression, fullName, comment), start, end); - } - - function parseOverloadTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocOverloadTag { - skipWhitespace(); - let comment = parseTagComments(indent); - const typeExpression = parseJSDocSignature(start, indent); - if (!comment) { - comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); - } - const end = comment !== undefined ? getNodePos() : typeExpression.end; - return finishNode(factory.createJSDocOverloadTag(tagName, typeExpression, comment), start, end); - } - - function escapedTextsEqual(a: EntityName, b: EntityName): boolean { - while (!isIdentifierNode(a) || !isIdentifierNode(b)) { - if (!isIdentifierNode(a) && !isIdentifierNode(b) && a.right.escapedText === b.right.escapedText) { - a = a.left; - b = b.left; - } - else { - return false; - } - } - return a.escapedText === b.escapedText; - } - - function parseChildPropertyTag(indent: number) { - return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false; - } - - function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | JSDocThisTag | false { - let canParseTag = true; - let seenAsterisk = false; - while (true) { - switch (nextTokenJSDoc()) { - case SyntaxKind.AtToken: - if (canParseTag) { - const child = tryParseChildTag(target, indent); - if ( - child && (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) && - name && (isIdentifierNode(child.name) || !escapedTextsEqual(name, child.name.left)) - ) { - return false; - } - return child; - } - seenAsterisk = false; - break; - case SyntaxKind.NewLineTrivia: - canParseTag = true; - seenAsterisk = false; - break; - case SyntaxKind.AsteriskToken: - if (seenAsterisk) { - canParseTag = false; - } - seenAsterisk = true; - break; - case SyntaxKind.Identifier: - canParseTag = false; - break; - case SyntaxKind.EndOfFileToken: - return false; - } - } - } - - function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | JSDocThisTag | false { - Debug.assert(token() === SyntaxKind.AtToken); - const start = scanner.getTokenFullStart(); - nextTokenJSDoc(); - - const tagName = parseJSDocIdentifierName(); - const indentText = skipWhitespaceOrAsterisk(); - let t: PropertyLikeParse; - switch (tagName.escapedText) { - case "type": - return target === PropertyLikeParse.Property && parseTypeTag(start, tagName); - case "prop": - case "property": - t = PropertyLikeParse.Property; - break; - case "arg": - case "argument": - case "param": - t = PropertyLikeParse.Parameter | PropertyLikeParse.CallbackParameter; - break; - case "template": - return parseTemplateTag(start, tagName, indent, indentText); - case "this": - return parseThisTag(start, tagName, indent, indentText); - default: - return false; - } - if (!(target & t)) { - return false; - } - return parseParameterOrPropertyTag(start, tagName, target, indent); - } - - function parseTemplateTagTypeParameter() { - const typeParameterPos = getNodePos(); - const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); - if (isBracketed) { - skipWhitespace(); - } - - const modifiers = parseModifiers(/*allowDecorators*/ false, /*permitConstAsModifier*/ true); - const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); - let defaultType: TypeNode | undefined; - if (isBracketed) { - skipWhitespace(); - parseExpected(SyntaxKind.EqualsToken); - defaultType = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); - parseExpected(SyntaxKind.CloseBracketToken); - } - - if (nodeIsMissing(name)) { - return undefined; - } - return finishNode(factory.createTypeParameterDeclaration(modifiers, name, /*constraint*/ undefined, defaultType), typeParameterPos); - } - - function parseTemplateTagTypeParameters() { - const pos = getNodePos(); - const typeParameters = []; - do { - skipWhitespace(); - const node = parseTemplateTagTypeParameter(); - if (node !== undefined) { - typeParameters.push(node); - } - skipWhitespaceOrAsterisk(); - } - while (parseOptionalJsdoc(SyntaxKind.CommaToken)); - return createNodeArray(typeParameters, pos); - } - - function parseTemplateTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTemplateTag { - // The template tag looks like one of the following: - // @template T,U,V - // @template {Constraint} T - // - // According to the [closure docs](https://github.com/google/closure-compiler/wiki/Generic-Types#multiple-bounded-template-types): - // > Multiple bounded generics cannot be declared on the same line. For the sake of clarity, if multiple templates share the same - // > type bound they must be declared on separate lines. - // - // TODO: Determine whether we should enforce this in the checker. - // TODO: Consider moving the `constraint` to the first type parameter as we could then remove `getEffectiveConstraintOfTypeParameter`. - // TODO: Consider only parsing a single type parameter if there is a constraint. - const constraint = token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; - const typeParameters = parseTemplateTagTypeParameters(); - return finishNode(factory.createJSDocTemplateTag(tagName, constraint, typeParameters, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); - } - - function parseOptionalJsdoc(t: JSDocSyntaxKind): boolean { - if (token() === t) { - nextTokenJSDoc(); - return true; - } - return false; - } - - function parseJSDocEntityName(): EntityName { - let entity: EntityName = parseJSDocIdentifierName(); - if (parseOptional(SyntaxKind.OpenBracketToken)) { - parseExpected(SyntaxKind.CloseBracketToken); - // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. - // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}> - // but it's not worth it to enforce that restriction. - } - while (parseOptional(SyntaxKind.DotToken)) { - const name = parseJSDocIdentifierName(); - if (parseOptional(SyntaxKind.OpenBracketToken)) { - parseExpected(SyntaxKind.CloseBracketToken); - } - entity = createQualifiedName(entity, name); - } - return entity; - } - - function parseJSDocIdentifierName(message?: DiagnosticMessage): Identifier { - if (!tokenIsIdentifierOrKeyword(token())) { - return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || Diagnostics.Identifier_expected); - } - - identifierCount++; - const start = scanner.getTokenStart(); - const end = scanner.getTokenEnd(); - const originalKeywordKind = token(); - const text = internIdentifier(scanner.getTokenValue()); - const result = finishNode(factoryCreateIdentifier(text, originalKeywordKind), start, end); - nextTokenJSDoc(); - return result; - } - } - } -} - -const incrementallyParsedFiles = new WeakSet(); - -function markAsIncrementallyParsed(sourceFile: SourceFile) { - if (incrementallyParsedFiles.has(sourceFile)) { - Debug.fail("Source file has already been incrementally parsed"); - } - incrementallyParsedFiles.add(sourceFile); -} - -const intersectingChangeSet = new WeakSet>(); - -function intersectsIncrementalChange(node: Node | NodeArray): boolean { - return intersectingChangeSet.has(node); -} - -function markAsIntersectingIncrementalChange(node: Node | NodeArray) { - intersectingChangeSet.add(node); -} - -namespace IncrementalParser { - export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile { - aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive); - - checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); - if (textChangeRangeIsUnchanged(textChangeRange)) { - // if the text didn't change, then we can just return our current source file as-is. - return sourceFile; - } - - if (sourceFile.statements.length === 0) { - // If we don't have any statements in the current source file, then there's no real - // way to incrementally parse. So just do a full parse instead. - return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind, sourceFile.setExternalModuleIndicator, sourceFile.jsDocParsingMode); - } - - // Make sure we're not trying to incrementally update a source file more than once. Once - // we do an update the original source file is considered unusable from that point onwards. - // - // This is because we do incremental parsing in-place. i.e. we take nodes from the old - // tree and give them new positions and parents. From that point on, trusting the old - // tree at all is not possible as far too much of it may violate invariants. - markAsIncrementallyParsed(sourceFile); - Parser.fixupParentReferences(sourceFile); - const oldText = sourceFile.text; - const syntaxCursor = createSyntaxCursor(sourceFile); - - // Make the actual change larger so that we know to reparse anything whose lookahead - // might have intersected the change. - const changeRange = extendToAffectedRange(sourceFile, textChangeRange); - checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks); - - // Ensure that extending the affected range only moved the start of the change range - // earlier in the file. - Debug.assert(changeRange.span.start <= textChangeRange.span.start); - Debug.assert(textSpanEnd(changeRange.span) === textSpanEnd(textChangeRange.span)); - Debug.assert(textSpanEnd(textChangeRangeNewSpan(changeRange)) === textSpanEnd(textChangeRangeNewSpan(textChangeRange))); - - // The is the amount the nodes after the edit range need to be adjusted. It can be - // positive (if the edit added characters), negative (if the edit deleted characters) - // or zero (if this was a pure overwrite with nothing added/removed). - const delta = textChangeRangeNewSpan(changeRange).length - changeRange.span.length; - - // If we added or removed characters during the edit, then we need to go and adjust all - // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they - // may move backward (if we deleted chars). - // - // Doing this helps us out in two ways. First, it means that any nodes/tokens we want - // to reuse are already at the appropriate position in the new text. That way when we - // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes - // it very easy to determine if we can reuse a node. If the node's position is at where - // we are in the text, then we can reuse it. Otherwise we can't. If the node's position - // is ahead of us, then we'll need to rescan tokens. If the node's position is behind - // us, then we'll need to skip it or crumble it as appropriate - // - // We will also adjust the positions of nodes that intersect the change range as well. - // By doing this, we ensure that all the positions in the old tree are consistent, not - // just the positions of nodes entirely before/after the change range. By being - // consistent, we can then easily map from positions to nodes in the old tree easily. - // - // Also, mark any syntax elements that intersect the changed span. We know, up front, - // that we cannot reuse these elements. - updateTokenPositionsAndMarkElements(sourceFile, changeRange.span.start, textSpanEnd(changeRange.span), textSpanEnd(textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks); - - // Now that we've set up our internal incremental state just proceed and parse the - // source file in the normal fashion. When possible the parser will retrieve and - // reuse nodes from the old tree. - // - // Note: passing in 'true' for setNodeParents is very important. When incrementally - // parsing, we will be reusing nodes from the old tree, and placing it into new - // parents. If we don't set the parents now, we'll end up with an observably - // inconsistent tree. Setting the parents on the new tree should be very fast. We - // will immediately bail out of walking any subtrees when we can see that their parents - // are already correct. - const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind, sourceFile.setExternalModuleIndicator, sourceFile.jsDocParsingMode); - result.commentDirectives = getNewCommentDirectives( - sourceFile.commentDirectives, - result.commentDirectives, - changeRange.span.start, - textSpanEnd(changeRange.span), - delta, - oldText, - newText, - aggressiveChecks, - ); - result.impliedNodeFormat = sourceFile.impliedNodeFormat; - transferSourceFileChildren(sourceFile, result); - return result; - } - - function getNewCommentDirectives( - oldDirectives: CommentDirective[] | undefined, - newDirectives: CommentDirective[] | undefined, - changeStart: number, - changeRangeOldEnd: number, - delta: number, - oldText: string, - newText: string, - aggressiveChecks: boolean, - ): CommentDirective[] | undefined { - if (!oldDirectives) return newDirectives; - let commentDirectives: CommentDirective[] | undefined; - let addedNewlyScannedDirectives = false; - for (const directive of oldDirectives) { - const { range, type } = directive; - // Range before the change - if (range.end < changeStart) { - commentDirectives = append(commentDirectives, directive); - } - else if (range.pos > changeRangeOldEnd) { - addNewlyScannedDirectives(); - // Node is entirely past the change range. We need to move both its pos and - // end, forward or backward appropriately. - const updatedDirective: CommentDirective = { - range: { pos: range.pos + delta, end: range.end + delta }, - type, - }; - commentDirectives = append(commentDirectives, updatedDirective); - if (aggressiveChecks) { - Debug.assert(oldText.substring(range.pos, range.end) === newText.substring(updatedDirective.range.pos, updatedDirective.range.end)); - } - } - // Ignore ranges that fall in change range - } - addNewlyScannedDirectives(); - return commentDirectives; - - function addNewlyScannedDirectives() { - if (addedNewlyScannedDirectives) return; - addedNewlyScannedDirectives = true; - if (!commentDirectives) { - commentDirectives = newDirectives; - } - else if (newDirectives) { - commentDirectives.push(...newDirectives); - } - } - } - - function moveElementEntirelyPastChangeRange(element: Node, origSourceFile: SourceFile, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void; - function moveElementEntirelyPastChangeRange(element: NodeArray, origSourceFile: SourceFile, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void; - function moveElementEntirelyPastChangeRange(element: Node | NodeArray, origSourceFile: SourceFile, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { - if (isArray) { - visitArray(element as NodeArray); - } - else { - visitNode(element as Node); - } - return; - - function visitNode(node: Node) { - let text = ""; - if (aggressiveChecks && shouldCheckNode(node)) { - text = oldText.substring(node.pos, node.end); - } - - // Ditch any existing LS children we may have created. This way we can avoid - // moving them forward. - unsetNodeChildren(node, origSourceFile); - - setTextRangePosEnd(node, node.pos + delta, node.end + delta); - - if (aggressiveChecks && shouldCheckNode(node)) { - Debug.assert(text === newText.substring(node.pos, node.end)); - } - - forEachChild(node, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray) => void); - if (hasJSDocNodes(node)) { - for (const jsDocComment of node.jsDoc!) { - visitNode(jsDocComment); - } - } - checkNodePositions(node, aggressiveChecks); - } - - function visitArray(array: NodeArray) { - setTextRangePosEnd(array, array.pos + delta, array.end + delta); - - for (const node of array) { - visitNode(node); - } - } - } - - function shouldCheckNode(node: Node) { - switch (node.kind) { - case SyntaxKind.StringLiteral: - case SyntaxKind.NumericLiteral: - case SyntaxKind.Identifier: - return true; - } - - return false; - } - - function adjustIntersectingElement(element: Node | NodeArray, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number) { - Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range"); - Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range"); - Debug.assert(element.pos <= element.end); - - // We have an element that intersects the change range in some way. It may have its - // start, or its end (or both) in the changed range. We want to adjust any part - // that intersects such that the final tree is in a consistent state. i.e. all - // children have spans within the span of their parent, and all siblings are ordered - // properly. - - // We may need to update both the 'pos' and the 'end' of the element. - - // If the 'pos' is before the start of the change, then we don't need to touch it. - // If it isn't, then the 'pos' must be inside the change. How we update it will - // depend if delta is positive or negative. If delta is positive then we have - // something like: - // - // -------------------AAA----------------- - // -------------------BBBCCCCCCC----------------- - // - // In this case, we consider any node that started in the change range to still be - // starting at the same position. - // - // however, if the delta is negative, then we instead have something like this: - // - // -------------------XXXYYYYYYY----------------- - // -------------------ZZZ----------------- - // - // In this case, any element that started in the 'X' range will keep its position. - // However any element that started after that will have their pos adjusted to be - // at the end of the new range. i.e. any node that started in the 'Y' range will - // be adjusted to have their start at the end of the 'Z' range. - // - // The element will keep its position if possible. Or Move backward to the new-end - // if it's in the 'Y' range. - const pos = Math.min(element.pos, changeRangeNewEnd); - - // If the 'end' is after the change range, then we always adjust it by the delta - // amount. However, if the end is in the change range, then how we adjust it - // will depend on if delta is positive or negative. If delta is positive then we - // have something like: - // - // -------------------AAA----------------- - // -------------------BBBCCCCCCC----------------- - // - // In this case, we consider any node that ended inside the change range to keep its - // end position. - // - // however, if the delta is negative, then we instead have something like this: - // - // -------------------XXXYYYYYYY----------------- - // -------------------ZZZ----------------- - // - // In this case, any element that ended in the 'X' range will keep its position. - // However any element that ended after that will have their pos adjusted to be - // at the end of the new range. i.e. any node that ended in the 'Y' range will - // be adjusted to have their end at the end of the 'Z' range. - const end = element.end >= changeRangeOldEnd ? - // Element ends after the change range. Always adjust the end pos. - element.end + delta : - // Element ends in the change range. The element will keep its position if - // possible. Or Move backward to the new-end if it's in the 'Y' range. - Math.min(element.end, changeRangeNewEnd); - - Debug.assert(pos <= end); - if ((element as any).parent) { - const parent = (element as any).parent as Node; - Debug.assertGreaterThanOrEqual(pos, parent.pos); - Debug.assertLessThanOrEqual(end, parent.end); - } - - setTextRangePosEnd(element, pos, end); - } - - function checkNodePositions(node: Node, aggressiveChecks: boolean) { - if (aggressiveChecks) { - let pos = node.pos; - const visitNode = (child: Node) => { - Debug.assert(child.pos >= pos); - pos = child.end; - }; - if (hasJSDocNodes(node)) { - for (const jsDocComment of node.jsDoc!) { - visitNode(jsDocComment); - } - } - forEachChild(node, visitNode); - Debug.assert(pos <= node.end); - } - } - - function updateTokenPositionsAndMarkElements( - sourceFile: SourceFile, - changeStart: number, - changeRangeOldEnd: number, - changeRangeNewEnd: number, - delta: number, - oldText: string, - newText: string, - aggressiveChecks: boolean, - ): void { - visitNode(sourceFile); - return; - - function visitNode(child: Node) { - Debug.assert(child.pos <= child.end); - if (child.pos > changeRangeOldEnd) { - // Node is entirely past the change range. We need to move both its pos and - // end, forward or backward appropriately. - moveElementEntirelyPastChangeRange(child, sourceFile, /*isArray*/ false, delta, oldText, newText, aggressiveChecks); - return; - } - - // Check if the element intersects the change range. If it does, then it is not - // reusable. Also, we'll need to recurse to see what constituent portions we may - // be able to use. - const fullEnd = child.end; - if (fullEnd >= changeStart) { - markAsIntersectingIncrementalChange(child); - unsetNodeChildren(child, sourceFile); - - // Adjust the pos or end (or both) of the intersecting element accordingly. - adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - forEachChild(child, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray) => void); - if (hasJSDocNodes(child)) { - for (const jsDocComment of child.jsDoc!) { - visitNode(jsDocComment); - } - } - checkNodePositions(child, aggressiveChecks); - return; - } - - // Otherwise, the node is entirely before the change range. No need to do anything with it. - Debug.assert(fullEnd < changeStart); - } - - function visitArray(array: NodeArray) { - Debug.assert(array.pos <= array.end); - if (array.pos > changeRangeOldEnd) { - // Array is entirely after the change range. We need to move it, and move any of - // its children. - moveElementEntirelyPastChangeRange(array, sourceFile, /*isArray*/ true, delta, oldText, newText, aggressiveChecks); - return; - } - - // Check if the element intersects the change range. If it does, then it is not - // reusable. Also, we'll need to recurse to see what constituent portions we may - // be able to use. - const fullEnd = array.end; - if (fullEnd >= changeStart) { - markAsIntersectingIncrementalChange(array); - - // Adjust the pos or end (or both) of the intersecting array accordingly. - adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - for (const node of array) { - visitNode(node); - } - return; - } - - // Otherwise, the array is entirely before the change range. No need to do anything with it. - Debug.assert(fullEnd < changeStart); - } - } - - function extendToAffectedRange(sourceFile: SourceFile, changeRange: TextChangeRange): TextChangeRange { - // Consider the following code: - // void foo() { /; } - // - // If the text changes with an insertion of / just before the semicolon then we end up with: - // void foo() { //; } - // - // If we were to just use the changeRange a is, then we would not rescan the { token - // (as it does not intersect the actual original change range). Because an edit may - // change the token touching it, we actually need to look back *at least* one token so - // that the prior token sees that change. - const maxLookahead = 1; - - let start = changeRange.span.start; - - // the first iteration aligns us with the change start. subsequent iteration move us to - // the left by maxLookahead tokens. We only need to do this as long as we're not at the - // start of the tree. - for (let i = 0; start > 0 && i <= maxLookahead; i++) { - const nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start); - Debug.assert(nearestNode.pos <= start); - const position = nearestNode.pos; - - start = Math.max(0, position - 1); - } - - const finalSpan = createTextSpanFromBounds(start, textSpanEnd(changeRange.span)); - const finalLength = changeRange.newLength + (changeRange.span.start - start); - - return createTextChangeRange(finalSpan, finalLength); - } - - function findNearestNodeStartingBeforeOrAtPosition(sourceFile: SourceFile, position: number): Node { - let bestResult: Node = sourceFile; - let lastNodeEntirelyBeforePosition: Node | undefined; - - forEachChild(sourceFile, visit); - - if (lastNodeEntirelyBeforePosition) { - const lastChildOfLastEntireNodeBeforePosition = getLastDescendant(lastNodeEntirelyBeforePosition); - if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) { - bestResult = lastChildOfLastEntireNodeBeforePosition; - } - } - - return bestResult; - - function getLastDescendant(node: Node): Node { - while (true) { - const lastChild = getLastChild(node); - if (lastChild) { - node = lastChild; - } - else { - return node; - } - } - } - - function visit(child: Node) { - if (nodeIsMissing(child)) { - // Missing nodes are effectively invisible to us. We never even consider them - // When trying to find the nearest node before us. - return; - } - - // If the child intersects this position, then this node is currently the nearest - // node that starts before the position. - if (child.pos <= position) { - if (child.pos >= bestResult.pos) { - // This node starts before the position, and is closer to the position than - // the previous best node we found. It is now the new best node. - bestResult = child; - } - - // Now, the node may overlap the position, or it may end entirely before the - // position. If it overlaps with the position, then either it, or one of its - // children must be the nearest node before the position. So we can just - // recurse into this child to see if we can find something better. - if (position < child.end) { - // The nearest node is either this child, or one of the children inside - // of it. We've already marked this child as the best so far. Recurse - // in case one of the children is better. - forEachChild(child, visit); - - // Once we look at the children of this node, then there's no need to - // continue any further. - return true; - } - else { - Debug.assert(child.end <= position); - // The child ends entirely before this position. Say you have the following - // (where $ is the position) - // - // ? $ : <...> <...> - // - // We would want to find the nearest preceding node in "complex expr 2". - // To support that, we keep track of this node, and once we're done searching - // for a best node, we recurse down this node to see if we can find a good - // result in it. - // - // This approach allows us to quickly skip over nodes that are entirely - // before the position, while still allowing us to find any nodes in the - // last one that might be what we want. - lastNodeEntirelyBeforePosition = child; - } - } - else { - Debug.assert(child.pos > position); - // We're now at a node that is entirely past the position we're searching for. - // This node (and all following nodes) could never contribute to the result, - // so just skip them by returning 'true' here. - return true; - } - } - } - - function checkChangeRange(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean) { - const oldText = sourceFile.text; - if (textChangeRange) { - Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); - - if (aggressiveChecks || Debug.shouldAssert(AssertionLevel.VeryAggressive)) { - const oldTextPrefix = oldText.substr(0, textChangeRange.span.start); - const newTextPrefix = newText.substr(0, textChangeRange.span.start); - Debug.assert(oldTextPrefix === newTextPrefix); - - const oldTextSuffix = oldText.substring(textSpanEnd(textChangeRange.span), oldText.length); - const newTextSuffix = newText.substring(textSpanEnd(textChangeRangeNewSpan(textChangeRange)), newText.length); - Debug.assert(oldTextSuffix === newTextSuffix); - } - } - } - - // Allows finding nodes in the source file at a certain position in an efficient manner. - // The implementation takes advantage of the calling pattern it knows the parser will - // make in order to optimize finding nodes as quickly as possible. - export interface SyntaxCursor { - currentNode(position: number): Node; - } - - export function createSyntaxCursor(sourceFile: SourceFile): SyntaxCursor { - let currentArray: NodeArray = sourceFile.statements; - let currentArrayIndex = 0; - - Debug.assert(currentArrayIndex < currentArray.length); - let current = currentArray[currentArrayIndex]; - let lastQueriedPosition = InvalidPosition.Value; - - return { - currentNode(position: number) { - // Only compute the current node if the position is different than the last time - // we were asked. The parser commonly asks for the node at the same position - // twice. Once to know if can read an appropriate list element at a certain point, - // and then to actually read and consume the node. - if (position !== lastQueriedPosition) { - // Much of the time the parser will need the very next node in the array that - // we just returned a node from.So just simply check for that case and move - // forward in the array instead of searching for the node again. - if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) { - currentArrayIndex++; - current = currentArray[currentArrayIndex]; - } - - // If we don't have a node, or the node we have isn't in the right position, - // then try to find a viable node at the position requested. - if (!current || current.pos !== position) { - findHighestListElementThatStartsAtPosition(position); - } - } - - // Cache this query so that we don't do any extra work if the parser calls back - // into us. Note: this is very common as the parser will make pairs of calls like - // 'isListElement -> parseListElement'. If we were unable to find a node when - // called with 'isListElement', we don't want to redo the work when parseListElement - // is called immediately after. - lastQueriedPosition = position; - - // Either we don'd have a node, or we have a node at the position being asked for. - Debug.assert(!current || current.pos === position); - return current; - }, - }; - - // Finds the highest element in the tree we can find that starts at the provided position. - // The element must be a direct child of some node list in the tree. This way after we - // return it, we can easily return its next sibling in the list. - function findHighestListElementThatStartsAtPosition(position: number) { - // Clear out any cached state about the last node we found. - currentArray = undefined!; - currentArrayIndex = InvalidPosition.Value; - current = undefined!; - - // Recurse into the source file to find the highest node at this position. - forEachChild(sourceFile, visitNode, visitArray); - return; - - function visitNode(node: Node) { - if (position >= node.pos && position < node.end) { - // Position was within this node. Keep searching deeper to find the node. - forEachChild(node, visitNode, visitArray); - - // don't proceed any further in the search. - return true; - } - - // position wasn't in this node, have to keep searching. - return false; - } - - function visitArray(array: NodeArray) { - if (position >= array.pos && position < array.end) { - // position was in this array. Search through this array to see if we find a - // viable element. - for (let i = 0; i < array.length; i++) { - const child = array[i]; - if (child) { - if (child.pos === position) { - // Found the right node. We're done. - currentArray = array; - currentArrayIndex = i; - current = child; - return true; - } - else { - if (child.pos < position && position < child.end) { - // Position in somewhere within this child. Search in it and - // stop searching in this array. - forEachChild(child, visitNode, visitArray); - return true; - } - } - } - } - } - - // position wasn't in this array, have to keep searching. - return false; - } - } - } - - const enum InvalidPosition { - Value = -1, - } -} - -/** @internal */ -export function isDeclarationFileName(fileName: string): boolean { - return getDeclarationFileExtension(fileName) !== undefined; -} - -/** @internal */ -export function getDeclarationFileExtension(fileName: string): string | undefined { - const standardExtension = getAnyExtensionFromPath(fileName, supportedDeclarationExtensions, /*ignoreCase*/ false); - if (standardExtension) { - return standardExtension; - } - if (fileExtensionIs(fileName, Extension.Ts)) { - const baseName = getBaseFileName(fileName); - const index = baseName.lastIndexOf(".d."); - if (index >= 0) { - return baseName.substring(index); - } - } - return undefined; -} - -function parseResolutionMode(mode: string | undefined, pos: number, end: number, reportDiagnostic: PragmaDiagnosticReporter): ResolutionMode { - if (!mode) { - return undefined; - } - if (mode === "import") { - return ModuleKind.ESNext; - } - if (mode === "require") { - return ModuleKind.CommonJS; - } - reportDiagnostic(pos, end - pos, Diagnostics.resolution_mode_should_be_either_require_or_import); - return undefined; -} - -/** @internal */ -export function processCommentPragmas(context: PragmaContext, sourceText: string): void { - const pragmas: PragmaPseudoMapEntry[] = []; - - for (const range of getLeadingCommentRanges(sourceText, 0) || emptyArray) { - const comment = sourceText.substring(range.pos, range.end); - extractPragmas(pragmas, range, comment); - } - - context.pragmas = new Map() as PragmaMap; - for (const pragma of pragmas) { - if (context.pragmas.has(pragma.name)) { - const currentValue = context.pragmas.get(pragma.name); - if (currentValue instanceof Array) { - currentValue.push(pragma.args); - } - else { - context.pragmas.set(pragma.name, [currentValue, pragma.args]); - } - continue; - } - context.pragmas.set(pragma.name, pragma.args); - } -} - -/** @internal */ -export type PragmaDiagnosticReporter = (pos: number, length: number, message: DiagnosticMessage) => void; - -/** @internal */ -export function processPragmasIntoFields(context: PragmaContext, reportDiagnostic: PragmaDiagnosticReporter): void { - context.checkJsDirective = undefined; - context.referencedFiles = []; - context.typeReferenceDirectives = []; - context.libReferenceDirectives = []; - context.amdDependencies = []; - context.pragmas!.forEach((entryOrList, key) => { // TODO: GH#18217 - // TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to - // key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :( - switch (key) { - case "reference": { - const referencedFiles = context.referencedFiles; - const typeReferenceDirectives = context.typeReferenceDirectives; - const libReferenceDirectives = context.libReferenceDirectives; - forEach(toArray(entryOrList) as PragmaPseudoMap["reference"][], arg => { - const { types, lib, path, ["resolution-mode"]: res, preserve: _preserve } = arg.arguments; - const preserve = _preserve === "true" ? true : undefined; - if (arg.arguments["no-default-lib"] === "true") { - // This has been removed; parse but ignore it. - } - else if (types) { - const parsed = parseResolutionMode(res, types.pos, types.end, reportDiagnostic); - typeReferenceDirectives.push({ pos: types.pos, end: types.end, fileName: types.value, ...(parsed ? { resolutionMode: parsed } : {}), ...(preserve ? { preserve } : {}) }); - } - else if (lib) { - libReferenceDirectives.push({ pos: lib.pos, end: lib.end, fileName: lib.value, ...(preserve ? { preserve } : {}) }); - } - else if (path) { - referencedFiles.push({ pos: path.pos, end: path.end, fileName: path.value, ...(preserve ? { preserve } : {}) }); - } - else { - reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, Diagnostics.Invalid_reference_directive_syntax); - } - }); - break; - } - case "amd-dependency": { - context.amdDependencies = map( - toArray(entryOrList) as PragmaPseudoMap["amd-dependency"][], - x => ({ name: x.arguments.name, path: x.arguments.path }), - ); - break; - } - case "amd-module": { - if (entryOrList instanceof Array) { - for (const entry of entryOrList) { - if (context.moduleName) { - // TODO: It's probably fine to issue this diagnostic on all instances of the pragma - reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments); - } - context.moduleName = (entry as PragmaPseudoMap["amd-module"]).arguments.name; - } - } - else { - context.moduleName = (entryOrList as PragmaPseudoMap["amd-module"]).arguments.name; - } - break; - } - case "ts-nocheck": - case "ts-check": { - // _last_ of either nocheck or check in a file is the "winner" - forEach(toArray(entryOrList), entry => { - if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) { - context.checkJsDirective = { - enabled: key === "ts-check", - end: entry.range.end, - pos: entry.range.pos, - }; - } - }); - break; - } - case "jsx": - case "jsxfrag": - case "jsximportsource": - case "jsxruntime": - return; // Accessed directly - default: - Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future? - } - }); -} - -const namedArgRegExCache = new Map(); -function getNamedArgRegEx(name: string): RegExp { - if (namedArgRegExCache.has(name)) { - return namedArgRegExCache.get(name)!; - } - const result = new RegExp(`(\\s${name}\\s*=\\s*)(?:(?:'([^']*)')|(?:"([^"]*)"))`, "im"); - namedArgRegExCache.set(name, result); - return result; -} - -const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/m; -const singleLinePragmaRegEx = /^\/\/\/?\s*@([^\s:]+)((?:[^\S\r\n]|:).*)?$/m; -function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) { - const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text); - if (tripleSlash) { - const name = tripleSlash[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks - const pragma = commentPragmas[name] as PragmaDefinition; - if (!pragma || !(pragma.kind! & PragmaKindFlags.TripleSlashXML)) { - return; - } - if (pragma.args) { - const argument: { [index: string]: string | { value: string; pos: number; end: number; }; } = {}; - for (const arg of pragma.args) { - const matcher = getNamedArgRegEx(arg.name); - const matchResult = matcher.exec(text); - if (!matchResult && !arg.optional) { - return; // Missing required argument, don't parse - } - else if (matchResult) { - const value = matchResult[2] || matchResult[3]; - if (arg.captureSpan) { - const startPos = range.pos + matchResult.index + matchResult[1].length + 1; - argument[arg.name] = { - value, - pos: startPos, - end: startPos + value.length, - }; - } - else { - argument[arg.name] = value; - } - } - } - pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry); - } - else { - pragmas.push({ name, args: { arguments: {}, range } } as PragmaPseudoMapEntry); - } - return; - } - - const singleLine = range.kind === SyntaxKind.SingleLineCommentTrivia && singleLinePragmaRegEx.exec(text); - if (singleLine) { - return addPragmaForMatch(pragmas, range, PragmaKindFlags.SingleLine, singleLine); - } - - if (range.kind === SyntaxKind.MultiLineCommentTrivia) { - const multiLinePragmaRegEx = /@(\S+)(\s+(?:\S.*)?)?$/gm; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating) - let multiLineMatch: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax - while (multiLineMatch = multiLinePragmaRegEx.exec(text)) { - addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch); - } - } -} - -function addPragmaForMatch(pragmas: PragmaPseudoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) { - if (!match) return; - const name = match[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks - const pragma = commentPragmas[name] as PragmaDefinition; - if (!pragma || !(pragma.kind! & kind)) { - return; - } - const args = match[2]; // Split on spaces and match up positionally with definition - const argument = getNamedPragmaArguments(pragma, args); - if (argument === "fail") return; // Missing required argument, fail to parse it - pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry); - return; -} - -function getNamedPragmaArguments(pragma: PragmaDefinition, text: string | undefined): { [index: string]: string; } | "fail" { - if (!text) return {}; - if (!pragma.args) return {}; - const args = text.trim().split(/\s+/); - const argMap: { [index: string]: string; } = {}; - for (let i = 0; i < pragma.args.length; i++) { - const argument = pragma.args[i]; - if (!args[i] && !argument.optional) { - return "fail"; - } - if (argument.captureSpan) { - return Debug.fail("Capture spans not yet implemented for non-xml pragmas"); - } - argMap[argument.name] = args[i]; - } - return argMap; -} - -/** @internal */ -export function tagNamesAreEquivalent(lhs: JsxTagNameExpression, rhs: JsxTagNameExpression): boolean { - if (lhs.kind !== rhs.kind) { - return false; - } - - if (lhs.kind === SyntaxKind.Identifier) { - return lhs.escapedText === (rhs as Identifier).escapedText; - } - - if (lhs.kind === SyntaxKind.ThisKeyword) { - return true; - } - - if (lhs.kind === SyntaxKind.JsxNamespacedName) { - return lhs.namespace.escapedText === (rhs as JsxNamespacedName).namespace.escapedText && - lhs.name.escapedText === (rhs as JsxNamespacedName).name.escapedText; - } - - // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only - // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression - // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element - return (lhs as PropertyAccessExpression).name.escapedText === (rhs as PropertyAccessExpression).name.escapedText && - tagNamesAreEquivalent((lhs as PropertyAccessExpression).expression as JsxTagNameExpression, (rhs as PropertyAccessExpression).expression as JsxTagNameExpression); -} +import { + AccessorDeclaration, + addRange, + addRelatedInfo, + append, + ArrayBindingElement, + ArrayBindingPattern, + ArrayLiteralExpression, + ArrayTypeNode, + ArrowFunction, + AsExpression, + AssertionLevel, + AsteriskToken, + attachFileToDiagnostics, + AwaitExpression, + BaseNodeFactory, + BigIntLiteral, + BinaryExpression, + BinaryOperatorToken, + BindingElement, + BindingName, + BindingPattern, + Block, + BooleanLiteral, + BreakOrContinueStatement, + BreakStatement, + CallExpression, + CallSignatureDeclaration, + canHaveJSDoc, + canHaveModifiers, + CaseBlock, + CaseClause, + CaseOrDefaultClause, + CatchClause, + CharacterCodes, + ClassDeclaration, + ClassElement, + ClassExpression, + ClassLikeDeclaration, + ClassStaticBlockDeclaration, + CommaListExpression, + CommentDirective, + commentPragmas, + CommentRange, + ComputedPropertyName, + concatenate, + ConditionalExpression, + ConditionalTypeNode, + ConstructorDeclaration, + ConstructorTypeNode, + ConstructSignatureDeclaration, + containsParseError, + ContinueStatement, + convertToJson, + createDetachedDiagnostic, + createNodeFactory, + createScanner, + createTextChangeRange, + createTextSpanFromBounds, + Debug, + Decorator, + DefaultClause, + DeleteExpression, + Diagnostic, + DiagnosticArguments, + DiagnosticMessage, + Diagnostics, + DiagnosticWithDetachedLocation, + DoStatement, + DotDotDotToken, + ElementAccessExpression, + emptyArray, + emptyMap, + EndOfFileToken, + ensureScriptKind, + EntityName, + EnumDeclaration, + EnumMember, + ExclamationToken, + ExportAssignment, + ExportDeclaration, + ExportSpecifier, + Expression, + ExpressionStatement, + ExpressionWithTypeArguments, + Extension, + ExternalModuleReference, + fileExtensionIs, + findIndex, + firstOrUndefined, + forEach, + ForEachChildNodes, + ForInOrOfStatement, + ForInStatement, + ForOfStatement, + ForStatement, + FunctionDeclaration, + FunctionExpression, + FunctionOrConstructorTypeNode, + FunctionTypeNode, + GetAccessorDeclaration, + getAnyExtensionFromPath, + getBaseFileName, + getBinaryOperatorPrecedence, + getFullWidth, + getJSDocCommentRanges, + getLanguageVariant, + getLastChild, + getLeadingCommentRanges, + getSpellingSuggestion, + getTextOfNodeFromSourceText, + HasJSDoc, + hasJSDocNodes, + HasModifiers, + HeritageClause, + Identifier, + identity, + idText, + IfStatement, + ImportAttribute, + ImportAttributes, + ImportClause, + ImportDeclaration, + ImportEqualsDeclaration, + ImportOrExportSpecifier, + ImportPhaseModifierSyntaxKind, + ImportSpecifier, + ImportTypeAssertionContainer, + ImportTypeNode, + IndexedAccessTypeNode, + IndexSignatureDeclaration, + InferTypeNode, + InterfaceDeclaration, + IntersectionTypeNode, + isArray, + isAssignmentOperator, + isAsyncModifier, + isClassMemberModifier, + isExportAssignment, + isExportDeclaration, + isExportModifier, + isExpressionWithTypeArguments, + isExternalModuleReference, + isFunctionTypeNode, + isIdentifier as isIdentifierNode, + isIdentifierText, + isImportDeclaration, + isImportEqualsDeclaration, + isJSDocFunctionType, + isJSDocNullableType, + isJSDocReturnTag, + isJSDocTypeTag, + isJsxNamespacedName, + isJsxOpeningElement, + isJsxOpeningFragment, + isKeyword, + isKeywordOrPunctuation, + isLeftHandSideExpression, + isLiteralKind, + isMetaProperty, + isModifierKind, + isNonNullExpression, + isPrivateIdentifier, + isSetAccessorDeclaration, + isStringOrNumericLiteralLike, + isTaggedTemplateExpression, + isTemplateLiteralKind, + isTypeReferenceNode, + IterationStatement, + JSDoc, + JSDocAllType, + JSDocAugmentsTag, + JSDocAuthorTag, + JSDocCallbackTag, + JSDocClassTag, + JSDocComment, + JSDocDeprecatedTag, + JSDocEnumTag, + JSDocFunctionType, + JSDocImplementsTag, + JSDocImportTag, + JSDocLink, + JSDocLinkCode, + JSDocLinkPlain, + JSDocMemberName, + JSDocNameReference, + JSDocNamespaceDeclaration, + JSDocNonNullableType, + JSDocNullableType, + JSDocOptionalType, + JSDocOverloadTag, + JSDocOverrideTag, + JSDocParameterTag, + JSDocParsingMode, + JSDocPrivateTag, + JSDocPropertyLikeTag, + JSDocPropertyTag, + JSDocProtectedTag, + JSDocPublicTag, + JSDocReadonlyTag, + JSDocReturnTag, + JSDocSatisfiesTag, + JSDocSeeTag, + JSDocSignature, + JSDocSyntaxKind, + JSDocTag, + JSDocTemplateTag, + JSDocText, + JSDocThisTag, + JSDocThrowsTag, + JSDocTypedefTag, + JSDocTypeExpression, + JSDocTypeLiteral, + JSDocTypeTag, + JSDocUnknownTag, + JSDocUnknownType, + JSDocVariadicType, + JsonMinusNumericLiteral, + JsonObjectExpressionStatement, + JsonSourceFile, + JsxAttribute, + JsxAttributes, + JsxAttributeValue, + JsxChild, + JsxClosingElement, + JsxClosingFragment, + JsxElement, + JsxExpression, + JsxFragment, + JsxNamespacedName, + JsxOpeningElement, + JsxOpeningFragment, + JsxOpeningLikeElement, + JsxSelfClosingElement, + JsxSpreadAttribute, + JsxTagNameExpression, + JsxText, + JsxTokenSyntaxKind, + LabeledStatement, + LanguageVariant, + lastOrUndefined, + LeftHandSideExpression, + LiteralExpression, + LiteralLikeNode, + LiteralTypeNode, + map, + mapDefined, + MappedTypeNode, + MemberExpression, + MetaProperty, + MethodDeclaration, + MethodSignature, + MinusToken, + MissingDeclaration, + Modifier, + ModifierFlags, + ModifierLike, + modifiersToFlags, + ModuleBlock, + ModuleDeclaration, + ModuleExportName, + ModuleKind, + Mutable, + NamedExportBindings, + NamedExports, + NamedImports, + NamedImportsOrExports, + NamedTupleMember, + NamespaceDeclaration, + NamespaceExport, + NamespaceExportDeclaration, + NamespaceImport, + NewExpression, + Node, + NodeArray, + NodeFactory, + NodeFactoryFlags, + NodeFlags, + nodeIsMissing, + nodeIsPresent, + NonNullExpression, + noop, + normalizePath, + NoSubstitutionTemplateLiteral, + NullLiteral, + NumericLiteral, + objectAllocator, + ObjectBindingPattern, + ObjectLiteralElementLike, + ObjectLiteralExpression, + OperatorPrecedence, + OptionalTypeNode, + PackageJsonInfo, + ParameterDeclaration, + ParenthesizedExpression, + ParenthesizedTypeNode, + PartiallyEmittedExpression, + PlusToken, + PostfixUnaryExpression, + PostfixUnaryOperator, + PragmaContext, + PragmaDefinition, + PragmaKindFlags, + PragmaMap, + PragmaPseudoMap, + PragmaPseudoMapEntry, + PrefixUnaryExpression, + PrefixUnaryOperator, + PrimaryExpression, + PrivateIdentifier, + PropertyAccessEntityNameExpression, + PropertyAccessExpression, + PropertyAssignment, + PropertyDeclaration, + PropertyName, + PropertySignature, + PunctuationOrKeywordSyntaxKind, + PunctuationSyntaxKind, + QualifiedName, + QuestionDotToken, + QuestionToken, + ReadonlyKeyword, + ReadonlyPragmaMap, + ResolutionMode, + RestTypeNode, + ReturnStatement, + SatisfiesExpression, + ScriptKind, + ScriptTarget, + SetAccessorDeclaration, + setParent, + setParentRecursive, + setTextRange, + setTextRangePos, + setTextRangePosEnd, + setTextRangePosWidth, + ShorthandPropertyAssignment, + skipTrivia, + some, + SourceFile, + SpreadAssignment, + SpreadElement, + startsWith, + Statement, + StringLiteral, + supportedDeclarationExtensions, + SwitchStatement, + SyntaxKind, + TaggedTemplateExpression, + TemplateExpression, + TemplateHead, + TemplateLiteralToken, + TemplateLiteralTypeNode, + TemplateLiteralTypeSpan, + TemplateMiddle, + TemplateSpan, + TemplateTail, + TextChangeRange, + textChangeRangeIsUnchanged, + textChangeRangeNewSpan, + TextRange, + textSpanEnd, + textToKeywordObj, + ThisExpression, + ThisTypeNode, + ThrowStatement, + toArray, + Token, + TokenFlags, + tokenIsIdentifierOrKeyword, + tokenIsIdentifierOrKeywordOrGreaterThan, + tokenToString, + tracing, + transferSourceFileChildren, + TransformFlags, + TryStatement, + TupleTypeNode, + TypeAliasDeclaration, + TypeAssertion, + TypeElement, + TypeLiteralNode, + TypeNode, + TypeOfExpression, + TypeOperatorNode, + TypeParameterDeclaration, + TypePredicateNode, + TypeQueryNode, + TypeReferenceNode, + UnaryExpression, + unescapeLeadingUnderscores, + UnionOrIntersectionTypeNode, + UnionTypeNode, + unsetNodeChildren, + UpdateExpression, + VariableDeclaration, + VariableDeclarationList, + VariableStatement, + VoidExpression, + WhileStatement, + WithStatement, + YieldExpression, +} from "./_namespaces/ts.js"; +import * as performance from "./_namespaces/ts.performance.js"; + +const enum SignatureFlags { + None = 0, + Yield = 1 << 0, + Await = 1 << 1, + Type = 1 << 2, + IgnoreMissingOpenBrace = 1 << 4, + JSDoc = 1 << 5, +} + +const enum SpeculationKind { + TryParse, + Lookahead, + Reparse, +} + +let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; +let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; +let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Node; +let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => Node; +let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => Node; + +/** + * NOTE: You should not use this, it is only exported to support `createNode` in `~/src/deprecatedCompat/deprecations.ts`. + * + * @internal + * @knipignore + */ +export const parseBaseNodeFactory: BaseNodeFactory = { + createBaseSourceFileNode: kind => new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, -1, -1), + createBaseIdentifierNode: kind => new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, -1, -1), + createBasePrivateIdentifierNode: kind => new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, -1, -1), + createBaseTokenNode: kind => new (TokenConstructor || (TokenConstructor = objectAllocator.getTokenConstructor()))(kind, -1, -1), + createBaseNode: kind => new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, -1, -1), +}; + +/** @internal */ +export const parseNodeFactory: NodeFactory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules, parseBaseNodeFactory); + +function visitNode(cbNode: (node: Node) => T, node: Node | undefined): T | undefined { + return node && cbNode(node); +} + +function visitNodes(cbNode: (node: Node) => T, cbNodes: ((node: NodeArray) => T | undefined) | undefined, nodes: NodeArray | undefined): T | undefined { + if (nodes) { + if (cbNodes) { + return cbNodes(nodes); + } + for (const node of nodes) { + const result = cbNode(node); + if (result) { + return result; + } + } + } +} + +/** @internal */ +export function isJSDocLikeText(text: string, start: number): boolean { + return text.charCodeAt(start + 1) === CharacterCodes.asterisk && + text.charCodeAt(start + 2) === CharacterCodes.asterisk && + text.charCodeAt(start + 3) !== CharacterCodes.slash; +} + +/** @internal */ +export function isFileProbablyExternalModule(sourceFile: SourceFile): Node | undefined { + // Try to use the first top-level import/export when available, then + // fall back to looking for an 'import.meta' somewhere in the tree if necessary. + return forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) || + getImportMetaIfNecessary(sourceFile); +} + +function isAnExternalModuleIndicatorNode(node: Node) { + return canHaveModifiers(node) && hasModifierOfKind(node, SyntaxKind.ExportKeyword) + || isImportEqualsDeclaration(node) && isExternalModuleReference(node.moduleReference) + || isImportDeclaration(node) + || isExportAssignment(node) + || isExportDeclaration(node) ? node : undefined; +} + +function getImportMetaIfNecessary(sourceFile: SourceFile) { + return sourceFile.flags & NodeFlags.PossiblyContainsImportMeta ? + walkTreeForImportMeta(sourceFile) : + undefined; +} + +function walkTreeForImportMeta(node: Node): Node | undefined { + return isImportMeta(node) ? node : forEachChild(node, walkTreeForImportMeta); +} + +/** Do not use hasModifier inside the parser; it relies on parent pointers. Use this instead. */ +function hasModifierOfKind(node: HasModifiers, kind: SyntaxKind) { + return some(node.modifiers, m => m.kind === kind); +} + +function isImportMeta(node: Node): boolean { + return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta"; +} + +type ForEachChildFunction = (node: TNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined) => T | undefined; +type ForEachChildTable = { [TNode in ForEachChildNodes as TNode["kind"]]: ForEachChildFunction; }; +const forEachChildTable: ForEachChildTable = { + [SyntaxKind.QualifiedName]: function forEachChildInQualifiedName(node: QualifiedName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.left) || + visitNode(cbNode, node.right); + }, + [SyntaxKind.TypeParameter]: function forEachChildInTypeParameter(node: TypeParameterDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.constraint) || + visitNode(cbNode, node.default) || + visitNode(cbNode, node.expression); + }, + [SyntaxKind.ShorthandPropertyAssignment]: function forEachChildInShorthandPropertyAssignment(node: ShorthandPropertyAssignment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.exclamationToken) || + visitNode(cbNode, node.equalsToken) || + visitNode(cbNode, node.objectAssignmentInitializer); + }, + [SyntaxKind.SpreadAssignment]: function forEachChildInSpreadAssignment(node: SpreadAssignment, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.Parameter]: function forEachChildInParameter(node: ParameterDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.dotDotDotToken) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.PropertyDeclaration]: function forEachChildInPropertyDeclaration(node: PropertyDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.exclamationToken) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.PropertySignature]: function forEachChildInPropertySignature(node: PropertySignature, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.PropertyAssignment]: function forEachChildInPropertyAssignment(node: PropertyAssignment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.exclamationToken) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.VariableDeclaration]: function forEachChildInVariableDeclaration(node: VariableDeclaration, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.exclamationToken) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.BindingElement]: function forEachChildInBindingElement(node: BindingElement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.dotDotDotToken) || + visitNode(cbNode, node.propertyName) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.IndexSignature]: function forEachChildInIndexSignature(node: IndexSignatureDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.ConstructorType]: function forEachChildInConstructorType(node: ConstructorTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.FunctionType]: function forEachChildInFunctionType(node: FunctionTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.CallSignature]: forEachChildInCallOrConstructSignature, + [SyntaxKind.ConstructSignature]: forEachChildInCallOrConstructSignature, + [SyntaxKind.MethodDeclaration]: function forEachChildInMethodDeclaration(node: MethodDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.asteriskToken) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.exclamationToken) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.MethodSignature]: function forEachChildInMethodSignature(node: MethodSignature, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.Constructor]: function forEachChildInConstructor(node: ConstructorDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.GetAccessor]: function forEachChildInGetAccessor(node: GetAccessorDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.SetAccessor]: function forEachChildInSetAccessor(node: SetAccessorDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.FunctionDeclaration]: function forEachChildInFunctionDeclaration(node: FunctionDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.asteriskToken) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.FunctionExpression]: function forEachChildInFunctionExpression(node: FunctionExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.asteriskToken) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.ArrowFunction]: function forEachChildInArrowFunction(node: ArrowFunction, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type) || + visitNode(cbNode, node.equalsGreaterThanToken) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.ClassStaticBlockDeclaration]: function forEachChildInClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.TypeReference]: function forEachChildInTypeReference(node: TypeReferenceNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.typeName) || + visitNodes(cbNode, cbNodes, node.typeArguments); + }, + [SyntaxKind.TypePredicate]: function forEachChildInTypePredicate(node: TypePredicateNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.assertsModifier) || + visitNode(cbNode, node.parameterName) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.TypeQuery]: function forEachChildInTypeQuery(node: TypeQueryNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.exprName) || + visitNodes(cbNode, cbNodes, node.typeArguments); + }, + [SyntaxKind.TypeLiteral]: function forEachChildInTypeLiteral(node: TypeLiteralNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.members); + }, + [SyntaxKind.ArrayType]: function forEachChildInArrayType(node: ArrayTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.elementType); + }, + [SyntaxKind.TupleType]: function forEachChildInTupleType(node: TupleTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.elements); + }, + [SyntaxKind.UnionType]: forEachChildInUnionOrIntersectionType, + [SyntaxKind.IntersectionType]: forEachChildInUnionOrIntersectionType, + [SyntaxKind.ConditionalType]: function forEachChildInConditionalType(node: ConditionalTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.checkType) || + visitNode(cbNode, node.extendsType) || + visitNode(cbNode, node.trueType) || + visitNode(cbNode, node.falseType); + }, + [SyntaxKind.InferType]: function forEachChildInInferType(node: InferTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.typeParameter); + }, + [SyntaxKind.ImportType]: function forEachChildInImportType(node: ImportTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.argument) || + visitNode(cbNode, node.attributes) || + visitNode(cbNode, node.qualifier) || + visitNodes(cbNode, cbNodes, node.typeArguments); + }, + [SyntaxKind.ImportTypeAssertionContainer]: function forEachChildInImportTypeAssertionContainer(node: ImportTypeAssertionContainer, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.assertClause); + }, + [SyntaxKind.ParenthesizedType]: forEachChildInParenthesizedTypeOrTypeOperator, + [SyntaxKind.TypeOperator]: forEachChildInParenthesizedTypeOrTypeOperator, + [SyntaxKind.IndexedAccessType]: function forEachChildInIndexedAccessType(node: IndexedAccessTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.objectType) || + visitNode(cbNode, node.indexType); + }, + [SyntaxKind.MappedType]: function forEachChildInMappedType(node: MappedTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.readonlyToken) || + visitNode(cbNode, node.typeParameter) || + visitNode(cbNode, node.nameType) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.type) || + visitNodes(cbNode, cbNodes, node.members); + }, + [SyntaxKind.LiteralType]: function forEachChildInLiteralType(node: LiteralTypeNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.literal); + }, + [SyntaxKind.NamedTupleMember]: function forEachChildInNamedTupleMember(node: NamedTupleMember, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.dotDotDotToken) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.ObjectBindingPattern]: forEachChildInObjectOrArrayBindingPattern, + [SyntaxKind.ArrayBindingPattern]: forEachChildInObjectOrArrayBindingPattern, + [SyntaxKind.ArrayLiteralExpression]: function forEachChildInArrayLiteralExpression(node: ArrayLiteralExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.elements); + }, + [SyntaxKind.ObjectLiteralExpression]: function forEachChildInObjectLiteralExpression(node: ObjectLiteralExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.properties); + }, + [SyntaxKind.PropertyAccessExpression]: function forEachChildInPropertyAccessExpression(node: PropertyAccessExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.questionDotToken) || + visitNode(cbNode, node.name); + }, + [SyntaxKind.ElementAccessExpression]: function forEachChildInElementAccessExpression(node: ElementAccessExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.questionDotToken) || + visitNode(cbNode, node.argumentExpression); + }, + [SyntaxKind.CallExpression]: forEachChildInCallOrNewExpression, + [SyntaxKind.NewExpression]: forEachChildInCallOrNewExpression, + [SyntaxKind.TaggedTemplateExpression]: function forEachChildInTaggedTemplateExpression(node: TaggedTemplateExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tag) || + visitNode(cbNode, node.questionDotToken) || + visitNodes(cbNode, cbNodes, node.typeArguments) || + visitNode(cbNode, node.template); + }, + [SyntaxKind.TypeAssertionExpression]: function forEachChildInTypeAssertionExpression(node: TypeAssertion, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.type) || + visitNode(cbNode, node.expression); + }, + [SyntaxKind.ParenthesizedExpression]: function forEachChildInParenthesizedExpression(node: ParenthesizedExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.DeleteExpression]: function forEachChildInDeleteExpression(node: DeleteExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.TypeOfExpression]: function forEachChildInTypeOfExpression(node: TypeOfExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.VoidExpression]: function forEachChildInVoidExpression(node: VoidExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.PrefixUnaryExpression]: function forEachChildInPrefixUnaryExpression(node: PrefixUnaryExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.operand); + }, + [SyntaxKind.YieldExpression]: function forEachChildInYieldExpression(node: YieldExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.asteriskToken) || + visitNode(cbNode, node.expression); + }, + [SyntaxKind.AwaitExpression]: function forEachChildInAwaitExpression(node: AwaitExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.PostfixUnaryExpression]: function forEachChildInPostfixUnaryExpression(node: PostfixUnaryExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.operand); + }, + [SyntaxKind.BinaryExpression]: function forEachChildInBinaryExpression(node: BinaryExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.left) || + visitNode(cbNode, node.operatorToken) || + visitNode(cbNode, node.right); + }, + [SyntaxKind.AsExpression]: function forEachChildInAsExpression(node: AsExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.NonNullExpression]: function forEachChildInNonNullExpression(node: NonNullExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.SatisfiesExpression]: function forEachChildInSatisfiesExpression(node: SatisfiesExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || visitNode(cbNode, node.type); + }, + [SyntaxKind.MetaProperty]: function forEachChildInMetaProperty(node: MetaProperty, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name); + }, + [SyntaxKind.ConditionalExpression]: function forEachChildInConditionalExpression(node: ConditionalExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.condition) || + visitNode(cbNode, node.questionToken) || + visitNode(cbNode, node.whenTrue) || + visitNode(cbNode, node.colonToken) || + visitNode(cbNode, node.whenFalse); + }, + [SyntaxKind.SpreadElement]: function forEachChildInSpreadElement(node: SpreadElement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.Block]: forEachChildInBlock, + [SyntaxKind.ModuleBlock]: forEachChildInBlock, + [SyntaxKind.SourceFile]: function forEachChildInSourceFile(node: SourceFile, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.statements) || + visitNode(cbNode, node.endOfFileToken); + }, + [SyntaxKind.VariableStatement]: function forEachChildInVariableStatement(node: VariableStatement, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.declarationList); + }, + [SyntaxKind.VariableDeclarationList]: function forEachChildInVariableDeclarationList(node: VariableDeclarationList, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.declarations); + }, + [SyntaxKind.ExpressionStatement]: function forEachChildInExpressionStatement(node: ExpressionStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.IfStatement]: function forEachChildInIfStatement(node: IfStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.thenStatement) || + visitNode(cbNode, node.elseStatement); + }, + [SyntaxKind.DoStatement]: function forEachChildInDoStatement(node: DoStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.statement) || + visitNode(cbNode, node.expression); + }, + [SyntaxKind.WhileStatement]: function forEachChildInWhileStatement(node: WhileStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.statement); + }, + [SyntaxKind.ForStatement]: function forEachChildInForStatement(node: ForStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.initializer) || + visitNode(cbNode, node.condition) || + visitNode(cbNode, node.incrementor) || + visitNode(cbNode, node.statement); + }, + [SyntaxKind.ForInStatement]: function forEachChildInForInStatement(node: ForInStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.initializer) || + visitNode(cbNode, node.expression) || + visitNode(cbNode, node.statement); + }, + [SyntaxKind.ForOfStatement]: function forEachChildInForOfStatement(node: ForOfStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.awaitModifier) || + visitNode(cbNode, node.initializer) || + visitNode(cbNode, node.expression) || + visitNode(cbNode, node.statement); + }, + [SyntaxKind.ContinueStatement]: forEachChildInContinueOrBreakStatement, + [SyntaxKind.BreakStatement]: forEachChildInContinueOrBreakStatement, + [SyntaxKind.ReturnStatement]: function forEachChildInReturnStatement(node: ReturnStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.WithStatement]: function forEachChildInWithStatement(node: WithStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.statement); + }, + [SyntaxKind.SwitchStatement]: function forEachChildInSwitchStatement(node: SwitchStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.caseBlock); + }, + [SyntaxKind.CaseBlock]: function forEachChildInCaseBlock(node: CaseBlock, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.clauses); + }, + [SyntaxKind.CaseClause]: function forEachChildInCaseClause(node: CaseClause, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNodes(cbNode, cbNodes, node.statements); + }, + [SyntaxKind.DefaultClause]: function forEachChildInDefaultClause(node: DefaultClause, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.statements); + }, + [SyntaxKind.LabeledStatement]: function forEachChildInLabeledStatement(node: LabeledStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.label) || + visitNode(cbNode, node.statement); + }, + [SyntaxKind.ThrowStatement]: function forEachChildInThrowStatement(node: ThrowStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.TryStatement]: function forEachChildInTryStatement(node: TryStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tryBlock) || + visitNode(cbNode, node.catchClause) || + visitNode(cbNode, node.finallyBlock); + }, + [SyntaxKind.CatchClause]: function forEachChildInCatchClause(node: CatchClause, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.variableDeclaration) || + visitNode(cbNode, node.block); + }, + [SyntaxKind.Decorator]: function forEachChildInDecorator(node: Decorator, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.ClassDeclaration]: forEachChildInClassDeclarationOrExpression, + [SyntaxKind.ClassExpression]: forEachChildInClassDeclarationOrExpression, + [SyntaxKind.InterfaceDeclaration]: function forEachChildInInterfaceDeclaration(node: InterfaceDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.heritageClauses) || + visitNodes(cbNode, cbNodes, node.members); + }, + [SyntaxKind.TypeAliasDeclaration]: function forEachChildInTypeAliasDeclaration(node: TypeAliasDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.EnumDeclaration]: function forEachChildInEnumDeclaration(node: EnumDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.members); + }, + [SyntaxKind.EnumMember]: function forEachChildInEnumMember(node: EnumMember, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.ModuleDeclaration]: function forEachChildInModuleDeclaration(node: ModuleDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.body); + }, + [SyntaxKind.ImportEqualsDeclaration]: function forEachChildInImportEqualsDeclaration(node: ImportEqualsDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNode(cbNode, node.moduleReference); + }, + [SyntaxKind.ImportDeclaration]: function forEachChildInImportDeclaration(node: ImportDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.importClause) || + visitNode(cbNode, node.moduleSpecifier) || + visitNode(cbNode, node.attributes); + }, + [SyntaxKind.ImportClause]: function forEachChildInImportClause(node: ImportClause, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.namedBindings); + }, + [SyntaxKind.ImportAttributes]: function forEachChildInImportAttributes(node: ImportAttributes, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.elements); + }, + [SyntaxKind.ImportAttribute]: function forEachChildInImportAttribute(node: ImportAttribute, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.value); + }, + [SyntaxKind.NamespaceExportDeclaration]: function forEachChildInNamespaceExportDeclaration(node: NamespaceExportDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name); + }, + [SyntaxKind.NamespaceImport]: function forEachChildInNamespaceImport(node: NamespaceImport, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name); + }, + [SyntaxKind.NamespaceExport]: function forEachChildInNamespaceExport(node: NamespaceExport, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name); + }, + [SyntaxKind.NamedImports]: forEachChildInNamedImportsOrExports, + [SyntaxKind.NamedExports]: forEachChildInNamedImportsOrExports, + [SyntaxKind.ExportDeclaration]: function forEachChildInExportDeclaration(node: ExportDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.exportClause) || + visitNode(cbNode, node.moduleSpecifier) || + visitNode(cbNode, node.attributes); + }, + [SyntaxKind.ImportSpecifier]: forEachChildInImportOrExportSpecifier, + [SyntaxKind.ExportSpecifier]: forEachChildInImportOrExportSpecifier, + [SyntaxKind.ExportAssignment]: function forEachChildInExportAssignment(node: ExportAssignment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.expression); + }, + [SyntaxKind.TemplateExpression]: function forEachChildInTemplateExpression(node: TemplateExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.head) || + visitNodes(cbNode, cbNodes, node.templateSpans); + }, + [SyntaxKind.TemplateSpan]: function forEachChildInTemplateSpan(node: TemplateSpan, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNode(cbNode, node.literal); + }, + [SyntaxKind.TemplateLiteralType]: function forEachChildInTemplateLiteralType(node: TemplateLiteralTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.head) || + visitNodes(cbNode, cbNodes, node.templateSpans); + }, + [SyntaxKind.TemplateLiteralTypeSpan]: function forEachChildInTemplateLiteralTypeSpan(node: TemplateLiteralTypeSpan, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.type) || + visitNode(cbNode, node.literal); + }, + [SyntaxKind.ComputedPropertyName]: function forEachChildInComputedPropertyName(node: ComputedPropertyName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.HeritageClause]: function forEachChildInHeritageClause(node: HeritageClause, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.types); + }, + [SyntaxKind.ExpressionWithTypeArguments]: function forEachChildInExpressionWithTypeArguments(node: ExpressionWithTypeArguments, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + visitNodes(cbNode, cbNodes, node.typeArguments); + }, + [SyntaxKind.ExternalModuleReference]: function forEachChildInExternalModuleReference(node: ExternalModuleReference, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.MissingDeclaration]: function forEachChildInMissingDeclaration(node: MissingDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers); + }, + [SyntaxKind.CommaListExpression]: function forEachChildInCommaListExpression(node: CommaListExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.elements); + }, + [SyntaxKind.JsxElement]: function forEachChildInJsxElement(node: JsxElement, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.openingElement) || + visitNodes(cbNode, cbNodes, node.children) || + visitNode(cbNode, node.closingElement); + }, + [SyntaxKind.JsxFragment]: function forEachChildInJsxFragment(node: JsxFragment, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.openingFragment) || + visitNodes(cbNode, cbNodes, node.children) || + visitNode(cbNode, node.closingFragment); + }, + [SyntaxKind.JsxSelfClosingElement]: forEachChildInJsxOpeningOrSelfClosingElement, + [SyntaxKind.JsxOpeningElement]: forEachChildInJsxOpeningOrSelfClosingElement, + [SyntaxKind.JsxAttributes]: function forEachChildInJsxAttributes(node: JsxAttributes, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.properties); + }, + [SyntaxKind.JsxAttribute]: function forEachChildInJsxAttribute(node: JsxAttribute, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name) || + visitNode(cbNode, node.initializer); + }, + [SyntaxKind.JsxSpreadAttribute]: function forEachChildInJsxSpreadAttribute(node: JsxSpreadAttribute, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); + }, + [SyntaxKind.JsxExpression]: function forEachChildInJsxExpression(node: JsxExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.dotDotDotToken) || + visitNode(cbNode, node.expression); + }, + [SyntaxKind.JsxClosingElement]: function forEachChildInJsxClosingElement(node: JsxClosingElement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName); + }, + [SyntaxKind.JsxNamespacedName]: function forEachChildInJsxNamespacedName(node: JsxNamespacedName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.namespace) || + visitNode(cbNode, node.name); + }, + [SyntaxKind.OptionalType]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.RestType]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.JSDocTypeExpression]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.JSDocNonNullableType]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.JSDocNullableType]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.JSDocOptionalType]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.JSDocVariadicType]: forEachChildInOptionalRestOrJSDocParameterModifier, + [SyntaxKind.JSDocFunctionType]: function forEachChildInJSDocFunctionType(node: JSDocFunctionType, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.JSDoc]: function forEachChildInJSDoc(node: JSDoc, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)) + || visitNodes(cbNode, cbNodes, node.tags); + }, + [SyntaxKind.JSDocSeeTag]: function forEachChildInJSDocSeeTag(node: JSDocSeeTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNode(cbNode, node.name) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); + }, + [SyntaxKind.JSDocNameReference]: function forEachChildInJSDocNameReference(node: JSDocNameReference, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name); + }, + [SyntaxKind.JSDocMemberName]: function forEachChildInJSDocMemberName(node: JSDocMemberName, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.left) || + visitNode(cbNode, node.right); + }, + [SyntaxKind.JSDocParameterTag]: forEachChildInJSDocParameterOrPropertyTag, + [SyntaxKind.JSDocPropertyTag]: forEachChildInJSDocParameterOrPropertyTag, + [SyntaxKind.JSDocAuthorTag]: function forEachChildInJSDocAuthorTag(node: JSDocAuthorTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); + }, + [SyntaxKind.JSDocImplementsTag]: function forEachChildInJSDocImplementsTag(node: JSDocImplementsTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNode(cbNode, node.class) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); + }, + [SyntaxKind.JSDocAugmentsTag]: function forEachChildInJSDocAugmentsTag(node: JSDocAugmentsTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNode(cbNode, node.class) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); + }, + [SyntaxKind.JSDocTemplateTag]: function forEachChildInJSDocTemplateTag(node: JSDocTemplateTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNode(cbNode, node.constraint) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); + }, + [SyntaxKind.JSDocTypedefTag]: function forEachChildInJSDocTypedefTag(node: JSDocTypedefTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + (node.typeExpression && + node.typeExpression.kind === SyntaxKind.JSDocTypeExpression + ? visitNode(cbNode, node.typeExpression) || + visitNode(cbNode, node.fullName) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)) + : visitNode(cbNode, node.fullName) || + visitNode(cbNode, node.typeExpression) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment))); + }, + [SyntaxKind.JSDocCallbackTag]: function forEachChildInJSDocCallbackTag(node: JSDocCallbackTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNode(cbNode, node.fullName) || + visitNode(cbNode, node.typeExpression) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); + }, + [SyntaxKind.JSDocReturnTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocTypeTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocThisTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocEnumTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocSatisfiesTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocThrowsTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocOverloadTag]: forEachChildInJSDocTypeLikeTag, + [SyntaxKind.JSDocSignature]: function forEachChildInJSDocSignature(node: JSDocSignature, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return forEach(node.typeParameters, cbNode) || + forEach(node.parameters, cbNode) || + visitNode(cbNode, node.type); + }, + [SyntaxKind.JSDocLink]: forEachChildInJSDocLinkCodeOrPlain, + [SyntaxKind.JSDocLinkCode]: forEachChildInJSDocLinkCodeOrPlain, + [SyntaxKind.JSDocLinkPlain]: forEachChildInJSDocLinkCodeOrPlain, + [SyntaxKind.JSDocTypeLiteral]: function forEachChildInJSDocTypeLiteral(node: JSDocTypeLiteral, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return forEach(node.jsDocPropertyTags, cbNode); + }, + [SyntaxKind.JSDocTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocClassTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocPublicTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocPrivateTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocProtectedTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocReadonlyTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocDeprecatedTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocOverrideTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocImportTag]: forEachChildInJSDocImportTag, + [SyntaxKind.PartiallyEmittedExpression]: forEachChildInPartiallyEmittedExpression, +}; + +// shared + +function forEachChildInCallOrConstructSignature(node: CallSignatureDeclaration | ConstructSignatureDeclaration, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.parameters) || + visitNode(cbNode, node.type); +} + +function forEachChildInUnionOrIntersectionType(node: UnionTypeNode | IntersectionTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.types); +} + +function forEachChildInParenthesizedTypeOrTypeOperator(node: ParenthesizedTypeNode | TypeOperatorNode, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.type); +} + +function forEachChildInObjectOrArrayBindingPattern(node: BindingPattern, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.elements); +} + +function forEachChildInCallOrNewExpression(node: CallExpression | NewExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression) || + // TODO: should we separate these branches out? + visitNode(cbNode, (node as CallExpression).questionDotToken) || + visitNodes(cbNode, cbNodes, node.typeArguments) || + visitNodes(cbNode, cbNodes, node.arguments); +} + +function forEachChildInBlock(node: Block | ModuleBlock, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.statements); +} + +function forEachChildInContinueOrBreakStatement(node: ContinueStatement | BreakStatement, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.label); +} + +function forEachChildInClassDeclarationOrExpression(node: ClassDeclaration | ClassExpression, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.modifiers) || + visitNode(cbNode, node.name) || + visitNodes(cbNode, cbNodes, node.typeParameters) || + visitNodes(cbNode, cbNodes, node.heritageClauses) || + visitNodes(cbNode, cbNodes, node.members); +} + +function forEachChildInNamedImportsOrExports(node: NamedImports | NamedExports, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNodes(cbNode, cbNodes, node.elements); +} + +function forEachChildInImportOrExportSpecifier(node: ImportSpecifier | ExportSpecifier, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.propertyName) || + visitNode(cbNode, node.name); +} + +function forEachChildInJsxOpeningOrSelfClosingElement(node: JsxOpeningLikeElement, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNodes(cbNode, cbNodes, node.typeArguments) || + visitNode(cbNode, node.attributes); +} + +function forEachChildInOptionalRestOrJSDocParameterModifier(node: OptionalTypeNode | RestTypeNode | JSDocTypeExpression | JSDocNullableType | JSDocNonNullableType | JSDocOptionalType | JSDocVariadicType, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.type); +} + +function forEachChildInJSDocParameterOrPropertyTag(node: JSDocParameterTag | JSDocPropertyTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + (node.isNameFirst + ? visitNode(cbNode, node.name) || visitNode(cbNode, node.typeExpression) + : visitNode(cbNode, node.typeExpression) || visitNode(cbNode, node.name)) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); +} + +function forEachChildInJSDocTypeLikeTag(node: JSDocReturnTag | JSDocTypeTag | JSDocThisTag | JSDocEnumTag | JSDocThrowsTag | JSDocOverloadTag | JSDocSatisfiesTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) || + visitNode(cbNode, node.typeExpression) || + (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); +} + +function forEachChildInJSDocLinkCodeOrPlain(node: JSDocLink | JSDocLinkCode | JSDocLinkPlain, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.name); +} + +function forEachChildInJSDocTag(node: JSDocUnknownTag | JSDocClassTag | JSDocPublicTag | JSDocPrivateTag | JSDocProtectedTag | JSDocReadonlyTag | JSDocDeprecatedTag | JSDocOverrideTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) + || (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); +} + +function forEachChildInJSDocImportTag(node: JSDocImportTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.tagName) + || visitNode(cbNode, node.importClause) + || visitNode(cbNode, node.moduleSpecifier) + || visitNode(cbNode, node.attributes) + || (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); +} + +function forEachChildInPartiallyEmittedExpression(node: PartiallyEmittedExpression, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + return visitNode(cbNode, node.expression); +} + +/** + * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes + * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, + * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns + * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. + * + * @param node a given node to visit its children + * @param cbNode a callback to be invoked for all child nodes + * @param cbNodes a callback to be invoked for embedded array + * + * @remarks `forEachChild` must visit the children of a node in the order + * that they appear in the source code. The language service depends on this property to locate nodes by position. + */ +export function forEachChild(node: Node, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + if (node === undefined || node.kind <= SyntaxKind.LastToken) { + return; + } + const fn = (forEachChildTable as Record>)[node.kind]; + return fn === undefined ? undefined : fn(node, cbNode, cbNodes); +} + +/** + * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes + * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; additionally, + * unlike `forEachChild`, embedded arrays are flattened and the 'cbNode' callback is invoked for each element. + * If a callback returns a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. + * + * @param node a given node to visit its children + * @param cbNode a callback to be invoked for all child nodes + * @param cbNodes a callback to be invoked for embedded array + * + * @remarks Unlike `forEachChild`, `forEachChildRecursively` handles recursively invoking the traversal on each child node found, + * and while doing so, handles traversing the structure without relying on the callstack to encode the tree structure. + * + * @internal + */ +export function forEachChildRecursively(rootNode: Node, cbNode: (node: Node, parent: Node) => T | "skip" | undefined, cbNodes?: (nodes: NodeArray, parent: Node) => T | "skip" | undefined): T | undefined { + const queue: (Node | NodeArray)[] = gatherPossibleChildren(rootNode); + const parents: Node[] = []; // tracks parent references for elements in queue + while (parents.length < queue.length) { + parents.push(rootNode); + } + while (queue.length !== 0) { + const current = queue.pop()!; + const parent = parents.pop()!; + if (isArray(current)) { + if (cbNodes) { + const res = cbNodes(current, parent); + if (res) { + if (res === "skip") continue; + return res; + } + } + for (let i = current.length - 1; i >= 0; --i) { + queue.push(current[i]); + parents.push(parent); + } + } + else { + const res = cbNode(current, parent); + if (res) { + if (res === "skip") continue; + return res; + } + if (current.kind >= SyntaxKind.FirstNode) { + // add children in reverse order to the queue, so popping gives the first child + for (const child of gatherPossibleChildren(current)) { + queue.push(child); + parents.push(current); + } + } + } + } +} + +function gatherPossibleChildren(node: Node) { + const children: (Node | NodeArray)[] = []; + forEachChild(node, addWorkItem, addWorkItem); // By using a stack above and `unshift` here, we emulate a depth-first preorder traversal + return children; + + function addWorkItem(n: Node | NodeArray) { + children.unshift(n); + } +} + +export interface CreateSourceFileOptions { + languageVersion: ScriptTarget; + /** + * Controls the format the file is detected as - this can be derived from only the path + * and files on disk, but needs to be done with a module resolution cache in scope to be performant. + * This is usually `undefined` for compilations that do not have `moduleResolution` values of `node16` or `nodenext`. + */ + impliedNodeFormat?: ResolutionMode; + /** + * Controls how module-y-ness is set for the given file. Usually the result of calling + * `getSetExternalModuleIndicator` on a valid `CompilerOptions` object. If not present, the default + * check specified by `isFileProbablyExternalModule` will be used to set the field. + */ + setExternalModuleIndicator?: (file: SourceFile) => void; + /** @internal */ packageJsonLocations?: readonly string[]; + /** @internal */ packageJsonScope?: PackageJsonInfo; + jsDocParsingMode?: JSDocParsingMode; +} + +function setExternalModuleIndicator(sourceFile: SourceFile) { + sourceFile.externalModuleIndicator = isFileProbablyExternalModule(sourceFile); +} + +export function createSourceFile(fileName: string, sourceText: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, setParentNodes = false, scriptKind?: ScriptKind): SourceFile { + tracing?.push(tracing.Phase.Parse, "createSourceFile", { path: fileName }, /*separateBeginAndEnd*/ true); + performance.mark("beforeParse"); + let result: SourceFile; + + const { + languageVersion, + setExternalModuleIndicator: overrideSetExternalModuleIndicator, + impliedNodeFormat: format, + jsDocParsingMode, + } = typeof languageVersionOrOptions === "object" ? languageVersionOrOptions : ({ languageVersion: languageVersionOrOptions } as CreateSourceFileOptions); + if (languageVersion === ScriptTarget.JSON) { + result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, ScriptKind.JSON, noop, jsDocParsingMode); + } + else { + const setIndicator = format === undefined ? overrideSetExternalModuleIndicator : (file: SourceFile) => { + file.impliedNodeFormat = format; + return (overrideSetExternalModuleIndicator || setExternalModuleIndicator)(file); + }; + result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind, setIndicator, jsDocParsingMode); + } + + performance.mark("afterParse"); + performance.measure("Parse", "beforeParse", "afterParse"); + tracing?.pop(); + return result; +} + +export function parseIsolatedEntityName(text: string, languageVersion: ScriptTarget): EntityName | undefined { + return Parser.parseIsolatedEntityName(text, languageVersion); +} + +/** + * Parse json text into SyntaxTree and return node and parse errors if any + * @param fileName + * @param sourceText + */ +export function parseJsonText(fileName: string, sourceText: string): JsonSourceFile { + return Parser.parseJsonText(fileName, sourceText); +} + +// See also `isExternalOrCommonJsModule` in utilities.ts +export function isExternalModule(file: SourceFile): boolean { + return file.externalModuleIndicator !== undefined; +} + +// Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter +// indicates what changed between the 'text' that this SourceFile has and the 'newText'. +// The SourceFile will be created with the compiler attempting to reuse as many nodes from +// this file as possible. +// +// Note: this function mutates nodes from this SourceFile. That means any existing nodes +// from this SourceFile that are being held onto may change as a result (including +// becoming detached from any SourceFile). It is recommended that this SourceFile not +// be used once 'update' is called on it. +export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks = false): SourceFile { + const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); + // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. + // We will manually port the flag to the new source file. + (newSourceFile as Mutable).flags |= sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags; + return newSourceFile; +} + +/** @internal */ +export interface JsDocWithDiagnostics { + jsDoc: JSDoc; + diagnostics: Diagnostic[]; +} + +/** @internal */ +export function parseIsolatedJSDocComment(content: string, start?: number, length?: number): JsDocWithDiagnostics | undefined { + const result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); + if (result && result.jsDoc) { + // because the jsDocComment was parsed out of the source file, it might + // not be covered by the fixupParentReferences. + Parser.fixupParentReferences(result.jsDoc); + } + + return result; +} + +/** @internal */ +// Exposed only for testing. +export function parseJSDocTypeExpressionForTests(content: string, start?: number, length?: number): { + jsDocTypeExpression: JSDocTypeExpression; + diagnostics: Diagnostic[]; +} | undefined { + return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); +} + +// Implement the parser as a singleton module. We do this for perf reasons because creating +// parser instances can actually be expensive enough to impact us on projects with many source +// files. +namespace Parser { + // Why var? It avoids TDZ checks in the runtime which can be costly. + // See: https://github.com/microsoft/TypeScript/issues/52924 + /* eslint-disable no-var */ + + // Share a single scanner across all calls to parse a source file. This helps speed things + // up by avoiding the cost of creating/compiling scanners over and over again. + var scanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ true); + + var disallowInAndDecoratorContext = NodeFlags.DisallowInContext | NodeFlags.DecoratorContext; + + // capture constructors in 'initializeState' to avoid null checks + var NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + var TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + var IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Identifier; + var PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => PrivateIdentifier; + var SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => SourceFile; + + function countNode(node: Node) { + nodeCount++; + return node; + } + + // Rather than using `createBaseNodeFactory` here, we establish a `BaseNodeFactory` that closes over the + // constructors above, which are reset each time `initializeState` is called. + var baseNodeFactory: BaseNodeFactory = { + createBaseSourceFileNode: kind => countNode(new SourceFileConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBaseIdentifierNode: kind => countNode(new IdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBasePrivateIdentifierNode: kind => countNode(new PrivateIdentifierConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBaseTokenNode: kind => countNode(new TokenConstructor(kind, /*pos*/ 0, /*end*/ 0)), + createBaseNode: kind => countNode(new NodeConstructor(kind, /*pos*/ 0, /*end*/ 0)), + }; + + var factory = createNodeFactory(NodeFactoryFlags.NoParenthesizerRules | NodeFactoryFlags.NoNodeConverters | NodeFactoryFlags.NoOriginalNode, baseNodeFactory); + + var { + createNodeArray: factoryCreateNodeArray, + createNumericLiteral: factoryCreateNumericLiteral, + createStringLiteral: factoryCreateStringLiteral, + createLiteralLikeNode: factoryCreateLiteralLikeNode, + createIdentifier: factoryCreateIdentifier, + createPrivateIdentifier: factoryCreatePrivateIdentifier, + createToken: factoryCreateToken, + createArrayLiteralExpression: factoryCreateArrayLiteralExpression, + createObjectLiteralExpression: factoryCreateObjectLiteralExpression, + createPropertyAccessExpression: factoryCreatePropertyAccessExpression, + createPropertyAccessChain: factoryCreatePropertyAccessChain, + createElementAccessExpression: factoryCreateElementAccessExpression, + createElementAccessChain: factoryCreateElementAccessChain, + createCallExpression: factoryCreateCallExpression, + createCallChain: factoryCreateCallChain, + createNewExpression: factoryCreateNewExpression, + createParenthesizedExpression: factoryCreateParenthesizedExpression, + createBlock: factoryCreateBlock, + createVariableStatement: factoryCreateVariableStatement, + createExpressionStatement: factoryCreateExpressionStatement, + createIfStatement: factoryCreateIfStatement, + createWhileStatement: factoryCreateWhileStatement, + createForStatement: factoryCreateForStatement, + createForOfStatement: factoryCreateForOfStatement, + createVariableDeclaration: factoryCreateVariableDeclaration, + createVariableDeclarationList: factoryCreateVariableDeclarationList, + } = factory; + + var fileName: string; + var sourceFlags: NodeFlags; + var sourceText: string; + var languageVersion: ScriptTarget; + var scriptKind: ScriptKind; + var languageVariant: LanguageVariant; + var parseDiagnostics: DiagnosticWithDetachedLocation[]; + var jsDocDiagnostics: DiagnosticWithDetachedLocation[]; + var syntaxCursor: IncrementalParser.SyntaxCursor | undefined; + + var currentToken: SyntaxKind; + var nodeCount: number; + var identifiers: Map; + var identifierCount: number; + + // TODO(jakebailey): This type is a lie; this value actually contains the result + // of ORing a bunch of `1 << ParsingContext.XYZ`. + var parsingContext: ParsingContext; + + var notParenthesizedArrow: Set | undefined; + + // Flags that dictate what parsing context we're in. For example: + // Whether or not we are in strict parsing mode. All that changes in strict parsing mode is + // that some tokens that would be considered identifiers may be considered keywords. + // + // When adding more parser context flags, consider which is the more common case that the + // flag will be in. This should be the 'false' state for that flag. The reason for this is + // that we don't store data in our nodes unless the value is in the *non-default* state. So, + // for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for + // 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost + // all nodes would need extra state on them to store this info. + // + // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 + // grammar specification. + // + // An important thing about these context concepts. By default they are effectively inherited + // while parsing through every grammar production. i.e. if you don't change them, then when + // you parse a sub-production, it will have the same context values as the parent production. + // This is great most of the time. After all, consider all the 'expression' grammar productions + // and how nearly all of them pass along the 'in' and 'yield' context values: + // + // EqualityExpression[In, Yield] : + // RelationalExpression[?In, ?Yield] + // EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield] + // EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield] + // EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield] + // EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield] + // + // Where you have to be careful is then understanding what the points are in the grammar + // where the values are *not* passed along. For example: + // + // SingleNameBinding[Yield,GeneratorParameter] + // [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt + // [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt + // + // Here this is saying that if the GeneratorParameter context flag is set, that we should + // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier + // and we should explicitly unset the 'yield' context flag before calling into the Initializer. + // production. Conversely, if the GeneratorParameter context flag is not set, then we + // should leave the 'yield' context flag alone. + // + // Getting this all correct is tricky and requires careful reading of the grammar to + // understand when these values should be changed versus when they should be inherited. + // + // Note: it should not be necessary to save/restore these flags during speculative/lookahead + // parsing. These context flags are naturally stored and restored through normal recursive + // descent parsing and unwinding. + var contextFlags: NodeFlags; + + // Indicates whether we are currently parsing top-level statements. + var topLevel = true; + + // Whether or not we've had a parse error since creating the last AST node. If we have + // encountered an error, it will be stored on the next AST node we create. Parse errors + // can be broken down into three categories: + // + // 1) An error that occurred during scanning. For example, an unterminated literal, or a + // character that was completely not understood. + // + // 2) A token was expected, but was not present. This type of error is commonly produced + // by the 'parseExpected' function. + // + // 3) A token was present that no parsing function was able to consume. This type of error + // only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser + // decides to skip the token. + // + // In all of these cases, we want to mark the next node as having had an error before it. + // With this mark, we can know in incremental settings if this node can be reused, or if + // we have to reparse it. If we don't keep this information around, we may just reuse the + // node. in that event we would then not produce the same errors as we did before, causing + // significant confusion problems. + // + // Note: it is necessary that this value be saved/restored during speculative/lookahead + // parsing. During lookahead parsing, we will often create a node. That node will have + // this value attached, and then this value will be set back to 'false'. If we decide to + // rewind, we must get back to the same value we had prior to the lookahead. + // + // Note: any errors at the end of the file that do not precede a regular node, should get + // attached to the EOF token. + var parseErrorBeforeNextFinishedNode = false; + /* eslint-enable no-var */ + + export function parseSourceFile( + fileName: string, + sourceText: string, + languageVersion: ScriptTarget, + syntaxCursor: IncrementalParser.SyntaxCursor | undefined, + setParentNodes = false, + scriptKind?: ScriptKind, + setExternalModuleIndicatorOverride?: (file: SourceFile) => void, + jsDocParsingMode = JSDocParsingMode.ParseAll, + ): SourceFile { + scriptKind = ensureScriptKind(fileName, scriptKind); + if (scriptKind === ScriptKind.JSON) { + const result = parseJsonText(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes); + convertToJson(result, result.statements[0]?.expression, result.parseDiagnostics, /*returnValue*/ false, /*jsonConversionNotifier*/ undefined); + result.referencedFiles = emptyArray; + result.typeReferenceDirectives = emptyArray; + result.libReferenceDirectives = emptyArray; + result.amdDependencies = emptyArray; + result.hasNoDefaultLib = false; + result.pragmas = emptyMap as ReadonlyPragmaMap; + return result; + } + + initializeState(fileName, sourceText, languageVersion, syntaxCursor, scriptKind, jsDocParsingMode); + + const result = parseSourceFileWorker(languageVersion, setParentNodes, scriptKind, setExternalModuleIndicatorOverride || setExternalModuleIndicator, jsDocParsingMode); + + clearState(); + + return result; + } + + export function parseIsolatedEntityName(content: string, languageVersion: ScriptTarget): EntityName | undefined { + // Choice of `isDeclarationFile` should be arbitrary + initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS, JSDocParsingMode.ParseAll); + // Prime the scanner. + nextToken(); + const entityName = parseEntityName(/*allowReservedWords*/ true); + const isValid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length; + clearState(); + return isValid ? entityName : undefined; + } + + export function parseJsonText(fileName: string, sourceText: string, languageVersion: ScriptTarget = ScriptTarget.ES2015, syntaxCursor?: IncrementalParser.SyntaxCursor, setParentNodes = false): JsonSourceFile { + initializeState(fileName, sourceText, languageVersion, syntaxCursor, ScriptKind.JSON, JSDocParsingMode.ParseAll); + sourceFlags = contextFlags; + + // Prime the scanner. + nextToken(); + const pos = getNodePos(); + let statements, endOfFileToken; + if (token() === SyntaxKind.EndOfFileToken) { + statements = createNodeArray([], pos, pos); + endOfFileToken = parseTokenNode(); + } + else { + // Loop and synthesize an ArrayLiteralExpression if there are more than + // one top-level expressions to ensure all input text is consumed. + let expressions: Expression[] | Expression | undefined; + while (token() !== SyntaxKind.EndOfFileToken) { + let expression; + switch (token()) { + case SyntaxKind.OpenBracketToken: + expression = parseArrayLiteralExpression(); + break; + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + case SyntaxKind.NullKeyword: + expression = parseTokenNode(); + break; + case SyntaxKind.MinusToken: + if (lookAhead(() => nextToken() === SyntaxKind.NumericLiteral && nextToken() !== SyntaxKind.ColonToken)) { + expression = parsePrefixUnaryExpression() as JsonMinusNumericLiteral; + } + else { + expression = parseObjectLiteralExpression(); + } + break; + case SyntaxKind.NumericLiteral: + case SyntaxKind.StringLiteral: + if (lookAhead(() => nextToken() !== SyntaxKind.ColonToken)) { + expression = parseLiteralNode() as StringLiteral | NumericLiteral; + break; + } + // falls through + default: + expression = parseObjectLiteralExpression(); + break; + } + + // Error recovery: collect multiple top-level expressions + if (expressions && isArray(expressions)) { + expressions.push(expression); + } + else if (expressions) { + expressions = [expressions, expression]; + } + else { + expressions = expression; + if (token() !== SyntaxKind.EndOfFileToken) { + parseErrorAtCurrentToken(Diagnostics.Unexpected_token); + } + } + } + + const expression = isArray(expressions) ? finishNode(factoryCreateArrayLiteralExpression(expressions), pos) : Debug.checkDefined(expressions); + const statement = factoryCreateExpressionStatement(expression) as JsonObjectExpressionStatement; + finishNode(statement, pos); + statements = createNodeArray([statement], pos); + endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token) as EndOfFileToken; + } + + // Set source file so that errors will be reported with this file name + const sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclarationFile*/ false, statements, endOfFileToken, sourceFlags, noop); + + if (setParentNodes) { + fixupParentReferences(sourceFile); + } + + sourceFile.nodeCount = nodeCount; + sourceFile.identifierCount = identifierCount; + sourceFile.identifiers = identifiers; + sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + if (jsDocDiagnostics) { + sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + } + + const result = sourceFile as JsonSourceFile; + clearState(); + return result; + } + + function initializeState(_fileName: string, _sourceText: string, _languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor | undefined, _scriptKind: ScriptKind, _jsDocParsingMode: JSDocParsingMode) { + NodeConstructor = objectAllocator.getNodeConstructor(); + TokenConstructor = objectAllocator.getTokenConstructor(); + IdentifierConstructor = objectAllocator.getIdentifierConstructor(); + PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor(); + SourceFileConstructor = objectAllocator.getSourceFileConstructor(); + + fileName = normalizePath(_fileName); + sourceText = _sourceText; + languageVersion = _languageVersion; + syntaxCursor = _syntaxCursor; + scriptKind = _scriptKind; + languageVariant = getLanguageVariant(_scriptKind); + + parseDiagnostics = []; + parsingContext = 0; + identifiers = new Map(); + identifierCount = 0; + nodeCount = 0; + sourceFlags = 0; + topLevel = true; + + switch (scriptKind) { + case ScriptKind.JS: + case ScriptKind.JSX: + contextFlags = NodeFlags.JavaScriptFile; + break; + case ScriptKind.JSON: + contextFlags = NodeFlags.JavaScriptFile | NodeFlags.JsonFile; + break; + default: + contextFlags = NodeFlags.None; + break; + } + parseErrorBeforeNextFinishedNode = false; + + // Initialize and prime the scanner before parsing the source elements. + scanner.setText(sourceText); + scanner.setOnError(scanError); + scanner.setScriptTarget(languageVersion); + scanner.setLanguageVariant(languageVariant); + scanner.setScriptKind(scriptKind); + scanner.setJSDocParsingMode(_jsDocParsingMode); + } + + function clearState() { + // Clear out the text the scanner is pointing at, so it doesn't keep anything alive unnecessarily. + scanner.clearCommentDirectives(); + scanner.setText(""); + scanner.setOnError(undefined); + scanner.setScriptKind(ScriptKind.Unknown); + scanner.setJSDocParsingMode(JSDocParsingMode.ParseAll); + + // Clear any data. We don't want to accidentally hold onto it for too long. + sourceText = undefined!; + languageVersion = undefined!; + syntaxCursor = undefined; + scriptKind = undefined!; + languageVariant = undefined!; + sourceFlags = 0; + parseDiagnostics = undefined!; + jsDocDiagnostics = undefined!; + parsingContext = 0; + identifiers = undefined!; + notParenthesizedArrow = undefined; + topLevel = true; + } + + function parseSourceFileWorker(languageVersion: ScriptTarget, setParentNodes: boolean, scriptKind: ScriptKind, setExternalModuleIndicator: (file: SourceFile) => void, jsDocParsingMode: JSDocParsingMode): SourceFile { + const isDeclarationFile = isDeclarationFileName(fileName); + if (isDeclarationFile) { + contextFlags |= NodeFlags.Ambient; + } + + sourceFlags = contextFlags; + + // Prime the scanner. + nextToken(); + + const statements = parseList(ParsingContext.SourceElements, parseStatement); + Debug.assert(token() === SyntaxKind.EndOfFileToken); + const endHasJSDoc = hasPrecedingJSDocComment(); + const endOfFileToken = withJSDoc(parseTokenNode(), endHasJSDoc); + + const sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile, statements, endOfFileToken, sourceFlags, setExternalModuleIndicator); + + // A member of ReadonlyArray isn't assignable to a member of T[] (and prevents a direct cast) - but this is where we set up those members so they can be readonly in the future + processCommentPragmas(sourceFile as {} as PragmaContext, sourceText); + processPragmasIntoFields(sourceFile as {} as PragmaContext, reportPragmaDiagnostic); + + sourceFile.commentDirectives = scanner.getCommentDirectives(); + sourceFile.nodeCount = nodeCount; + sourceFile.identifierCount = identifierCount; + sourceFile.identifiers = identifiers; + sourceFile.parseDiagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + sourceFile.jsDocParsingMode = jsDocParsingMode; + if (jsDocDiagnostics) { + sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + } + + if (setParentNodes) { + fixupParentReferences(sourceFile); + } + + return sourceFile; + + function reportPragmaDiagnostic(pos: number, end: number, diagnostic: DiagnosticMessage) { + parseDiagnostics.push(createDetachedDiagnostic(fileName, sourceText, pos, end, diagnostic)); + } + } + + let hasDeprecatedTag = false; + function withJSDoc(node: T, hasJSDoc: boolean): T { + if (!hasJSDoc) { + return node; + } + + Debug.assert(!node.jsDoc); // Should only be called once per node + const jsDoc = mapDefined(getJSDocCommentRanges(node, sourceText), comment => JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos)); + if (jsDoc.length) node.jsDoc = jsDoc; + if (hasDeprecatedTag) { + hasDeprecatedTag = false; + (node as Mutable).flags |= NodeFlags.Deprecated; + } + return node; + } + + function reparseTopLevelAwait(sourceFile: SourceFile) { + const savedSyntaxCursor = syntaxCursor; + const baseSyntaxCursor = IncrementalParser.createSyntaxCursor(sourceFile); + syntaxCursor = { currentNode }; + + const statements: Statement[] = []; + const savedParseDiagnostics = parseDiagnostics; + + parseDiagnostics = []; + + let pos = 0; + let start = findNextStatementWithAwait(sourceFile.statements, 0); + while (start !== -1) { + // append all statements between pos and start + const prevStatement = sourceFile.statements[pos]; + const nextStatement = sourceFile.statements[start]; + addRange(statements, sourceFile.statements, pos, start); + pos = findNextStatementWithoutAwait(sourceFile.statements, start); + + // append all diagnostics associated with the copied range + const diagnosticStart = findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); + const diagnosticEnd = diagnosticStart >= 0 ? findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= nextStatement.pos, diagnosticStart) : -1; + if (diagnosticStart >= 0) { + addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart, diagnosticEnd >= 0 ? diagnosticEnd : undefined); + } + + // reparse all statements between start and pos. We skip existing diagnostics for the same range and allow the parser to generate new ones. + speculationHelper(() => { + const savedContextFlags = contextFlags; + contextFlags |= NodeFlags.AwaitContext; + scanner.resetTokenState(nextStatement.pos); + nextToken(); + + while (token() !== SyntaxKind.EndOfFileToken) { + const startPos = scanner.getTokenFullStart(); + const statement = parseListElement(ParsingContext.SourceElements, parseStatement); + statements.push(statement); + if (startPos === scanner.getTokenFullStart()) { + nextToken(); + } + + if (pos >= 0) { + const nonAwaitStatement = sourceFile.statements[pos]; + if (statement.end === nonAwaitStatement.pos) { + // done reparsing this section + break; + } + if (statement.end > nonAwaitStatement.pos) { + // we ate into the next statement, so we must reparse it. + pos = findNextStatementWithoutAwait(sourceFile.statements, pos + 1); + } + } + } + + contextFlags = savedContextFlags; + }, SpeculationKind.Reparse); + + // find the next statement containing an `await` + start = pos >= 0 ? findNextStatementWithAwait(sourceFile.statements, pos) : -1; + } + + // append all statements between pos and the end of the list + if (pos >= 0) { + const prevStatement = sourceFile.statements[pos]; + addRange(statements, sourceFile.statements, pos); + + // append all diagnostics associated with the copied range + const diagnosticStart = findIndex(savedParseDiagnostics, diagnostic => diagnostic.start >= prevStatement.pos); + if (diagnosticStart >= 0) { + addRange(parseDiagnostics, savedParseDiagnostics, diagnosticStart); + } + } + + syntaxCursor = savedSyntaxCursor; + return factory.updateSourceFile(sourceFile, setTextRange(factoryCreateNodeArray(statements), sourceFile.statements)); + + function containsPossibleTopLevelAwait(node: Node) { + return !(node.flags & NodeFlags.AwaitContext) + && !!(node.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait); + } + + function findNextStatementWithAwait(statements: NodeArray, start: number) { + for (let i = start; i < statements.length; i++) { + if (containsPossibleTopLevelAwait(statements[i])) { + return i; + } + } + return -1; + } + + function findNextStatementWithoutAwait(statements: NodeArray, start: number) { + for (let i = start; i < statements.length; i++) { + if (!containsPossibleTopLevelAwait(statements[i])) { + return i; + } + } + return -1; + } + + function currentNode(position: number) { + const node = baseSyntaxCursor.currentNode(position); + if (topLevel && node && containsPossibleTopLevelAwait(node)) { + markAsIntersectingIncrementalChange(node); + } + return node; + } + } + + export function fixupParentReferences(rootNode: Node) { + // normally parent references are set during binding. However, for clients that only need + // a syntax tree, and no semantic features, then the binding process is an unnecessary + // overhead. This functions allows us to set all the parents, without all the expense of + // binding. + setParentRecursive(rootNode, /*incremental*/ true); + } + + function createSourceFile( + fileName: string, + languageVersion: ScriptTarget, + scriptKind: ScriptKind, + isDeclarationFile: boolean, + statements: readonly Statement[], + endOfFileToken: EndOfFileToken, + flags: NodeFlags, + setExternalModuleIndicator: (sourceFile: SourceFile) => void, + ): SourceFile { + // code from createNode is inlined here so createNode won't have to deal with special case of creating source files + // this is quite rare comparing to other nodes and createNode should be as fast as possible + let sourceFile = factory.createSourceFile(statements, endOfFileToken, flags); + setTextRangePosWidth(sourceFile, 0, sourceText.length); + setFields(sourceFile); + + // If we parsed this as an external module, it may contain top-level await + if (!isDeclarationFile && isExternalModule(sourceFile) && sourceFile.transformFlags & TransformFlags.ContainsPossibleTopLevelAwait) { + const oldSourceFile = sourceFile; + sourceFile = reparseTopLevelAwait(sourceFile); + if (oldSourceFile !== sourceFile) setFields(sourceFile); + } + + return sourceFile; + + function setFields(sourceFile: SourceFile) { + sourceFile.text = sourceText; + sourceFile.bindDiagnostics = []; + sourceFile.bindSuggestionDiagnostics = undefined; + sourceFile.languageVersion = languageVersion; + sourceFile.fileName = fileName; + sourceFile.languageVariant = getLanguageVariant(scriptKind); + sourceFile.isDeclarationFile = isDeclarationFile; + sourceFile.scriptKind = scriptKind; + + setExternalModuleIndicator(sourceFile); + sourceFile.setExternalModuleIndicator = setExternalModuleIndicator; + } + } + + function setContextFlag(val: boolean, flag: NodeFlags) { + if (val) { + contextFlags |= flag; + } + else { + contextFlags &= ~flag; + } + } + + function setDisallowInContext(val: boolean) { + setContextFlag(val, NodeFlags.DisallowInContext); + } + + function setYieldContext(val: boolean) { + setContextFlag(val, NodeFlags.YieldContext); + } + + function setDecoratorContext(val: boolean) { + setContextFlag(val, NodeFlags.DecoratorContext); + } + + function setAwaitContext(val: boolean) { + setContextFlag(val, NodeFlags.AwaitContext); + } + + function doOutsideOfContext(context: NodeFlags, func: () => T): T { + // contextFlagsToClear will contain only the context flags that are + // currently set that we need to temporarily clear + // We don't just blindly reset to the previous flags to ensure + // that we do not mutate cached flags for the incremental + // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and + // HasAggregatedChildData). + const contextFlagsToClear = context & contextFlags; + if (contextFlagsToClear) { + // clear the requested context flags + setContextFlag(/*val*/ false, contextFlagsToClear); + const result = func(); + // restore the context flags we just cleared + setContextFlag(/*val*/ true, contextFlagsToClear); + return result; + } + + // no need to do anything special as we are not in any of the requested contexts + return func(); + } + + function doInsideOfContext(context: NodeFlags, func: () => T): T { + // contextFlagsToSet will contain only the context flags that + // are not currently set that we need to temporarily enable. + // We don't just blindly reset to the previous flags to ensure + // that we do not mutate cached flags for the incremental + // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and + // HasAggregatedChildData). + const contextFlagsToSet = context & ~contextFlags; + if (contextFlagsToSet) { + // set the requested context flags + setContextFlag(/*val*/ true, contextFlagsToSet); + const result = func(); + // reset the context flags we just set + setContextFlag(/*val*/ false, contextFlagsToSet); + return result; + } + + // no need to do anything special as we are already in all of the requested contexts + return func(); + } + + function allowInAnd(func: () => T): T { + return doOutsideOfContext(NodeFlags.DisallowInContext, func); + } + + function disallowInAnd(func: () => T): T { + return doInsideOfContext(NodeFlags.DisallowInContext, func); + } + + function allowConditionalTypesAnd(func: () => T): T { + return doOutsideOfContext(NodeFlags.DisallowConditionalTypesContext, func); + } + + function disallowConditionalTypesAnd(func: () => T): T { + return doInsideOfContext(NodeFlags.DisallowConditionalTypesContext, func); + } + + function doInYieldContext(func: () => T): T { + return doInsideOfContext(NodeFlags.YieldContext, func); + } + + function doInDecoratorContext(func: () => T): T { + return doInsideOfContext(NodeFlags.DecoratorContext, func); + } + + function doInAwaitContext(func: () => T): T { + return doInsideOfContext(NodeFlags.AwaitContext, func); + } + + function doOutsideOfAwaitContext(func: () => T): T { + return doOutsideOfContext(NodeFlags.AwaitContext, func); + } + + function doInYieldAndAwaitContext(func: () => T): T { + return doInsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); + } + + function doOutsideOfYieldAndAwaitContext(func: () => T): T { + return doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext, func); + } + + function inContext(flags: NodeFlags) { + return (contextFlags & flags) !== 0; + } + + function inYieldContext() { + return inContext(NodeFlags.YieldContext); + } + + function inDisallowInContext() { + return inContext(NodeFlags.DisallowInContext); + } + + function inDisallowConditionalTypesContext() { + return inContext(NodeFlags.DisallowConditionalTypesContext); + } + + function inDecoratorContext() { + return inContext(NodeFlags.DecoratorContext); + } + + function inAwaitContext() { + return inContext(NodeFlags.AwaitContext); + } + + function parseErrorAtCurrentToken(message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { + return parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), message, ...args); + } + + function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { + // Don't report another error if it would just be at the same position as the last error. + const lastError = lastOrUndefined(parseDiagnostics); + let result: DiagnosticWithDetachedLocation | undefined; + if (!lastError || start !== lastError.start) { + result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args); + parseDiagnostics.push(result); + } + + // Mark that we've encountered an error. We'll set an appropriate bit on the next + // node we finish so that it can't be reused incrementally. + parseErrorBeforeNextFinishedNode = true; + return result; + } + + function parseErrorAt(start: number, end: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { + return parseErrorAtPosition(start, end - start, message, ...args); + } + + function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, ...args: DiagnosticArguments): void { + parseErrorAt(range.pos, range.end, message, ...args); + } + + function scanError(message: DiagnosticMessage, length: number, arg0?: any): void { + parseErrorAtPosition(scanner.getTokenEnd(), length, message, arg0); + } + + function getNodePos(): number { + return scanner.getTokenFullStart(); + } + + function hasPrecedingJSDocComment() { + return scanner.hasPrecedingJSDocComment(); + } + + // Use this function to access the current token instead of reading the currentToken + // variable. Since function results aren't narrowed in control flow analysis, this ensures + // that the type checker doesn't make wrong assumptions about the type of the current + // token (e.g. a call to nextToken() changes the current token but the checker doesn't + // reason about this side effect). Mainstream VMs inline simple functions like this, so + // there is no performance penalty. + function token(): SyntaxKind { + return currentToken; + } + + function nextTokenWithoutCheck() { + return currentToken = scanner.scan(); + } + + function nextTokenAnd(func: () => T): T { + nextToken(); + return func(); + } + + function nextToken(): SyntaxKind { + // if the keyword had an escape + if (isKeyword(currentToken) && (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape())) { + // issue a parse error for the escape + parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), Diagnostics.Keywords_cannot_contain_escape_characters); + } + return nextTokenWithoutCheck(); + } + + function nextTokenJSDoc(): JSDocSyntaxKind { + return currentToken = scanner.scanJsDocToken(); + } + + function nextJSDocCommentTextToken(inBackticks: boolean): JSDocSyntaxKind | SyntaxKind.JSDocCommentTextToken { + return currentToken = scanner.scanJSDocCommentTextToken(inBackticks); + } + + function reScanGreaterToken(): SyntaxKind { + return currentToken = scanner.reScanGreaterToken(); + } + + function reScanSlashToken(): SyntaxKind { + return currentToken = scanner.reScanSlashToken(); + } + + function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind { + return currentToken = scanner.reScanTemplateToken(isTaggedTemplate); + } + + function reScanLessThanToken(): SyntaxKind { + return currentToken = scanner.reScanLessThanToken(); + } + + function reScanHashToken(): SyntaxKind { + return currentToken = scanner.reScanHashToken(); + } + + function scanJsxIdentifier(): SyntaxKind { + return currentToken = scanner.scanJsxIdentifier(); + } + + function scanJsxText(): SyntaxKind { + return currentToken = scanner.scanJsxToken(); + } + + function scanJsxAttributeValue(): SyntaxKind { + return currentToken = scanner.scanJsxAttributeValue(); + } + + function speculationHelper(callback: () => T, speculationKind: SpeculationKind): T { + // Keep track of the state we'll need to rollback to if lookahead fails (or if the + // caller asked us to always reset our state). + const saveToken = currentToken; + const saveParseDiagnosticsLength = parseDiagnostics.length; + const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; + + // Note: it is not actually necessary to save/restore the context flags here. That's + // because the saving/restoring of these flags happens naturally through the recursive + // descent nature of our parser. However, we still store this here just so we can + // assert that invariant holds. + const saveContextFlags = contextFlags; + + // If we're only looking ahead, then tell the scanner to only lookahead as well. + // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the + // same. + const result = speculationKind !== SpeculationKind.TryParse + ? scanner.lookAhead(callback) + : scanner.tryScan(callback); + + Debug.assert(saveContextFlags === contextFlags); + + // If our callback returned something 'falsy' or we're just looking ahead, + // then unconditionally restore us to where we were. + if (!result || speculationKind !== SpeculationKind.TryParse) { + currentToken = saveToken; + if (speculationKind !== SpeculationKind.Reparse) { + parseDiagnostics.length = saveParseDiagnosticsLength; + } + parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; + } + + return result; + } + + /** Invokes the provided callback then unconditionally restores the parser to the state it + * was in immediately prior to invoking the callback. The result of invoking the callback + * is returned from this function. + */ + function lookAhead(callback: () => T): T { + return speculationHelper(callback, SpeculationKind.Lookahead); + } + + /** Invokes the provided callback. If the callback returns something falsy, then it restores + * the parser to the state it was in immediately prior to invoking the callback. If the + * callback returns something truthy, then the parser state is not rolled back. The result + * of invoking the callback is returned from this function. + */ + function tryParse(callback: () => T): T { + return speculationHelper(callback, SpeculationKind.TryParse); + } + + function isBindingIdentifier(): boolean { + if (token() === SyntaxKind.Identifier) { + return true; + } + + // `let await`/`let yield` in [Yield] or [Await] are allowed here and disallowed in the binder. + return token() > SyntaxKind.LastReservedWord; + } + + // Ignore strict mode flag because we will report an error in type checker instead. + function isIdentifier(): boolean { + if (token() === SyntaxKind.Identifier) { + return true; + } + + // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is + // considered a keyword and is not an identifier. + if (token() === SyntaxKind.YieldKeyword && inYieldContext()) { + return false; + } + + // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is + // considered a keyword and is not an identifier. + if (token() === SyntaxKind.AwaitKeyword && inAwaitContext()) { + return false; + } + + return token() > SyntaxKind.LastReservedWord; + } + + function parseExpected(kind: PunctuationOrKeywordSyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean { + if (token() === kind) { + if (shouldAdvance) { + nextToken(); + } + return true; + } + + // Report specific message if provided with one. Otherwise, report generic fallback message. + if (diagnosticMessage) { + parseErrorAtCurrentToken(diagnosticMessage); + } + else { + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); + } + return false; + } + + const viableKeywordSuggestions = Object.keys(textToKeywordObj).filter(keyword => keyword.length > 2); + + /** + * Provides a better error message than the generic "';' expected" if possible for + * known common variants of a missing semicolon, such as from a mispelled names. + * + * @param node Node preceding the expected semicolon location. + */ + function parseErrorForMissingSemicolonAfter(node: Expression | PropertyName): void { + // Tagged template literals are sometimes used in places where only simple strings are allowed, i.e.: + // module `M1` { + // ^^^^^^^^^^^ This block is parsed as a template literal like module`M1`. + if (isTaggedTemplateExpression(node)) { + parseErrorAt(skipTrivia(sourceText, node.template.pos), node.template.end, Diagnostics.Module_declaration_names_may_only_use_or_quoted_strings); + return; + } + + // Otherwise, if this isn't a well-known keyword-like identifier, give the generic fallback message. + const expressionText = isIdentifierNode(node) ? idText(node) : undefined; + if (!expressionText || !isIdentifierText(expressionText, languageVersion)) { + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); + return; + } + + const pos = skipTrivia(sourceText, node.pos); + + // Some known keywords are likely signs of syntax being used improperly. + switch (expressionText) { + case "const": + case "let": + case "var": + parseErrorAt(pos, node.end, Diagnostics.Variable_declaration_not_allowed_at_this_location); + return; + + case "declare": + // If a declared node failed to parse, it would have emitted a diagnostic already. + return; + + case "interface": + parseErrorForInvalidName(Diagnostics.Interface_name_cannot_be_0, Diagnostics.Interface_must_be_given_a_name, SyntaxKind.OpenBraceToken); + return; + + case "is": + parseErrorAt(pos, scanner.getTokenStart(), Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); + return; + + case "module": + case "namespace": + parseErrorForInvalidName(Diagnostics.Namespace_name_cannot_be_0, Diagnostics.Namespace_must_be_given_a_name, SyntaxKind.OpenBraceToken); + return; + + case "type": + parseErrorForInvalidName(Diagnostics.Type_alias_name_cannot_be_0, Diagnostics.Type_alias_must_be_given_a_name, SyntaxKind.EqualsToken); + return; + } + + // The user alternatively might have misspelled or forgotten to add a space after a common keyword. + const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, identity) ?? getSpaceSuggestion(expressionText); + if (suggestion) { + parseErrorAt(pos, node.end, Diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion); + return; + } + + // Unknown tokens are handled with their own errors in the scanner + if (token() === SyntaxKind.Unknown) { + return; + } + + // Otherwise, we know this some kind of unknown word, not just a missing expected semicolon. + parseErrorAt(pos, node.end, Diagnostics.Unexpected_keyword_or_identifier); + } + + /** + * Reports a diagnostic error for the current token being an invalid name. + * + * @param blankDiagnostic Diagnostic to report for the case of the name being blank (matched tokenIfBlankName). + * @param nameDiagnostic Diagnostic to report for all other cases. + * @param tokenIfBlankName Current token if the name was invalid for being blank (not provided / skipped). + */ + function parseErrorForInvalidName(nameDiagnostic: DiagnosticMessage, blankDiagnostic: DiagnosticMessage, tokenIfBlankName: SyntaxKind) { + if (token() === tokenIfBlankName) { + parseErrorAtCurrentToken(blankDiagnostic); + } + else { + parseErrorAtCurrentToken(nameDiagnostic, scanner.getTokenValue()); + } + } + + function getSpaceSuggestion(expressionText: string) { + for (const keyword of viableKeywordSuggestions) { + if (expressionText.length > keyword.length + 2 && startsWith(expressionText, keyword)) { + return `${keyword} ${expressionText.slice(keyword.length)}`; + } + } + + return undefined; + } + + function parseSemicolonAfterPropertyName(name: PropertyName, type: TypeNode | undefined, initializer: Expression | undefined) { + if (token() === SyntaxKind.AtToken && !scanner.hasPrecedingLineBreak()) { + parseErrorAtCurrentToken(Diagnostics.Decorators_must_precede_the_name_and_all_keywords_of_property_declarations); + return; + } + + if (token() === SyntaxKind.OpenParenToken) { + parseErrorAtCurrentToken(Diagnostics.Cannot_start_a_function_call_in_a_type_annotation); + nextToken(); + return; + } + + if (type && !canParseSemicolon()) { + if (initializer) { + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); + } + else { + parseErrorAtCurrentToken(Diagnostics.Expected_for_property_initializer); + } + return; + } + + if (tryParseSemicolon()) { + return; + } + + if (initializer) { + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.SemicolonToken)); + return; + } + + parseErrorForMissingSemicolonAfter(name); + } + + function parseExpectedJSDoc(kind: JSDocSyntaxKind) { + if (token() === kind) { + nextTokenJSDoc(); + return true; + } + Debug.assert(isKeywordOrPunctuation(kind)); + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); + return false; + } + + function parseExpectedMatchingBrackets(openKind: PunctuationSyntaxKind, closeKind: PunctuationSyntaxKind, openParsed: boolean, openPosition: number) { + if (token() === closeKind) { + nextToken(); + return; + } + const lastError = parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(closeKind)); + if (!openParsed) { + return; + } + if (lastError) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, sourceText, openPosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, tokenToString(openKind), tokenToString(closeKind)), + ); + } + } + + function parseOptional(t: SyntaxKind): boolean { + if (token() === t) { + nextToken(); + return true; + } + return false; + } + + function parseOptionalToken(t: TKind): Token; + function parseOptionalToken(t: SyntaxKind): Node | undefined { + if (token() === t) { + return parseTokenNode(); + } + return undefined; + } + + function parseOptionalTokenJSDoc(t: TKind): Token; + function parseOptionalTokenJSDoc(t: JSDocSyntaxKind): Node | undefined { + if (token() === t) { + return parseTokenNodeJSDoc(); + } + return undefined; + } + + function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: string): Token; + function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: string): Node { + return parseOptionalToken(t) || + createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)!); + } + + function parseExpectedTokenJSDoc(t: TKind): Token; + function parseExpectedTokenJSDoc(t: JSDocSyntaxKind): Node { + const optional = parseOptionalTokenJSDoc(t); + if (optional) return optional; + Debug.assert(isKeywordOrPunctuation(t)); + return createMissingNode(t, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(t)); + } + + function parseTokenNode(): T { + const pos = getNodePos(); + const kind = token(); + nextToken(); + return finishNode(factoryCreateToken(kind), pos) as T; + } + + function parseTokenNodeJSDoc(): T { + const pos = getNodePos(); + const kind = token(); + nextTokenJSDoc(); + return finishNode(factoryCreateToken(kind), pos) as T; + } + + function canParseSemicolon() { + // If there's a real semicolon, then we can always parse it out. + if (token() === SyntaxKind.SemicolonToken) { + return true; + } + + // We can parse out an optional semicolon in ASI cases in the following cases. + return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); + } + + function tryParseSemicolon() { + if (!canParseSemicolon()) { + return false; + } + + if (token() === SyntaxKind.SemicolonToken) { + // consume the semicolon if it was explicitly provided. + nextToken(); + } + + return true; + } + + function parseSemicolon(): boolean { + return tryParseSemicolon() || parseExpected(SyntaxKind.SemicolonToken); + } + + function createNodeArray(elements: T[], pos: number, end?: number, hasTrailingComma?: boolean): NodeArray { + const array = factoryCreateNodeArray(elements, hasTrailingComma); + setTextRangePosEnd(array, pos, end ?? scanner.getTokenFullStart()); + return array; + } + + function finishNode(node: T, pos: number, end?: number): T { + setTextRangePosEnd(node, pos, end ?? scanner.getTokenFullStart()); + if (contextFlags) { + (node as Mutable).flags |= contextFlags; + } + + // Keep track on the node if we encountered an error while parsing it. If we did, then + // we cannot reuse the node incrementally. Once we've marked this node, clear out the + // flag so that we don't mark any subsequent nodes. + if (parseErrorBeforeNextFinishedNode) { + parseErrorBeforeNextFinishedNode = false; + (node as Mutable).flags |= NodeFlags.ThisNodeHasError; + } + + return node; + } + + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, ...args: DiagnosticArguments): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): T { + if (reportAtCurrentPosition) { + parseErrorAtPosition(scanner.getTokenFullStart(), 0, diagnosticMessage!, ...args); + } + else if (diagnosticMessage) { + parseErrorAtCurrentToken(diagnosticMessage, ...args); + } + + const pos = getNodePos(); + const result = kind === SyntaxKind.Identifier ? factoryCreateIdentifier("", /*originalKeywordKind*/ undefined) : + isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, "", "", /*templateFlags*/ undefined) : + kind === SyntaxKind.NumericLiteral ? factoryCreateNumericLiteral("", /*numericLiteralFlags*/ undefined) : + kind === SyntaxKind.StringLiteral ? factoryCreateStringLiteral("", /*isSingleQuote*/ undefined) : + kind === SyntaxKind.MissingDeclaration ? factory.createMissingDeclaration() : + factoryCreateToken(kind); + return finishNode(result, pos) as T; + } + + function internIdentifier(text: string): string { + let identifier = identifiers.get(text); + if (identifier === undefined) { + identifiers.set(text, identifier = text); + } + return identifier; + } + + // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues + // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for + // each identifier in order to reduce memory consumption. + function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { + if (isIdentifier) { + identifierCount++; + const pos = scanner.hasPrecedingJSDocLeadingAsterisks() ? scanner.getTokenStart() : getNodePos(); + // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker + const originalKeywordKind = token(); + const text = internIdentifier(scanner.getTokenValue()); + const hasExtendedUnicodeEscape = scanner.hasExtendedUnicodeEscape(); + nextTokenWithoutCheck(); + return finishNode(factoryCreateIdentifier(text, originalKeywordKind, hasExtendedUnicodeEscape), pos); + } + + if (token() === SyntaxKind.PrivateIdentifier) { + parseErrorAtCurrentToken(privateIdentifierDiagnosticMessage || Diagnostics.Private_identifiers_are_not_allowed_outside_class_bodies); + return createIdentifier(/*isIdentifier*/ true); + } + + if (token() === SyntaxKind.Unknown && scanner.tryScan(() => scanner.reScanInvalidIdentifier() === SyntaxKind.Identifier)) { + // Scanner has already recorded an 'Invalid character' error, so no need to add another from the parser. + return createIdentifier(/*isIdentifier*/ true); + } + + identifierCount++; + // Only for end of file because the error gets reported incorrectly on embedded script tags. + const reportAtCurrentPosition = token() === SyntaxKind.EndOfFileToken; + + const isReservedWord = scanner.isReservedWord(); + const msgArg = scanner.getTokenText(); + + const defaultMessage = isReservedWord ? + Diagnostics.Identifier_expected_0_is_a_reserved_word_that_cannot_be_used_here : + Diagnostics.Identifier_expected; + + return createMissingNode(SyntaxKind.Identifier, reportAtCurrentPosition, diagnosticMessage || defaultMessage, msgArg); + } + + function parseBindingIdentifier(privateIdentifierDiagnosticMessage?: DiagnosticMessage) { + return createIdentifier(isBindingIdentifier(), /*diagnosticMessage*/ undefined, privateIdentifierDiagnosticMessage); + } + + function parseIdentifier(diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier { + return createIdentifier(isIdentifier(), diagnosticMessage, privateIdentifierDiagnosticMessage); + } + + function parseIdentifierName(diagnosticMessage?: DiagnosticMessage): Identifier { + return createIdentifier(tokenIsIdentifierOrKeyword(token()), diagnosticMessage); + } + + function parseIdentifierNameErrorOnUnicodeEscapeSequence(): Identifier { + if (scanner.hasUnicodeEscape() || scanner.hasExtendedUnicodeEscape()) { + parseErrorAtCurrentToken(Diagnostics.Unicode_escape_sequence_cannot_appear_here); + } + return createIdentifier(tokenIsIdentifierOrKeyword(token())); + } + + function isLiteralPropertyName(): boolean { + return tokenIsIdentifierOrKeyword(token()) || + token() === SyntaxKind.StringLiteral || + token() === SyntaxKind.NumericLiteral || + token() === SyntaxKind.BigIntLiteral; + } + + function isImportAttributeName(): boolean { + return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral; + } + + function parsePropertyNameWorker(allowComputedPropertyNames: boolean): PropertyName { + if (token() === SyntaxKind.StringLiteral || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral) { + const node = parseLiteralNode() as StringLiteral | NumericLiteral | BigIntLiteral; + node.text = internIdentifier(node.text); + return node; + } + if (allowComputedPropertyNames && token() === SyntaxKind.OpenBracketToken) { + return parseComputedPropertyName(); + } + if (token() === SyntaxKind.PrivateIdentifier) { + return parsePrivateIdentifier(); + } + return parseIdentifierName(); + } + + function parsePropertyName(): PropertyName { + return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true); + } + + function parseComputedPropertyName(): ComputedPropertyName { + // PropertyName [Yield]: + // LiteralPropertyName + // ComputedPropertyName[?Yield] + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBracketToken); + // We parse any expression (including a comma expression). But the grammar + // says that only an assignment expression is allowed, so the grammar checker + // will error if it sees a comma expression. + const expression = allowInAnd(parseExpression); + parseExpected(SyntaxKind.CloseBracketToken); + return finishNode(factory.createComputedPropertyName(expression), pos); + } + + function parsePrivateIdentifier(): PrivateIdentifier { + const pos = getNodePos(); + const node = factoryCreatePrivateIdentifier(internIdentifier(scanner.getTokenValue())); + nextToken(); + return finishNode(node, pos); + } + + function parseContextualModifier(t: SyntaxKind): boolean { + return token() === t && tryParse(nextTokenCanFollowModifier); + } + + function nextTokenIsOnSameLineAndCanFollowModifier() { + nextToken(); + if (scanner.hasPrecedingLineBreak()) { + return false; + } + return canFollowModifier(); + } + + function nextTokenCanFollowModifier() { + switch (token()) { + case SyntaxKind.ConstKeyword: + // 'const' is only a modifier if followed by 'enum'. + return nextToken() === SyntaxKind.EnumKeyword; + case SyntaxKind.ExportKeyword: + nextToken(); + if (token() === SyntaxKind.DefaultKeyword) { + return lookAhead(nextTokenCanFollowDefaultKeyword); + } + if (token() === SyntaxKind.TypeKeyword) { + return lookAhead(nextTokenCanFollowExportModifier); + } + return canFollowExportModifier(); + case SyntaxKind.DefaultKeyword: + return nextTokenCanFollowDefaultKeyword(); + case SyntaxKind.StaticKeyword: + nextToken(); + return canFollowModifier(); + case SyntaxKind.GetKeyword: + case SyntaxKind.SetKeyword: + nextToken(); + return canFollowGetOrSetKeyword(); + default: + return nextTokenIsOnSameLineAndCanFollowModifier(); + } + } + + function canFollowExportModifier(): boolean { + return token() === SyntaxKind.AtToken + || token() !== SyntaxKind.AsteriskToken + && token() !== SyntaxKind.AsKeyword + && token() !== SyntaxKind.OpenBraceToken + && canFollowModifier(); + } + + function nextTokenCanFollowExportModifier(): boolean { + nextToken(); + return canFollowExportModifier(); + } + + function parseAnyContextualModifier(): boolean { + return isModifierKind(token()) && tryParse(nextTokenCanFollowModifier); + } + + function canFollowModifier(): boolean { + return token() === SyntaxKind.OpenBracketToken + || token() === SyntaxKind.OpenBraceToken + || token() === SyntaxKind.AsteriskToken + || token() === SyntaxKind.DotDotDotToken + || isLiteralPropertyName(); + } + + function canFollowGetOrSetKeyword(): boolean { + return token() === SyntaxKind.OpenBracketToken + || isLiteralPropertyName(); + } + + function nextTokenCanFollowDefaultKeyword(): boolean { + nextToken(); + return token() === SyntaxKind.ClassKeyword + || token() === SyntaxKind.FunctionKeyword + || token() === SyntaxKind.InterfaceKeyword + || token() === SyntaxKind.AtToken + || (token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsClassKeywordOnSameLine)) + || (token() === SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); + } + + // True if positioned at the start of a list element + function isListElement(parsingContext: ParsingContext, inErrorRecovery: boolean): boolean { + const node = currentNode(parsingContext); + if (node) { + return true; + } + + switch (parsingContext) { + case ParsingContext.SourceElements: + case ParsingContext.BlockStatements: + case ParsingContext.SwitchClauseStatements: + // If we're in error recovery, then we don't want to treat ';' as an empty statement. + // The problem is that ';' can show up in far too many contexts, and if we see one + // and assume it's a statement, then we may bail out inappropriately from whatever + // we're parsing. For example, if we have a semicolon in the middle of a class, then + // we really don't want to assume the class is over and we're on a statement in the + // outer module. We just want to consume and move on. + return !(token() === SyntaxKind.SemicolonToken && inErrorRecovery) && isStartOfStatement(); + case ParsingContext.SwitchClauses: + return token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; + case ParsingContext.TypeMembers: + return lookAhead(isTypeMemberStart); + case ParsingContext.ClassMembers: + // We allow semicolons as class elements (as specified by ES6) as long as we're + // not in error recovery. If we're in error recovery, we don't want an errant + // semicolon to be treated as a class member (since they're almost always used + // for statements. + return lookAhead(isClassMemberStart) || (token() === SyntaxKind.SemicolonToken && !inErrorRecovery); + case ParsingContext.EnumMembers: + // Include open bracket computed properties. This technically also lets in indexers, + // which would be a candidate for improved error reporting. + return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName(); + case ParsingContext.ObjectLiteralMembers: + switch (token()) { + case SyntaxKind.OpenBracketToken: + case SyntaxKind.AsteriskToken: + case SyntaxKind.DotDotDotToken: + case SyntaxKind.DotToken: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`) + return true; + default: + return isLiteralPropertyName(); + } + case ParsingContext.RestProperties: + return isLiteralPropertyName(); + case ParsingContext.ObjectBindingElements: + return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName(); + case ParsingContext.ImportAttributes: + return isImportAttributeName(); + case ParsingContext.HeritageClauseElement: + // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{` + // That way we won't consume the body of a class in its heritage clause. + if (token() === SyntaxKind.OpenBraceToken) { + return lookAhead(isValidHeritageClauseObjectLiteral); + } + + if (!inErrorRecovery) { + return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword(); + } + else { + // If we're in error recovery we tighten up what we're willing to match. + // That way we don't treat something like "this" as a valid heritage clause + // element during recovery. + return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword(); + } + case ParsingContext.VariableDeclarations: + return isBindingIdentifierOrPrivateIdentifierOrPattern(); + case ParsingContext.ArrayBindingElements: + return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isBindingIdentifierOrPrivateIdentifierOrPattern(); + case ParsingContext.TypeParameters: + return token() === SyntaxKind.InKeyword || token() === SyntaxKind.ConstKeyword || isIdentifier(); + case ParsingContext.ArrayLiteralMembers: + switch (token()) { + case SyntaxKind.CommaToken: + case SyntaxKind.DotToken: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`) + return true; + } + // falls through + case ParsingContext.ArgumentExpressions: + return token() === SyntaxKind.DotDotDotToken || isStartOfExpression(); + case ParsingContext.Parameters: + return isStartOfParameter(/*isJSDocParameter*/ false); + case ParsingContext.JSDocParameters: + return isStartOfParameter(/*isJSDocParameter*/ true); + case ParsingContext.TypeArguments: + case ParsingContext.TupleElementTypes: + return token() === SyntaxKind.CommaToken || isStartOfType(); + case ParsingContext.HeritageClauses: + return isHeritageClause(); + case ParsingContext.ImportOrExportSpecifiers: + // bail out if the next token is [FromKeyword StringLiteral]. + // That means we're in something like `import { from "mod"`. Stop here can give better error message. + if (token() === SyntaxKind.FromKeyword && lookAhead(nextTokenIsStringLiteral)) { + return false; + } + if (token() === SyntaxKind.StringLiteral) { + return true; // For "arbitrary module namespace identifiers" + } + return tokenIsIdentifierOrKeyword(token()); + case ParsingContext.JsxAttributes: + return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.OpenBraceToken; + case ParsingContext.JsxChildren: + return true; + case ParsingContext.JSDocComment: + return true; + case ParsingContext.Count: + return Debug.fail("ParsingContext.Count used as a context"); // Not a real context, only a marker. + default: + Debug.assertNever(parsingContext, "Non-exhaustive case in 'isListElement'."); + } + } + + function isValidHeritageClauseObjectLiteral() { + Debug.assert(token() === SyntaxKind.OpenBraceToken); + if (nextToken() === SyntaxKind.CloseBraceToken) { + // if we see "extends {}" then only treat the {} as what we're extending (and not + // the class body) if we have: + // + // extends {} { + // extends {}, + // extends {} extends + // extends {} implements + + const next = nextToken(); + return next === SyntaxKind.CommaToken || next === SyntaxKind.OpenBraceToken || next === SyntaxKind.ExtendsKeyword || next === SyntaxKind.ImplementsKeyword; + } + + return true; + } + + function nextTokenIsIdentifier() { + nextToken(); + return isIdentifier(); + } + + function nextTokenIsIdentifierOrKeyword() { + nextToken(); + return tokenIsIdentifierOrKeyword(token()); + } + + function nextTokenIsIdentifierOrKeywordOrGreaterThan() { + nextToken(); + return tokenIsIdentifierOrKeywordOrGreaterThan(token()); + } + + function isHeritageClauseExtendsOrImplementsKeyword(): boolean { + if ( + token() === SyntaxKind.ImplementsKeyword || + token() === SyntaxKind.ExtendsKeyword + ) { + return lookAhead(nextTokenIsStartOfExpression); + } + + return false; + } + + function nextTokenIsStartOfExpression() { + nextToken(); + return isStartOfExpression(); + } + + function nextTokenIsStartOfType() { + nextToken(); + return isStartOfType(); + } + + // True if positioned at a list terminator + function isListTerminator(kind: ParsingContext): boolean { + if (token() === SyntaxKind.EndOfFileToken) { + // Being at the end of the file ends all lists. + return true; + } + + switch (kind) { + case ParsingContext.BlockStatements: + case ParsingContext.SwitchClauses: + case ParsingContext.TypeMembers: + case ParsingContext.ClassMembers: + case ParsingContext.EnumMembers: + case ParsingContext.ObjectLiteralMembers: + case ParsingContext.ObjectBindingElements: + case ParsingContext.ImportOrExportSpecifiers: + case ParsingContext.ImportAttributes: + return token() === SyntaxKind.CloseBraceToken; + case ParsingContext.SwitchClauseStatements: + return token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.CaseKeyword || token() === SyntaxKind.DefaultKeyword; + case ParsingContext.HeritageClauseElement: + return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + case ParsingContext.VariableDeclarations: + return isVariableDeclaratorListTerminator(); + case ParsingContext.TypeParameters: + // Tokens other than '>' are here for better error recovery + return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + case ParsingContext.ArgumentExpressions: + // Tokens other than ')' are here for better error recovery + return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.SemicolonToken; + case ParsingContext.ArrayLiteralMembers: + case ParsingContext.TupleElementTypes: + case ParsingContext.ArrayBindingElements: + return token() === SyntaxKind.CloseBracketToken; + case ParsingContext.JSDocParameters: + case ParsingContext.Parameters: + case ParsingContext.RestProperties: + // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery + return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.CloseBracketToken /*|| token === SyntaxKind.OpenBraceToken*/; + case ParsingContext.TypeArguments: + // All other tokens should cause the type-argument to terminate except comma token + return token() !== SyntaxKind.CommaToken; + case ParsingContext.HeritageClauses: + return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.CloseBraceToken; + case ParsingContext.JsxAttributes: + return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.SlashToken; + case ParsingContext.JsxChildren: + return token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsSlash); + default: + return false; + } + } + + function isVariableDeclaratorListTerminator(): boolean { + // If we can consume a semicolon (either explicitly, or with ASI), then consider us done + // with parsing the list of variable declarators. + if (canParseSemicolon()) { + return true; + } + + // in the case where we're parsing the variable declarator of a 'for-in' statement, we + // are done if we see an 'in' keyword in front of us. Same with for-of + if (isInOrOfKeyword(token())) { + return true; + } + + // ERROR RECOVERY TWEAK: + // For better error recovery, if we see an '=>' then we just stop immediately. We've got an + // arrow function here and it's going to be very unlikely that we'll resynchronize and get + // another variable declaration. + if (token() === SyntaxKind.EqualsGreaterThanToken) { + return true; + } + + // Keep trying to parse out variable declarators. + return false; + } + + // True if positioned at element or terminator of the current list or any enclosing list + function isInSomeParsingContext(): boolean { + // We should be in at least one parsing context, be it SourceElements while parsing + // a SourceFile, or JSDocComment when lazily parsing JSDoc. + Debug.assert(parsingContext, "Missing parsing context"); + for (let kind = 0; kind < ParsingContext.Count; kind++) { + if (parsingContext & (1 << kind)) { + if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) { + return true; + } + } + } + + return false; + } + + // Parses a list of elements + function parseList(kind: ParsingContext, parseElement: () => T): NodeArray { + const saveParsingContext = parsingContext; + parsingContext |= 1 << kind; + const list = []; + const listPos = getNodePos(); + + while (!isListTerminator(kind)) { + if (isListElement(kind, /*inErrorRecovery*/ false)) { + list.push(parseListElement(kind, parseElement)); + + continue; + } + + if (abortParsingListOrMoveToNextToken(kind)) { + break; + } + } + + parsingContext = saveParsingContext; + return createNodeArray(list, listPos); + } + + function parseListElement(parsingContext: ParsingContext, parseElement: () => T): T { + const node = currentNode(parsingContext); + if (node) { + return consumeNode(node) as T; + } + + return parseElement(); + } + + function currentNode(parsingContext: ParsingContext, pos?: number): Node | undefined { + // If we don't have a cursor or the parsing context isn't reusable, there's nothing to reuse. + // + // If there is an outstanding parse error that we've encountered, but not attached to + // some node, then we cannot get a node from the old source tree. This is because we + // want to mark the next node we encounter as being unusable. + // + // Note: This may be too conservative. Perhaps we could reuse the node and set the bit + // on it (or its leftmost child) as having the error. For now though, being conservative + // is nice and likely won't ever affect perf. + if (!syntaxCursor || !isReusableParsingContext(parsingContext) || parseErrorBeforeNextFinishedNode) { + return undefined; + } + + const node = syntaxCursor.currentNode(pos ?? scanner.getTokenFullStart()); + + // Can't reuse a missing node. + // Can't reuse a node that intersected the change range. + // Can't reuse a node that contains a parse error. This is necessary so that we + // produce the same set of errors again. + if (nodeIsMissing(node) || intersectsIncrementalChange(node) || containsParseError(node)) { + return undefined; + } + + // We can only reuse a node if it was parsed under the same strict mode that we're + // currently in. i.e. if we originally parsed a node in non-strict mode, but then + // the user added 'using strict' at the top of the file, then we can't use that node + // again as the presence of strict mode may cause us to parse the tokens in the file + // differently. + // + // Note: we *can* reuse tokens when the strict mode changes. That's because tokens + // are unaffected by strict mode. It's just the parser will decide what to do with it + // differently depending on what mode it is in. + // + // This also applies to all our other context flags as well. + const nodeContextFlags = node.flags & NodeFlags.ContextFlags; + if (nodeContextFlags !== contextFlags) { + return undefined; + } + + // Ok, we have a node that looks like it could be reused. Now verify that it is valid + // in the current list parsing context that we're currently at. + if (!canReuseNode(node, parsingContext)) { + return undefined; + } + + if (canHaveJSDoc(node) && node.jsDoc?.jsDocCache) { + // jsDocCache may include tags from parent nodes, which might have been modified. + node.jsDoc.jsDocCache = undefined; + } + + return node; + } + + function consumeNode(node: Node) { + // Move the scanner so it is after the node we just consumed. + scanner.resetTokenState(node.end); + nextToken(); + return node; + } + + function isReusableParsingContext(parsingContext: ParsingContext): boolean { + switch (parsingContext) { + case ParsingContext.ClassMembers: + case ParsingContext.SwitchClauses: + case ParsingContext.SourceElements: + case ParsingContext.BlockStatements: + case ParsingContext.SwitchClauseStatements: + case ParsingContext.EnumMembers: + case ParsingContext.TypeMembers: + case ParsingContext.VariableDeclarations: + case ParsingContext.JSDocParameters: + case ParsingContext.Parameters: + return true; + } + return false; + } + + function canReuseNode(node: Node, parsingContext: ParsingContext): boolean { + switch (parsingContext) { + case ParsingContext.ClassMembers: + return isReusableClassMember(node); + + case ParsingContext.SwitchClauses: + return isReusableSwitchClause(node); + + case ParsingContext.SourceElements: + case ParsingContext.BlockStatements: + case ParsingContext.SwitchClauseStatements: + return isReusableStatement(node); + + case ParsingContext.EnumMembers: + return isReusableEnumMember(node); + + case ParsingContext.TypeMembers: + return isReusableTypeMember(node); + + case ParsingContext.VariableDeclarations: + return isReusableVariableDeclaration(node); + + case ParsingContext.JSDocParameters: + case ParsingContext.Parameters: + return isReusableParameter(node); + + // Any other lists we do not care about reusing nodes in. But feel free to add if + // you can do so safely. Danger areas involve nodes that may involve speculative + // parsing. If speculative parsing is involved with the node, then the range the + // parser reached while looking ahead might be in the edited range (see the example + // in canReuseVariableDeclaratorNode for a good case of this). + + // case ParsingContext.HeritageClauses: + // This would probably be safe to reuse. There is no speculative parsing with + // heritage clauses. + + // case ParsingContext.TypeParameters: + // This would probably be safe to reuse. There is no speculative parsing with + // type parameters. Note that that's because type *parameters* only occur in + // unambiguous *type* contexts. While type *arguments* occur in very ambiguous + // *expression* contexts. + + // case ParsingContext.TupleElementTypes: + // This would probably be safe to reuse. There is no speculative parsing with + // tuple types. + + // Technically, type argument list types are probably safe to reuse. While + // speculative parsing is involved with them (since type argument lists are only + // produced from speculative parsing a < as a type argument list), we only have + // the types because speculative parsing succeeded. Thus, the lookahead never + // went past the end of the list and rewound. + // case ParsingContext.TypeArguments: + + // Note: these are almost certainly not safe to ever reuse. Expressions commonly + // need a large amount of lookahead, and we should not reuse them as they may + // have actually intersected the edit. + // case ParsingContext.ArgumentExpressions: + + // This is not safe to reuse for the same reason as the 'AssignmentExpression' + // cases. i.e. a property assignment may end with an expression, and thus might + // have lookahead far beyond it's old node. + // case ParsingContext.ObjectLiteralMembers: + + // This is probably not safe to reuse. There can be speculative parsing with + // type names in a heritage clause. There can be generic names in the type + // name list, and there can be left hand side expressions (which can have type + // arguments.) + // case ParsingContext.HeritageClauseElement: + + // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes + // on any given element. Same for children. + // case ParsingContext.JsxAttributes: + // case ParsingContext.JsxChildren: + } + + return false; + } + + function isReusableClassMember(node: Node) { + if (node) { + switch (node.kind) { + case SyntaxKind.Constructor: + case SyntaxKind.IndexSignature: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.SemicolonClassElement: + return true; + case SyntaxKind.MethodDeclaration: + // Method declarations are not necessarily reusable. An object-literal + // may have a method calls "constructor(...)" and we must reparse that + // into an actual .ConstructorDeclaration. + const methodDeclaration = node as MethodDeclaration; + const nameIsConstructor = methodDeclaration.name.kind === SyntaxKind.Identifier && + methodDeclaration.name.escapedText === "constructor"; + + return !nameIsConstructor; + } + } + + return false; + } + + function isReusableSwitchClause(node: Node) { + if (node) { + switch (node.kind) { + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + return true; + } + } + + return false; + } + + function isReusableStatement(node: Node) { + if (node) { + switch (node.kind) { + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.VariableStatement: + case SyntaxKind.Block: + case SyntaxKind.IfStatement: + case SyntaxKind.ExpressionStatement: + case SyntaxKind.ThrowStatement: + case SyntaxKind.ReturnStatement: + case SyntaxKind.SwitchStatement: + case SyntaxKind.BreakStatement: + case SyntaxKind.ContinueStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.ForStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.EmptyStatement: + case SyntaxKind.TryStatement: + case SyntaxKind.LabeledStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.DebuggerStatement: + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ImportEqualsDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.ExportAssignment: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.TypeAliasDeclaration: + return true; + } + } + + return false; + } + + function isReusableEnumMember(node: Node) { + return node.kind === SyntaxKind.EnumMember; + } + + function isReusableTypeMember(node: Node) { + if (node) { + switch (node.kind) { + case SyntaxKind.ConstructSignature: + case SyntaxKind.MethodSignature: + case SyntaxKind.IndexSignature: + case SyntaxKind.PropertySignature: + case SyntaxKind.CallSignature: + return true; + } + } + + return false; + } + + function isReusableVariableDeclaration(node: Node) { + if (node.kind !== SyntaxKind.VariableDeclaration) { + return false; + } + + // Very subtle incremental parsing bug. Consider the following code: + // + // let v = new List < A, B + // + // This is actually legal code. It's a list of variable declarators "v = new List() + // + // then we have a problem. "v = new List(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray; + function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray> | undefined; + function parseDelimitedList(kind: ParsingContext, parseElement: () => T, considerSemicolonAsDelimiter?: boolean): NodeArray> | undefined { + const saveParsingContext = parsingContext; + parsingContext |= 1 << kind; + const list: NonNullable[] = []; + const listPos = getNodePos(); + + let commaStart = -1; // Meaning the previous token was not a comma + while (true) { + if (isListElement(kind, /*inErrorRecovery*/ false)) { + const startPos = scanner.getTokenFullStart(); + const result = parseListElement(kind, parseElement); + if (!result) { + parsingContext = saveParsingContext; + return undefined; + } + list.push(result); + commaStart = scanner.getTokenStart(); + + if (parseOptional(SyntaxKind.CommaToken)) { + // No need to check for a zero length node since we know we parsed a comma + continue; + } + + commaStart = -1; // Back to the state where the last token was not a comma + if (isListTerminator(kind)) { + break; + } + + // We didn't get a comma, and the list wasn't terminated, explicitly parse + // out a comma so we give a good error message. + parseExpected(SyntaxKind.CommaToken, getExpectedCommaDiagnostic(kind)); + + // If the token was a semicolon, and the caller allows that, then skip it and + // continue. This ensures we get back on track and don't result in tons of + // parse errors. For example, this can happen when people do things like use + // a semicolon to delimit object literal members. Note: we'll have already + // reported an error when we called parseExpected above. + if (considerSemicolonAsDelimiter && token() === SyntaxKind.SemicolonToken && !scanner.hasPrecedingLineBreak()) { + nextToken(); + } + if (startPos === scanner.getTokenFullStart()) { + // What we're parsing isn't actually remotely recognizable as a element and we've consumed no tokens whatsoever + // Consume a token to advance the parser in some way and avoid an infinite loop + // This can happen when we're speculatively parsing parenthesized expressions which we think may be arrow functions, + // or when a modifier keyword which is disallowed as a parameter name (ie, `static` in strict mode) is supplied + nextToken(); + } + continue; + } + + if (isListTerminator(kind)) { + break; + } + + if (abortParsingListOrMoveToNextToken(kind)) { + break; + } + } + + parsingContext = saveParsingContext; + // Recording the trailing comma is deliberately done after the previous + // loop, and not just if we see a list terminator. This is because the list + // may have ended incorrectly, but it is still important to know if there + // was a trailing comma. + // Check if the last token was a comma. + // Always preserve a trailing comma by marking it on the NodeArray + return createNodeArray(list, listPos, /*end*/ undefined, commaStart >= 0); + } + + function getExpectedCommaDiagnostic(kind: ParsingContext) { + return kind === ParsingContext.EnumMembers ? Diagnostics.An_enum_member_name_must_be_followed_by_a_or : undefined; + } + + interface MissingList extends NodeArray { + isMissingList: true; + } + + function createMissingList(): MissingList { + const list = createNodeArray([], getNodePos()) as MissingList; + list.isMissingList = true; + return list; + } + + function isMissingList(arr: NodeArray): boolean { + return !!(arr as MissingList).isMissingList; + } + + function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: PunctuationSyntaxKind, close: PunctuationSyntaxKind): NodeArray { + if (parseExpected(open)) { + const result = parseDelimitedList(kind, parseElement); + parseExpected(close); + return result; + } + + return createMissingList(); + } + + function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName { + const pos = getNodePos(); + let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); + while (parseOptional(SyntaxKind.DotToken)) { + if (token() === SyntaxKind.LessThanToken) { + // The entity is part of a JSDoc-style generic. We will use the gap between `typeName` and + // `typeArguments` to report it as a grammar error in the checker. + break; + } + entity = finishNode( + factory.createQualifiedName( + entity, + parseRightSideOfDot(allowReservedWords, /*allowPrivateIdentifiers*/ false, /*allowUnicodeEscapeSequenceInIdentifierName*/ true) as Identifier, + ), + pos, + ); + } + return entity; + } + + function createQualifiedName(entity: EntityName, name: Identifier): QualifiedName { + return finishNode(factory.createQualifiedName(entity, name), entity.pos); + } + + function parseRightSideOfDot(allowIdentifierNames: boolean, allowPrivateIdentifiers: boolean, allowUnicodeEscapeSequenceInIdentifierName: boolean): Identifier | PrivateIdentifier { + // Technically a keyword is valid here as all identifiers and keywords are identifier names. + // However, often we'll encounter this in error situations when the identifier or keyword + // is actually starting another valid construct. + // + // So, we check for the following specific case: + // + // name. + // identifierOrKeyword identifierNameOrKeyword + // + // Note: the newlines are important here. For example, if that above code + // were rewritten into: + // + // name.identifierOrKeyword + // identifierNameOrKeyword + // + // Then we would consider it valid. That's because ASI would take effect and + // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". + // In the first case though, ASI will not take effect because there is not a + // line terminator after the identifier or keyword. + if (scanner.hasPrecedingLineBreak() && tokenIsIdentifierOrKeyword(token())) { + const matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); + + if (matchesPattern) { + // Report that we need an identifier. However, report it right after the dot, + // and not on the next token. This is because the next token might actually + // be an identifier and the error would be quite confusing. + return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); + } + } + + if (token() === SyntaxKind.PrivateIdentifier) { + const node = parsePrivateIdentifier(); + return allowPrivateIdentifiers ? node : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Identifier_expected); + } + + if (allowIdentifierNames) { + return allowUnicodeEscapeSequenceInIdentifierName ? parseIdentifierName() : parseIdentifierNameErrorOnUnicodeEscapeSequence(); + } + + return parseIdentifier(); + } + + function parseTemplateSpans(isTaggedTemplate: boolean) { + const pos = getNodePos(); + const list = []; + let node: TemplateSpan; + do { + node = parseTemplateSpan(isTaggedTemplate); + list.push(node); + } + while (node.literal.kind === SyntaxKind.TemplateMiddle); + return createNodeArray(list, pos); + } + + function parseTemplateExpression(isTaggedTemplate: boolean): TemplateExpression { + const pos = getNodePos(); + return finishNode( + factory.createTemplateExpression( + parseTemplateHead(isTaggedTemplate), + parseTemplateSpans(isTaggedTemplate), + ), + pos, + ); + } + + function parseTemplateType(): TemplateLiteralTypeNode { + const pos = getNodePos(); + return finishNode( + factory.createTemplateLiteralType( + parseTemplateHead(/*isTaggedTemplate*/ false), + parseTemplateTypeSpans(), + ), + pos, + ); + } + + function parseTemplateTypeSpans() { + const pos = getNodePos(); + const list = []; + let node: TemplateLiteralTypeSpan; + do { + node = parseTemplateTypeSpan(); + list.push(node); + } + while (node.literal.kind === SyntaxKind.TemplateMiddle); + return createNodeArray(list, pos); + } + + function parseTemplateTypeSpan(): TemplateLiteralTypeSpan { + const pos = getNodePos(); + return finishNode( + factory.createTemplateLiteralTypeSpan( + parseType(), + parseLiteralOfTemplateSpan(/*isTaggedTemplate*/ false), + ), + pos, + ); + } + + function parseLiteralOfTemplateSpan(isTaggedTemplate: boolean) { + if (token() === SyntaxKind.CloseBraceToken) { + reScanTemplateToken(isTaggedTemplate); + return parseTemplateMiddleOrTemplateTail(); + } + else { + // TODO(rbuckton): Do we need to call `parseExpectedToken` or can we just call `createMissingNode` directly? + return parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)) as TemplateTail; + } + } + + function parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan { + const pos = getNodePos(); + return finishNode( + factory.createTemplateSpan( + allowInAnd(parseExpression), + parseLiteralOfTemplateSpan(isTaggedTemplate), + ), + pos, + ); + } + + function parseLiteralNode(): LiteralExpression { + return parseLiteralLikeNode(token()) as LiteralExpression; + } + + function parseTemplateHead(isTaggedTemplate: boolean): TemplateHead { + if (!isTaggedTemplate && scanner.getTokenFlags() & TokenFlags.IsInvalid) { + reScanTemplateToken(/*isTaggedTemplate*/ false); + } + const fragment = parseLiteralLikeNode(token()); + Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind"); + return fragment as TemplateHead; + } + + function parseTemplateMiddleOrTemplateTail(): TemplateMiddle | TemplateTail { + const fragment = parseLiteralLikeNode(token()); + Debug.assert(fragment.kind === SyntaxKind.TemplateMiddle || fragment.kind === SyntaxKind.TemplateTail, "Template fragment has wrong token kind"); + return fragment as TemplateMiddle | TemplateTail; + } + + function getTemplateLiteralRawText(kind: TemplateLiteralToken["kind"]) { + const isLast = kind === SyntaxKind.NoSubstitutionTemplateLiteral || kind === SyntaxKind.TemplateTail; + const tokenText = scanner.getTokenText(); + return tokenText.substring(1, tokenText.length - (scanner.isUnterminated() ? 0 : isLast ? 1 : 2)); + } + + function parseLiteralLikeNode(kind: SyntaxKind): LiteralLikeNode { + const pos = getNodePos(); + const node = isTemplateLiteralKind(kind) ? factory.createTemplateLiteralLikeNode(kind, scanner.getTokenValue(), getTemplateLiteralRawText(kind), scanner.getTokenFlags() & TokenFlags.TemplateLiteralLikeFlags) : + // Note that theoretically the following condition would hold true literals like 009, + // which is not octal. But because of how the scanner separates the tokens, we would + // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. + // We also do not need to check for negatives because any prefix operator would be part of a + // parent unary expression. + kind === SyntaxKind.NumericLiteral ? factoryCreateNumericLiteral(scanner.getTokenValue(), scanner.getNumericLiteralFlags()) : + kind === SyntaxKind.StringLiteral ? factoryCreateStringLiteral(scanner.getTokenValue(), /*isSingleQuote*/ undefined, scanner.hasExtendedUnicodeEscape()) : + isLiteralKind(kind) ? factoryCreateLiteralLikeNode(kind, scanner.getTokenValue()) : + Debug.fail(); + + if (scanner.hasExtendedUnicodeEscape()) { + node.hasExtendedUnicodeEscape = true; + } + + if (scanner.isUnterminated()) { + node.isUnterminated = true; + } + + nextToken(); + return finishNode(node, pos); + } + + // TYPES + + function parseEntityNameOfTypeReference() { + return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected); + } + + function parseTypeArgumentsOfTypeReference() { + if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) { + return parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); + } + } + + function parseTypeReference(): TypeReferenceNode { + const pos = getNodePos(); + return finishNode( + factory.createTypeReferenceNode( + parseEntityNameOfTypeReference(), + parseTypeArgumentsOfTypeReference(), + ), + pos, + ); + } + + // If true, we should abort parsing an error function. + function typeHasArrowFunctionBlockingParseError(node: TypeNode): boolean { + switch (node.kind) { + case SyntaxKind.TypeReference: + return nodeIsMissing((node as TypeReferenceNode).typeName); + case SyntaxKind.FunctionType: + case SyntaxKind.ConstructorType: { + const { parameters, type } = node as FunctionOrConstructorTypeNode; + return isMissingList(parameters) || typeHasArrowFunctionBlockingParseError(type); + } + case SyntaxKind.ParenthesizedType: + return typeHasArrowFunctionBlockingParseError((node as ParenthesizedTypeNode).type); + default: + return false; + } + } + + function parseThisTypePredicate(lhs: ThisTypeNode): TypePredicateNode { + nextToken(); + return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, lhs, parseType()), lhs.pos); + } + + function parseThisTypeNode(): ThisTypeNode { + const pos = getNodePos(); + nextToken(); + return finishNode(factory.createThisTypeNode(), pos); + } + + function parseJSDocAllType(): JSDocAllType | JSDocOptionalType { + const pos = getNodePos(); + nextToken(); + return finishNode(factory.createJSDocAllType(), pos); + } + + function parseJSDocNonNullableType(): TypeNode { + const pos = getNodePos(); + nextToken(); + return finishNode(factory.createJSDocNonNullableType(parseNonArrayType(), /*postfix*/ false), pos); + } + + function parseJSDocUnknownOrNullableType(): JSDocUnknownType | JSDocNullableType { + const pos = getNodePos(); + // skip the ? + nextToken(); + + // Need to lookahead to decide if this is a nullable or unknown type. + + // Here are cases where we'll pick the unknown type: + // + // Foo(?, + // { a: ? } + // Foo(?) + // Foo + // Foo(?= + // (?| + if ( + token() === SyntaxKind.CommaToken || + token() === SyntaxKind.CloseBraceToken || + token() === SyntaxKind.CloseParenToken || + token() === SyntaxKind.GreaterThanToken || + token() === SyntaxKind.EqualsToken || + token() === SyntaxKind.BarToken + ) { + return finishNode(factory.createJSDocUnknownType(), pos); + } + else { + return finishNode(factory.createJSDocNullableType(parseType(), /*postfix*/ false), pos); + } + } + + function parseJSDocFunctionType(): JSDocFunctionType | TypeReferenceNode { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + if (tryParse(nextTokenIsOpenParen)) { + const parameters = parseParameters(SignatureFlags.Type | SignatureFlags.JSDoc); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + return withJSDoc(finishNode(factory.createJSDocFunctionType(parameters, type), pos), hasJSDoc); + } + return finishNode(factory.createTypeReferenceNode(parseIdentifierName(), /*typeArguments*/ undefined), pos); + } + + function parseJSDocParameter(): ParameterDeclaration { + const pos = getNodePos(); + let name: Identifier | undefined; + if (token() === SyntaxKind.ThisKeyword || token() === SyntaxKind.NewKeyword) { + name = parseIdentifierName(); + parseExpected(SyntaxKind.ColonToken); + } + return finishNode( + factory.createParameterDeclaration( + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + // TODO(rbuckton): JSDoc parameters don't have names (except `this`/`new`), should we manufacture an empty identifier? + name!, + /*questionToken*/ undefined, + parseJSDocType(), + /*initializer*/ undefined, + ), + pos, + ); + } + + function parseJSDocType(): TypeNode { + scanner.setSkipJsDocLeadingAsterisks(true); + const pos = getNodePos(); + if (parseOptional(SyntaxKind.ModuleKeyword)) { + // TODO(rbuckton): We never set the type for a JSDocNamepathType. What should we put here? + const moduleTag = factory.createJSDocNamepathType(/*type*/ undefined!); + terminate: + while (true) { + switch (token()) { + case SyntaxKind.CloseBraceToken: + case SyntaxKind.EndOfFileToken: + case SyntaxKind.CommaToken: + case SyntaxKind.WhitespaceTrivia: + break terminate; + default: + nextTokenJSDoc(); + } + } + + scanner.setSkipJsDocLeadingAsterisks(false); + return finishNode(moduleTag, pos); + } + + const hasDotDotDot = parseOptional(SyntaxKind.DotDotDotToken); + let type = parseTypeOrTypePredicate(); + scanner.setSkipJsDocLeadingAsterisks(false); + if (hasDotDotDot) { + type = finishNode(factory.createJSDocVariadicType(type), pos); + } + if (token() === SyntaxKind.EqualsToken) { + nextToken(); + return finishNode(factory.createJSDocOptionalType(type), pos); + } + return type; + } + + function parseTypeQuery(): TypeQueryNode { + const pos = getNodePos(); + parseExpected(SyntaxKind.TypeOfKeyword); + const entityName = parseEntityName(/*allowReservedWords*/ true); + // Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression. + const typeArguments = !scanner.hasPrecedingLineBreak() ? tryParseTypeArguments() : undefined; + return finishNode(factory.createTypeQueryNode(entityName, typeArguments), pos); + } + + function parseTypeParameter(): TypeParameterDeclaration { + const pos = getNodePos(); + const modifiers = parseModifiers(/*allowDecorators*/ false, /*permitConstAsModifier*/ true); + const name = parseIdentifier(); + let constraint: TypeNode | undefined; + let expression: Expression | undefined; + if (parseOptional(SyntaxKind.ExtendsKeyword)) { + // It's not uncommon for people to write improper constraints to a generic. If the + // user writes a constraint that is an expression and not an actual type, then parse + // it out as an expression (so we can recover well), but report that a type is needed + // instead. + if (isStartOfType() || !isStartOfExpression()) { + constraint = parseType(); + } + else { + // It was not a type, and it looked like an expression. Parse out an expression + // here so we recover well. Note: it is important that we call parseUnaryExpression + // and not parseExpression here. If the user has: + // + // + // + // We do *not* want to consume the `>` as we're consuming the expression for "". + expression = parseUnaryExpressionOrHigher(); + } + } + + const defaultType = parseOptional(SyntaxKind.EqualsToken) ? parseType() : undefined; + const node = factory.createTypeParameterDeclaration(modifiers, name, constraint, defaultType); + node.expression = expression; + return finishNode(node, pos); + } + + function parseTypeParameters(): NodeArray | undefined { + if (token() === SyntaxKind.LessThanToken) { + return parseBracketedList(ParsingContext.TypeParameters, parseTypeParameter, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken); + } + } + + function isStartOfParameter(isJSDocParameter: boolean): boolean { + return token() === SyntaxKind.DotDotDotToken || + isBindingIdentifierOrPrivateIdentifierOrPattern() || + isModifierKind(token()) || + token() === SyntaxKind.AtToken || + isStartOfType(/*inStartOfParameter*/ !isJSDocParameter); + } + + function parseNameOfParameter(modifiers: NodeArray | undefined) { + // FormalParameter [Yield,Await]: + // BindingElement[?Yield,?Await] + const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_cannot_be_used_as_parameters); + if (getFullWidth(name) === 0 && !some(modifiers) && isModifierKind(token())) { + // in cases like + // 'use strict' + // function foo(static) + // isParameter('static') === true, because of isModifier('static') + // however 'static' is not a legal identifier in a strict mode. + // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined) + // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM) + // to avoid this we'll advance cursor to the next token. + nextToken(); + } + return name; + } + + function isParameterNameStart() { + // Be permissive about await and yield by calling isBindingIdentifier instead of isIdentifier; disallowing + // them during a speculative parse leads to many more follow-on errors than allowing the function to parse then later + // complaining about the use of the keywords. + return isBindingIdentifier() || token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken; + } + + function parseParameter(inOuterAwaitContext: boolean): ParameterDeclaration { + return parseParameterWorker(inOuterAwaitContext); + } + + function parseParameterForSpeculation(inOuterAwaitContext: boolean): ParameterDeclaration | undefined { + return parseParameterWorker(inOuterAwaitContext, /*allowAmbiguity*/ false); + } + + function parseParameterWorker(inOuterAwaitContext: boolean): ParameterDeclaration; + function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity: false): ParameterDeclaration | undefined; + function parseParameterWorker(inOuterAwaitContext: boolean, allowAmbiguity = true): ParameterDeclaration | undefined { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + + // FormalParameter [Yield,Await]: + // BindingElement[?Yield,?Await] + + // Decorators are parsed in the outer [Await] context, the rest of the parameter is parsed in the function's [Await] context. + const modifiers = inOuterAwaitContext ? + doInAwaitContext(() => parseModifiers(/*allowDecorators*/ true)) : + doOutsideOfAwaitContext(() => parseModifiers(/*allowDecorators*/ true)); + + if (token() === SyntaxKind.ThisKeyword) { + const node = factory.createParameterDeclaration( + modifiers, + /*dotDotDotToken*/ undefined, + createIdentifier(/*isIdentifier*/ true), + /*questionToken*/ undefined, + parseTypeAnnotation(), + /*initializer*/ undefined, + ); + + const modifier = firstOrUndefined(modifiers); + if (modifier) { + parseErrorAtRange(modifier, Diagnostics.Neither_decorators_nor_modifiers_may_be_applied_to_this_parameters); + } + + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + const savedTopLevel = topLevel; + topLevel = false; + + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + + if (!allowAmbiguity && !isParameterNameStart()) { + return undefined; + } + + const node = withJSDoc( + finishNode( + factory.createParameterDeclaration( + modifiers, + dotDotDotToken, + parseNameOfParameter(modifiers), + parseOptionalToken(SyntaxKind.QuestionToken), + parseTypeAnnotation(), + parseInitializer(), + ), + pos, + ), + hasJSDoc, + ); + topLevel = savedTopLevel; + return node; + } + + function parseReturnType(returnToken: SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode; + function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): TypeNode | undefined; + function parseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean) { + if (shouldParseReturnType(returnToken, isType)) { + return allowConditionalTypesAnd(parseTypeOrTypePredicate); + } + } + + function shouldParseReturnType(returnToken: SyntaxKind.ColonToken | SyntaxKind.EqualsGreaterThanToken, isType: boolean): boolean { + if (returnToken === SyntaxKind.EqualsGreaterThanToken) { + parseExpected(returnToken); + return true; + } + else if (parseOptional(SyntaxKind.ColonToken)) { + return true; + } + else if (isType && token() === SyntaxKind.EqualsGreaterThanToken) { + // This is easy to get backward, especially in type contexts, so parse the type anyway + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); + nextToken(); + return true; + } + return false; + } + + function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: true): NodeArray; + function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: false): NodeArray | undefined; + function parseParametersWorker(flags: SignatureFlags, allowAmbiguity: boolean): NodeArray | undefined { + // FormalParameters [Yield,Await]: (modified) + // [empty] + // FormalParameterList[?Yield,Await] + // + // FormalParameter[Yield,Await]: (modified) + // BindingElement[?Yield,Await] + // + // BindingElement [Yield,Await]: (modified) + // SingleNameBinding[?Yield,?Await] + // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + // + // SingleNameBinding [Yield,Await]: + // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + const savedYieldContext = inYieldContext(); + const savedAwaitContext = inAwaitContext(); + + setYieldContext(!!(flags & SignatureFlags.Yield)); + setAwaitContext(!!(flags & SignatureFlags.Await)); + + const parameters = flags & SignatureFlags.JSDoc ? + parseDelimitedList(ParsingContext.JSDocParameters, parseJSDocParameter) : + parseDelimitedList(ParsingContext.Parameters, () => allowAmbiguity ? parseParameter(savedAwaitContext) : parseParameterForSpeculation(savedAwaitContext)); + + setYieldContext(savedYieldContext); + setAwaitContext(savedAwaitContext); + + return parameters; + } + + function parseParameters(flags: SignatureFlags): NodeArray { + // FormalParameters [Yield,Await]: (modified) + // [empty] + // FormalParameterList[?Yield,Await] + // + // FormalParameter[Yield,Await]: (modified) + // BindingElement[?Yield,Await] + // + // BindingElement [Yield,Await]: (modified) + // SingleNameBinding[?Yield,?Await] + // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + // + // SingleNameBinding [Yield,Await]: + // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt + if (!parseExpected(SyntaxKind.OpenParenToken)) { + return createMissingList(); + } + + const parameters = parseParametersWorker(flags, /*allowAmbiguity*/ true); + parseExpected(SyntaxKind.CloseParenToken); + return parameters; + } + + function parseTypeMemberSemicolon() { + // We allow type members to be separated by commas or (possibly ASI) semicolons. + // First check if it was a comma. If so, we're done with the member. + if (parseOptional(SyntaxKind.CommaToken)) { + return; + } + + // Didn't have a comma. We must have a (possible ASI) semicolon. + parseSemicolon(); + } + + function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + if (kind === SyntaxKind.ConstructSignature) { + parseExpected(SyntaxKind.NewKeyword); + } + + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.Type); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); + parseTypeMemberSemicolon(); + const node = kind === SyntaxKind.CallSignature + ? factory.createCallSignature(typeParameters, parameters, type) + : factory.createConstructSignature(typeParameters, parameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function isIndexSignature(): boolean { + return token() === SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); + } + + function isUnambiguouslyIndexSignature() { + // The only allowed sequence is: + // + // [id: + // + // However, for error recovery, we also check the following cases: + // + // [... + // [id, + // [id?, + // [id?: + // [id?] + // [public id + // [private id + // [protected id + // [] + // + nextToken(); + if (token() === SyntaxKind.DotDotDotToken || token() === SyntaxKind.CloseBracketToken) { + return true; + } + + if (isModifierKind(token())) { + nextToken(); + if (isIdentifier()) { + return true; + } + } + else if (!isIdentifier()) { + return false; + } + else { + // Skip the identifier + nextToken(); + } + + // A colon signifies a well formed indexer + // A comma should be a badly formed indexer because comma expressions are not allowed + // in computed properties. + if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken) { + return true; + } + + // Question mark could be an indexer with an optional property, + // or it could be a conditional expression in a computed property. + if (token() !== SyntaxKind.QuestionToken) { + return false; + } + + // If any of the following tokens are after the question mark, it cannot + // be a conditional expression, so treat it as an indexer. + nextToken(); + return token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBracketToken; + } + + function parseIndexSignatureDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): IndexSignatureDeclaration { + const parameters = parseBracketedList(ParsingContext.Parameters, () => parseParameter(/*inOuterAwaitContext*/ false), SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); + const type = parseTypeAnnotation(); + parseTypeMemberSemicolon(); + const node = factory.createIndexSignature(modifiers, parameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parsePropertyOrMethodSignature(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): PropertySignature | MethodSignature { + const name = parsePropertyName(); + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + let node: PropertySignature | MethodSignature; + if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + // Method signatures don't exist in expression contexts. So they have neither + // [Yield] nor [Await] + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.Type); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ true); + node = factory.createMethodSignature(modifiers, name, questionToken, typeParameters, parameters, type); + } + else { + const type = parseTypeAnnotation(); + node = factory.createPropertySignature(modifiers, name, questionToken, type); + // Although type literal properties cannot not have initializers, we attempt + // to parse an initializer so we can report in the checker that an interface + // property or type literal property cannot have an initializer. + if (token() === SyntaxKind.EqualsToken) (node as Mutable).initializer = parseInitializer(); + } + parseTypeMemberSemicolon(); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function isTypeMemberStart(): boolean { + // Return true if we have the start of a signature member + if ( + token() === SyntaxKind.OpenParenToken || + token() === SyntaxKind.LessThanToken || + token() === SyntaxKind.GetKeyword || + token() === SyntaxKind.SetKeyword + ) { + return true; + } + let idToken = false; + // Eat up all modifiers, but hold on to the last one in case it is actually an identifier + while (isModifierKind(token())) { + idToken = true; + nextToken(); + } + // Index signatures and computed property names are type members + if (token() === SyntaxKind.OpenBracketToken) { + return true; + } + // Try to get the first property-like token following all modifiers + if (isLiteralPropertyName()) { + idToken = true; + nextToken(); + } + // If we were able to get any potential identifier, check that it is + // the start of a member declaration + if (idToken) { + return token() === SyntaxKind.OpenParenToken || + token() === SyntaxKind.LessThanToken || + token() === SyntaxKind.QuestionToken || + token() === SyntaxKind.ColonToken || + token() === SyntaxKind.CommaToken || + canParseSemicolon(); + } + return false; + } + + function parseTypeMember(): TypeElement { + if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + return parseSignatureMember(SyntaxKind.CallSignature); + } + if (token() === SyntaxKind.NewKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) { + return parseSignatureMember(SyntaxKind.ConstructSignature); + } + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiers(/*allowDecorators*/ false); + if (parseContextualModifier(SyntaxKind.GetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.GetAccessor, SignatureFlags.Type); + } + + if (parseContextualModifier(SyntaxKind.SetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.SetAccessor, SignatureFlags.Type); + } + + if (isIndexSignature()) { + return parseIndexSignatureDeclaration(pos, hasJSDoc, modifiers); + } + return parsePropertyOrMethodSignature(pos, hasJSDoc, modifiers); + } + + function nextTokenIsOpenParenOrLessThan() { + nextToken(); + return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken; + } + + function nextTokenIsDot() { + return nextToken() === SyntaxKind.DotToken; + } + + function nextTokenIsOpenParenOrLessThanOrDot() { + switch (nextToken()) { + case SyntaxKind.OpenParenToken: + case SyntaxKind.LessThanToken: + case SyntaxKind.DotToken: + return true; + } + return false; + } + + function parseTypeLiteral(): TypeLiteralNode { + const pos = getNodePos(); + return finishNode(factory.createTypeLiteralNode(parseObjectTypeMembers()), pos); + } + + function parseObjectTypeMembers(): NodeArray { + let members: NodeArray; + if (parseExpected(SyntaxKind.OpenBraceToken)) { + members = parseList(ParsingContext.TypeMembers, parseTypeMember); + parseExpected(SyntaxKind.CloseBraceToken); + } + else { + members = createMissingList(); + } + + return members; + } + + function isStartOfMappedType() { + nextToken(); + if (token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { + return nextToken() === SyntaxKind.ReadonlyKeyword; + } + if (token() === SyntaxKind.ReadonlyKeyword) { + nextToken(); + } + return token() === SyntaxKind.OpenBracketToken && nextTokenIsIdentifier() && nextToken() === SyntaxKind.InKeyword; + } + + function parseMappedTypeParameter() { + const pos = getNodePos(); + const name = parseIdentifierName(); + parseExpected(SyntaxKind.InKeyword); + const type = parseType(); + return finishNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, type, /*defaultType*/ undefined), pos); + } + + function parseMappedType() { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBraceToken); + let readonlyToken: ReadonlyKeyword | PlusToken | MinusToken | undefined; + if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { + readonlyToken = parseTokenNode(); + if (readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { + parseExpected(SyntaxKind.ReadonlyKeyword); + } + } + parseExpected(SyntaxKind.OpenBracketToken); + const typeParameter = parseMappedTypeParameter(); + const nameType = parseOptional(SyntaxKind.AsKeyword) ? parseType() : undefined; + parseExpected(SyntaxKind.CloseBracketToken); + let questionToken: QuestionToken | PlusToken | MinusToken | undefined; + if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { + questionToken = parseTokenNode(); + if (questionToken.kind !== SyntaxKind.QuestionToken) { + parseExpected(SyntaxKind.QuestionToken); + } + } + const type = parseTypeAnnotation(); + parseSemicolon(); + const members = parseList(ParsingContext.TypeMembers, parseTypeMember); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(factory.createMappedTypeNode(readonlyToken, typeParameter, nameType, questionToken, type, members), pos); + } + + function parseTupleElementType() { + const pos = getNodePos(); + if (parseOptional(SyntaxKind.DotDotDotToken)) { + return finishNode(factory.createRestTypeNode(parseType()), pos); + } + const type = parseType(); + if (isJSDocNullableType(type) && type.pos === type.type.pos) { + const node = factory.createOptionalTypeNode(type.type); + setTextRange(node, type); + (node as Mutable).flags = type.flags; + return node; + } + return type; + } + + function isNextTokenColonOrQuestionColon() { + return nextToken() === SyntaxKind.ColonToken || (token() === SyntaxKind.QuestionToken && nextToken() === SyntaxKind.ColonToken); + } + + function isTupleElementName() { + if (token() === SyntaxKind.DotDotDotToken) { + return tokenIsIdentifierOrKeyword(nextToken()) && isNextTokenColonOrQuestionColon(); + } + return tokenIsIdentifierOrKeyword(token()) && isNextTokenColonOrQuestionColon(); + } + + function parseTupleElementNameOrTupleElementType() { + if (lookAhead(isTupleElementName)) { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const name = parseIdentifierName(); + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + parseExpected(SyntaxKind.ColonToken); + const type = parseTupleElementType(); + const node = factory.createNamedTupleMember(dotDotDotToken, name, questionToken, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + return parseTupleElementType(); + } + + function parseTupleType(): TupleTypeNode { + const pos = getNodePos(); + return finishNode( + factory.createTupleTypeNode( + parseBracketedList(ParsingContext.TupleElementTypes, parseTupleElementNameOrTupleElementType, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken), + ), + pos, + ); + } + + function parseParenthesizedType(): TypeNode { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenParenToken); + const type = parseType(); + parseExpected(SyntaxKind.CloseParenToken); + return finishNode(factory.createParenthesizedType(type), pos); + } + + function parseModifiersForConstructorType(): NodeArray | undefined { + let modifiers: NodeArray | undefined; + if (token() === SyntaxKind.AbstractKeyword) { + const pos = getNodePos(); + nextToken(); + const modifier = finishNode(factoryCreateToken(SyntaxKind.AbstractKeyword), pos); + modifiers = createNodeArray([modifier], pos); + } + return modifiers; + } + + function parseFunctionOrConstructorType(): TypeNode { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiersForConstructorType(); + const isConstructorType = parseOptional(SyntaxKind.NewKeyword); + Debug.assert(!modifiers || isConstructorType, "Per isStartOfFunctionOrConstructorType, a function type cannot have modifiers."); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.Type); + const type = parseReturnType(SyntaxKind.EqualsGreaterThanToken, /*isType*/ false); + const node = isConstructorType + ? factory.createConstructorTypeNode(modifiers, typeParameters, parameters, type) + : factory.createFunctionTypeNode(typeParameters, parameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseKeywordAndNoDot(): TypeNode | undefined { + const node = parseTokenNode(); + return token() === SyntaxKind.DotToken ? undefined : node; + } + + function parseLiteralTypeNode(negative?: boolean): LiteralTypeNode { + const pos = getNodePos(); + if (negative) { + nextToken(); + } + let expression: BooleanLiteral | NullLiteral | LiteralExpression | PrefixUnaryExpression = token() === SyntaxKind.TrueKeyword || token() === SyntaxKind.FalseKeyword || token() === SyntaxKind.NullKeyword ? + parseTokenNode() : + parseLiteralLikeNode(token()) as LiteralExpression; + if (negative) { + expression = finishNode(factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, expression), pos); + } + return finishNode(factory.createLiteralTypeNode(expression), pos); + } + + function isStartOfTypeOfImportType() { + nextToken(); + return token() === SyntaxKind.ImportKeyword; + } + + function parseImportType(): ImportTypeNode { + sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; + const pos = getNodePos(); + const isTypeOf = parseOptional(SyntaxKind.TypeOfKeyword); + parseExpected(SyntaxKind.ImportKeyword); + parseExpected(SyntaxKind.OpenParenToken); + const type = parseType(); + let attributes: ImportAttributes | undefined; + if (parseOptional(SyntaxKind.CommaToken)) { + const openBracePosition = scanner.getTokenStart(); + parseExpected(SyntaxKind.OpenBraceToken); + const currentToken = token(); + if (currentToken === SyntaxKind.WithKeyword || currentToken === SyntaxKind.AssertKeyword) { + nextToken(); + } + else { + parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(SyntaxKind.WithKeyword)); + } + parseExpected(SyntaxKind.ColonToken); + attributes = parseImportAttributes(currentToken as SyntaxKind.WithKeyword | SyntaxKind.AssertKeyword, /*skipKeyword*/ true); + parseOptional(SyntaxKind.CommaToken); + if (!parseExpected(SyntaxKind.CloseBraceToken)) { + const lastError = lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === Diagnostics._0_expected.code) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, sourceText, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}"), + ); + } + } + } + parseExpected(SyntaxKind.CloseParenToken); + const qualifier = parseOptional(SyntaxKind.DotToken) ? parseEntityNameOfTypeReference() : undefined; + const typeArguments = parseTypeArgumentsOfTypeReference(); + return finishNode(factory.createImportTypeNode(type, attributes, qualifier, typeArguments, isTypeOf), pos); + } + + function nextTokenIsNumericOrBigIntLiteral() { + nextToken(); + return token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral; + } + + function parseNonArrayType(): TypeNode { + switch (token()) { + case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.BigIntKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.ObjectKeyword: + // If these are followed by a dot, then parse these out as a dotted type reference instead. + return tryParse(parseKeywordAndNoDot) || parseTypeReference(); + case SyntaxKind.AsteriskEqualsToken: + // If there is '*=', treat it as * followed by postfix = + scanner.reScanAsteriskEqualsToken(); + // falls through + case SyntaxKind.AsteriskToken: + return parseJSDocAllType(); + case SyntaxKind.QuestionQuestionToken: + // If there is '??', treat it as prefix-'?' in JSDoc type. + scanner.reScanQuestionToken(); + // falls through + case SyntaxKind.QuestionToken: + return parseJSDocUnknownOrNullableType(); + case SyntaxKind.FunctionKeyword: + return parseJSDocFunctionType(); + case SyntaxKind.ExclamationToken: + return parseJSDocNonNullableType(); + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + case SyntaxKind.BigIntLiteral: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + case SyntaxKind.NullKeyword: + return parseLiteralTypeNode(); + case SyntaxKind.MinusToken: + return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); + case SyntaxKind.VoidKeyword: + return parseTokenNode(); + case SyntaxKind.ThisKeyword: { + const thisKeyword = parseThisTypeNode(); + if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { + return parseThisTypePredicate(thisKeyword); + } + else { + return thisKeyword; + } + } + case SyntaxKind.TypeOfKeyword: + return lookAhead(isStartOfTypeOfImportType) ? parseImportType() : parseTypeQuery(); + case SyntaxKind.OpenBraceToken: + return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral(); + case SyntaxKind.OpenBracketToken: + return parseTupleType(); + case SyntaxKind.OpenParenToken: + return parseParenthesizedType(); + case SyntaxKind.ImportKeyword: + return parseImportType(); + case SyntaxKind.AssertsKeyword: + return lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine) ? parseAssertsTypePredicate() : parseTypeReference(); + case SyntaxKind.TemplateHead: + return parseTemplateType(); + default: + return parseTypeReference(); + } + } + + function isStartOfType(inStartOfParameter?: boolean): boolean { + switch (token()) { + case SyntaxKind.AnyKeyword: + case SyntaxKind.UnknownKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.BigIntKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.ReadonlyKeyword: + case SyntaxKind.SymbolKeyword: + case SyntaxKind.UniqueKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.ThisKeyword: + case SyntaxKind.TypeOfKeyword: + case SyntaxKind.NeverKeyword: + case SyntaxKind.OpenBraceToken: + case SyntaxKind.OpenBracketToken: + case SyntaxKind.LessThanToken: + case SyntaxKind.BarToken: + case SyntaxKind.AmpersandToken: + case SyntaxKind.NewKeyword: + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + case SyntaxKind.BigIntLiteral: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + case SyntaxKind.ObjectKeyword: + case SyntaxKind.AsteriskToken: + case SyntaxKind.QuestionToken: + case SyntaxKind.ExclamationToken: + case SyntaxKind.DotDotDotToken: + case SyntaxKind.InferKeyword: + case SyntaxKind.ImportKeyword: + case SyntaxKind.AssertsKeyword: + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + return true; + case SyntaxKind.FunctionKeyword: + return !inStartOfParameter; + case SyntaxKind.MinusToken: + return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral); + case SyntaxKind.OpenParenToken: + // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, + // or something that starts a type. We don't want to consider things like '(1)' a type. + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); + default: + return isIdentifier(); + } + } + + function isStartOfParenthesizedOrFunctionType() { + nextToken(); + return token() === SyntaxKind.CloseParenToken || isStartOfParameter(/*isJSDocParameter*/ false) || isStartOfType(); + } + + function parsePostfixTypeOrHigher(): TypeNode { + const pos = getNodePos(); + let type = parseNonArrayType(); + while (!scanner.hasPrecedingLineBreak()) { + switch (token()) { + case SyntaxKind.ExclamationToken: + nextToken(); + type = finishNode(factory.createJSDocNonNullableType(type, /*postfix*/ true), pos); + break; + case SyntaxKind.QuestionToken: + // If next token is start of a type we have a conditional type + if (lookAhead(nextTokenIsStartOfType)) { + return type; + } + nextToken(); + type = finishNode(factory.createJSDocNullableType(type, /*postfix*/ true), pos); + break; + case SyntaxKind.OpenBracketToken: + parseExpected(SyntaxKind.OpenBracketToken); + if (isStartOfType()) { + const indexType = parseType(); + parseExpected(SyntaxKind.CloseBracketToken); + type = finishNode(factory.createIndexedAccessTypeNode(type, indexType), pos); + } + else { + parseExpected(SyntaxKind.CloseBracketToken); + type = finishNode(factory.createArrayTypeNode(type), pos); + } + break; + default: + return type; + } + } + return type; + } + + function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) { + const pos = getNodePos(); + parseExpected(operator); + return finishNode(factory.createTypeOperatorNode(operator, parseTypeOperatorOrHigher()), pos); + } + + function tryParseConstraintOfInferType() { + if (parseOptional(SyntaxKind.ExtendsKeyword)) { + const constraint = disallowConditionalTypesAnd(parseType); + if (inDisallowConditionalTypesContext() || token() !== SyntaxKind.QuestionToken) { + return constraint; + } + } + } + + function parseTypeParameterOfInferType(): TypeParameterDeclaration { + const pos = getNodePos(); + const name = parseIdentifier(); + const constraint = tryParse(tryParseConstraintOfInferType); + const node = factory.createTypeParameterDeclaration(/*modifiers*/ undefined, name, constraint); + return finishNode(node, pos); + } + + function parseInferType(): InferTypeNode { + const pos = getNodePos(); + parseExpected(SyntaxKind.InferKeyword); + return finishNode(factory.createInferTypeNode(parseTypeParameterOfInferType()), pos); + } + + function parseTypeOperatorOrHigher(): TypeNode { + const operator = token(); + switch (operator) { + case SyntaxKind.KeyOfKeyword: + case SyntaxKind.UniqueKeyword: + case SyntaxKind.ReadonlyKeyword: + return parseTypeOperator(operator); + case SyntaxKind.InferKeyword: + return parseInferType(); + } + return allowConditionalTypesAnd(parsePostfixTypeOrHigher); + } + + function parseFunctionOrConstructorTypeToError( + isInUnionType: boolean, + ): TypeNode | undefined { + // the function type and constructor type shorthand notation + // are not allowed directly in unions and intersections, but we'll + // try to parse them gracefully and issue a helpful message. + if (isStartOfFunctionTypeOrConstructorType()) { + const type = parseFunctionOrConstructorType(); + let diagnostic: DiagnosticMessage; + if (isFunctionTypeNode(type)) { + diagnostic = isInUnionType + ? Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type + : Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; + } + else { + diagnostic = isInUnionType + ? Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type + : Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type; + } + parseErrorAtRange(type, diagnostic); + return type; + } + return undefined; + } + + function parseUnionOrIntersectionType( + operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken, + parseConstituentType: () => TypeNode, + createTypeNode: (types: NodeArray) => UnionOrIntersectionTypeNode, + ): TypeNode { + const pos = getNodePos(); + const isUnionType = operator === SyntaxKind.BarToken; + const hasLeadingOperator = parseOptional(operator); + let type = hasLeadingOperator && parseFunctionOrConstructorTypeToError(isUnionType) + || parseConstituentType(); + if (token() === operator || hasLeadingOperator) { + const types = [type]; + while (parseOptional(operator)) { + types.push(parseFunctionOrConstructorTypeToError(isUnionType) || parseConstituentType()); + } + type = finishNode(createTypeNode(createNodeArray(types, pos)), pos); + } + return type; + } + + function parseIntersectionTypeOrHigher(): TypeNode { + return parseUnionOrIntersectionType(SyntaxKind.AmpersandToken, parseTypeOperatorOrHigher, factory.createIntersectionTypeNode); + } + + function parseUnionTypeOrHigher(): TypeNode { + return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); + } + + function nextTokenIsNewKeyword(): boolean { + nextToken(); + return token() === SyntaxKind.NewKeyword; + } + + function isStartOfFunctionTypeOrConstructorType(): boolean { + if (token() === SyntaxKind.LessThanToken) { + return true; + } + if (token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) { + return true; + } + return token() === SyntaxKind.NewKeyword || + token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsNewKeyword); + } + + function skipParameterStart(): boolean { + if (isModifierKind(token())) { + // Skip modifiers + parseModifiers(/*allowDecorators*/ false); + } + if (isIdentifier() || token() === SyntaxKind.ThisKeyword) { + nextToken(); + return true; + } + if (token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.OpenBraceToken) { + // Return true if we can parse an array or object binding pattern with no errors + const previousErrorCount = parseDiagnostics.length; + parseIdentifierOrPattern(); + return previousErrorCount === parseDiagnostics.length; + } + return false; + } + + function isUnambiguouslyStartOfFunctionType() { + nextToken(); + if (token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.DotDotDotToken) { + // ( ) + // ( ... + return true; + } + if (skipParameterStart()) { + // We successfully skipped modifiers (if any) and an identifier or binding pattern, + // now see if we have something that indicates a parameter declaration + if ( + token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || + token() === SyntaxKind.QuestionToken || token() === SyntaxKind.EqualsToken + ) { + // ( xxx : + // ( xxx , + // ( xxx ? + // ( xxx = + return true; + } + if (token() === SyntaxKind.CloseParenToken) { + nextToken(); + if (token() === SyntaxKind.EqualsGreaterThanToken) { + // ( xxx ) => + return true; + } + } + } + return false; + } + + function parseTypeOrTypePredicate(): TypeNode { + const pos = getNodePos(); + const typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); + const type = parseType(); + if (typePredicateVariable) { + return finishNode(factory.createTypePredicateNode(/*assertsModifier*/ undefined, typePredicateVariable, type), pos); + } + else { + return type; + } + } + + function parseTypePredicatePrefix() { + const id = parseIdentifier(); + if (token() === SyntaxKind.IsKeyword && !scanner.hasPrecedingLineBreak()) { + nextToken(); + return id; + } + } + + function parseAssertsTypePredicate(): TypeNode { + const pos = getNodePos(); + const assertsModifier = parseExpectedToken(SyntaxKind.AssertsKeyword); + const parameterName = token() === SyntaxKind.ThisKeyword ? parseThisTypeNode() : parseIdentifier(); + const type = parseOptional(SyntaxKind.IsKeyword) ? parseType() : undefined; + return finishNode(factory.createTypePredicateNode(assertsModifier, parameterName, type), pos); + } + + function parseType(): TypeNode { + if (contextFlags & NodeFlags.TypeExcludesFlags) { + return doOutsideOfContext(NodeFlags.TypeExcludesFlags, parseType); + } + if (isStartOfFunctionTypeOrConstructorType()) { + return parseFunctionOrConstructorType(); + } + const pos = getNodePos(); + const type = parseUnionTypeOrHigher(); + if (!inDisallowConditionalTypesContext() && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.ExtendsKeyword)) { + // The type following 'extends' is not permitted to be another conditional type + const extendsType = disallowConditionalTypesAnd(parseType); + parseExpected(SyntaxKind.QuestionToken); + const trueType = allowConditionalTypesAnd(parseType); + parseExpected(SyntaxKind.ColonToken); + const falseType = allowConditionalTypesAnd(parseType); + return finishNode(factory.createConditionalTypeNode(type, extendsType, trueType, falseType), pos); + } + return type; + } + + function parseTypeAnnotation(): TypeNode | undefined { + return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined; + } + + // EXPRESSIONS + function isStartOfLeftHandSideExpression(): boolean { + switch (token()) { + case SyntaxKind.ThisKeyword: + case SyntaxKind.SuperKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + case SyntaxKind.NumericLiteral: + case SyntaxKind.BigIntLiteral: + case SyntaxKind.StringLiteral: + case SyntaxKind.NoSubstitutionTemplateLiteral: + case SyntaxKind.TemplateHead: + case SyntaxKind.OpenParenToken: + case SyntaxKind.OpenBracketToken: + case SyntaxKind.OpenBraceToken: + case SyntaxKind.FunctionKeyword: + case SyntaxKind.ClassKeyword: + case SyntaxKind.NewKeyword: + case SyntaxKind.SlashToken: + case SyntaxKind.SlashEqualsToken: + case SyntaxKind.Identifier: + return true; + case SyntaxKind.ImportKeyword: + return lookAhead(nextTokenIsOpenParenOrLessThanOrDot); + default: + return isIdentifier(); + } + } + + function isStartOfExpression(): boolean { + if (isStartOfLeftHandSideExpression()) { + return true; + } + + switch (token()) { + case SyntaxKind.PlusToken: + case SyntaxKind.MinusToken: + case SyntaxKind.TildeToken: + case SyntaxKind.ExclamationToken: + case SyntaxKind.DeleteKeyword: + case SyntaxKind.TypeOfKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.PlusPlusToken: + case SyntaxKind.MinusMinusToken: + case SyntaxKind.LessThanToken: + case SyntaxKind.AwaitKeyword: + case SyntaxKind.YieldKeyword: + case SyntaxKind.PrivateIdentifier: + case SyntaxKind.AtToken: + // Yield/await always starts an expression. Either it is an identifier (in which case + // it is definitely an expression). Or it's a keyword (either because we're in + // a generator or async function, or in strict mode (or both)) and it started a yield or await expression. + return true; + default: + // Error tolerance. If we see the start of some binary operator, we consider + // that the start of an expression. That way we'll parse out a missing identifier, + // give a good message about an identifier being missing, and then consume the + // rest of the binary expression. + if (isBinaryOperator()) { + return true; + } + + return isIdentifier(); + } + } + + function isStartOfExpressionStatement(): boolean { + // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. + return token() !== SyntaxKind.OpenBraceToken && + token() !== SyntaxKind.FunctionKeyword && + token() !== SyntaxKind.ClassKeyword && + token() !== SyntaxKind.AtToken && + isStartOfExpression(); + } + + function parseExpression(): Expression { + // Expression[in]: + // AssignmentExpression[in] + // Expression[in] , AssignmentExpression[in] + + // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator + const saveDecoratorContext = inDecoratorContext(); + if (saveDecoratorContext) { + setDecoratorContext(/*val*/ false); + } + + const pos = getNodePos(); + let expr = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); + let operatorToken: BinaryOperatorToken; + while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) { + expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true), pos); + } + + if (saveDecoratorContext) { + setDecoratorContext(/*val*/ true); + } + return expr; + } + + function parseInitializer(): Expression | undefined { + return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true) : undefined; + } + + function parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction: boolean): Expression { + // AssignmentExpression[in,yield]: + // 1) ConditionalExpression[?in,?yield] + // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] + // 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield] + // 4) ArrowFunctionExpression[?in,?yield] + // 5) AsyncArrowFunctionExpression[in,yield,await] + // 6) [+Yield] YieldExpression[?In] + // + // Note: for ease of implementation we treat productions '2' and '3' as the same thing. + // (i.e. they're both BinaryExpressions with an assignment operator in it). + + // First, do the simple check if we have a YieldExpression (production '6'). + if (isYieldExpression()) { + return parseYieldExpression(); + } + + // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized + // parameter list or is an async arrow function. + // AsyncArrowFunctionExpression: + // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] + // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] + // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression". + // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". + // + // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is + // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done + // with AssignmentExpression if we see one. + const arrowExpression = tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction) || tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction); + if (arrowExpression) { + return arrowExpression; + } + + // Now try to see if we're in production '1', '2' or '3'. A conditional expression can + // start with a LogicalOrExpression, while the assignment productions can only start with + // LeftHandSideExpressions. + // + // So, first, we try to just parse out a BinaryExpression. If we get something that is a + // LeftHandSide or higher, then we can try to parse out the assignment expression part. + // Otherwise, we try to parse out the conditional expression bit. We want to allow any + // binary expression here, so we pass in the 'lowest' precedence here so that it matches + // and consumes anything. + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); + + // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized + // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single + // identifier and the current token is an arrow. + if (expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { + return parseSimpleArrowFunctionExpression(pos, expr as Identifier, allowReturnTypeInArrowFunction, hasJSDoc, /*asyncModifier*/ undefined); + } + + // Now see if we might be in cases '2' or '3'. + // If the expression was a LHS expression, and we have an assignment operator, then + // we're in '2' or '3'. Consume the assignment and return. + // + // Note: we call reScanGreaterToken so that we get an appropriately merged token + // for cases like `> > =` becoming `>>=` + if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) { + return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction), pos); + } + + // It wasn't an assignment or a lambda. This is a conditional expression: + return parseConditionalExpressionRest(expr, pos, allowReturnTypeInArrowFunction); + } + + function isYieldExpression(): boolean { + if (token() === SyntaxKind.YieldKeyword) { + // If we have a 'yield' keyword, and this is a context where yield expressions are + // allowed, then definitely parse out a yield expression. + if (inYieldContext()) { + return true; + } + + // We're in a context where 'yield expr' is not allowed. However, if we can + // definitely tell that the user was trying to parse a 'yield expr' and not + // just a normal expr that start with a 'yield' identifier, then parse out + // a 'yield expr'. We can then report an error later that they are only + // allowed in generator expressions. + // + // for example, if we see 'yield(foo)', then we'll have to treat that as an + // invocation expression of something called 'yield'. However, if we have + // 'yield foo' then that is not legal as a normal expression, so we can + // definitely recognize this as a yield expression. + // + // for now we just check if the next token is an identifier. More heuristics + // can be added here later as necessary. We just need to make sure that we + // don't accidentally consume something legal. + return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); + } + + return false; + } + + function nextTokenIsIdentifierOnSameLine() { + nextToken(); + return !scanner.hasPrecedingLineBreak() && isIdentifier(); + } + + function parseYieldExpression(): YieldExpression { + const pos = getNodePos(); + + // YieldExpression[In] : + // yield + // yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] + // yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] + nextToken(); + + if ( + !scanner.hasPrecedingLineBreak() && + (token() === SyntaxKind.AsteriskToken || isStartOfExpression()) + ) { + return finishNode( + factory.createYieldExpression( + parseOptionalToken(SyntaxKind.AsteriskToken), + parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true), + ), + pos, + ); + } + else { + // if the next token is not on the same line as yield. or we don't have an '*' or + // the start of an expression, then this is just a simple "yield" expression. + return finishNode(factory.createYieldExpression(/*asteriskToken*/ undefined, /*expression*/ undefined), pos); + } + } + + function parseSimpleArrowFunctionExpression(pos: number, identifier: Identifier, allowReturnTypeInArrowFunction: boolean, hasJSDoc: boolean, asyncModifier?: NodeArray | undefined): ArrowFunction { + Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); + const parameter = factory.createParameterDeclaration( + /*modifiers*/ undefined, + /*dotDotDotToken*/ undefined, + identifier, + /*questionToken*/ undefined, + /*type*/ undefined, + /*initializer*/ undefined, + ); + finishNode(parameter, identifier.pos); + + const parameters = createNodeArray([parameter], parameter.pos, parameter.end); + const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); + const body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier, allowReturnTypeInArrowFunction); + const node = factory.createArrowFunction(asyncModifier, /*typeParameters*/ undefined, parameters, /*type*/ undefined, equalsGreaterThanToken, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function tryParseParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction: boolean): Expression | undefined { + const triState = isParenthesizedArrowFunctionExpression(); + if (triState === Tristate.False) { + // It's definitely not a parenthesized arrow function expression. + return undefined; + } + + // If we definitely have an arrow function, then we can just parse one, not requiring a + // following => or { token. Otherwise, we *might* have an arrow function. Try to parse + // it out, but don't allow any ambiguity, and return 'undefined' if this could be an + // expression instead. + return triState === Tristate.True ? + parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true, /*allowReturnTypeInArrowFunction*/ true) : + tryParse(() => parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction)); + } + + // True -> We definitely expect a parenthesized arrow function here. + // False -> There *cannot* be a parenthesized arrow function here. + // Unknown -> There *might* be a parenthesized arrow function here. + // Speculatively look ahead to be sure, and rollback if not. + function isParenthesizedArrowFunctionExpression(): Tristate { + if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken || token() === SyntaxKind.AsyncKeyword) { + return lookAhead(isParenthesizedArrowFunctionExpressionWorker); + } + + if (token() === SyntaxKind.EqualsGreaterThanToken) { + // ERROR RECOVERY TWEAK: + // If we see a standalone => try to parse it as an arrow function expression as that's + // likely what the user intended to write. + return Tristate.True; + } + // Definitely not a parenthesized arrow function. + return Tristate.False; + } + + function isParenthesizedArrowFunctionExpressionWorker() { + if (token() === SyntaxKind.AsyncKeyword) { + nextToken(); + if (scanner.hasPrecedingLineBreak()) { + return Tristate.False; + } + if (token() !== SyntaxKind.OpenParenToken && token() !== SyntaxKind.LessThanToken) { + return Tristate.False; + } + } + + const first = token(); + const second = nextToken(); + + if (first === SyntaxKind.OpenParenToken) { + if (second === SyntaxKind.CloseParenToken) { + // Simple cases: "() =>", "(): ", and "() {". + // This is an arrow function with no parameters. + // The last one is not actually an arrow function, + // but this is probably what the user intended. + const third = nextToken(); + switch (third) { + case SyntaxKind.EqualsGreaterThanToken: + case SyntaxKind.ColonToken: + case SyntaxKind.OpenBraceToken: + return Tristate.True; + default: + return Tristate.False; + } + } + + // If encounter "([" or "({", this could be the start of a binding pattern. + // Examples: + // ([ x ]) => { } + // ({ x }) => { } + // ([ x ]) + // ({ x }) + if (second === SyntaxKind.OpenBracketToken || second === SyntaxKind.OpenBraceToken) { + return Tristate.Unknown; + } + + // Simple case: "(..." + // This is an arrow function with a rest parameter. + if (second === SyntaxKind.DotDotDotToken) { + return Tristate.True; + } + + // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This + // isn't actually allowed, but we want to treat it as a lambda so we can provide + // a good error message. + if (isModifierKind(second) && second !== SyntaxKind.AsyncKeyword && lookAhead(nextTokenIsIdentifier)) { + if (nextToken() === SyntaxKind.AsKeyword) { + // https://github.com/microsoft/TypeScript/issues/44466 + return Tristate.False; + } + return Tristate.True; + } + + // If we had "(" followed by something that's not an identifier, + // then this definitely doesn't look like a lambda. "this" is not + // valid, but we want to parse it and then give a semantic error. + if (!isIdentifier() && second !== SyntaxKind.ThisKeyword) { + return Tristate.False; + } + + switch (nextToken()) { + case SyntaxKind.ColonToken: + // If we have something like "(a:", then we must have a + // type-annotated parameter in an arrow function expression. + return Tristate.True; + case SyntaxKind.QuestionToken: + nextToken(); + // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda. + if (token() === SyntaxKind.ColonToken || token() === SyntaxKind.CommaToken || token() === SyntaxKind.EqualsToken || token() === SyntaxKind.CloseParenToken) { + return Tristate.True; + } + // Otherwise it is definitely not a lambda. + return Tristate.False; + case SyntaxKind.CommaToken: + case SyntaxKind.EqualsToken: + case SyntaxKind.CloseParenToken: + // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function + return Tristate.Unknown; + } + // It is definitely not an arrow function + return Tristate.False; + } + else { + Debug.assert(first === SyntaxKind.LessThanToken); + + // If we have "<" not followed by an identifier, + // then this definitely is not an arrow function. + if (!isIdentifier() && token() !== SyntaxKind.ConstKeyword) { + return Tristate.False; + } + + // JSX overrides + if (languageVariant === LanguageVariant.JSX) { + const isArrowFunctionInJsx = lookAhead(() => { + parseOptional(SyntaxKind.ConstKeyword); + const third = nextToken(); + if (third === SyntaxKind.ExtendsKeyword) { + const fourth = nextToken(); + switch (fourth) { + case SyntaxKind.EqualsToken: + case SyntaxKind.GreaterThanToken: + case SyntaxKind.SlashToken: + return false; + default: + return true; + } + } + else if (third === SyntaxKind.CommaToken || third === SyntaxKind.EqualsToken) { + return true; + } + return false; + }); + + if (isArrowFunctionInJsx) { + return Tristate.True; + } + + return Tristate.False; + } + + // This *could* be a parenthesized arrow function. + return Tristate.Unknown; + } + } + + function parsePossibleParenthesizedArrowFunctionExpression(allowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined { + const tokenPos = scanner.getTokenStart(); + if (notParenthesizedArrow?.has(tokenPos)) { + return undefined; + } + + const result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false, allowReturnTypeInArrowFunction); + if (!result) { + (notParenthesizedArrow || (notParenthesizedArrow = new Set())).add(tokenPos); + } + + return result; + } + + function tryParseAsyncSimpleArrowFunctionExpression(allowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined { + // We do a check here so that we won't be doing unnecessarily call to "lookAhead" + if (token() === SyntaxKind.AsyncKeyword) { + if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const asyncModifier = parseModifiersForArrowFunction(); + const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); + return parseSimpleArrowFunctionExpression(pos, expr as Identifier, allowReturnTypeInArrowFunction, hasJSDoc, asyncModifier); + } + } + return undefined; + } + + function isUnParenthesizedAsyncArrowFunctionWorker(): Tristate { + // AsyncArrowFunctionExpression: + // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] + // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] + if (token() === SyntaxKind.AsyncKeyword) { + nextToken(); + // If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function + // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher" + if (scanner.hasPrecedingLineBreak() || token() === SyntaxKind.EqualsGreaterThanToken) { + return Tristate.False; + } + // Check for un-parenthesized AsyncArrowFunction + const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest); + if (!scanner.hasPrecedingLineBreak() && expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) { + return Tristate.True; + } + } + + return Tristate.False; + } + + function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean, allowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiersForArrowFunction(); + const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + // Arrow functions are never generators. + // + // If we're speculatively parsing a signature for a parenthesized arrow function, then + // we have to have a complete parameter list. Otherwise we might see something like + // a => (b => c) + // And think that "(b =>" was actually a parenthesized arrow function with a missing + // close paren. + const typeParameters = parseTypeParameters(); + + let parameters: NodeArray; + if (!parseExpected(SyntaxKind.OpenParenToken)) { + if (!allowAmbiguity) { + return undefined; + } + parameters = createMissingList(); + } + else { + if (!allowAmbiguity) { + const maybeParameters = parseParametersWorker(isAsync, allowAmbiguity); + if (!maybeParameters) { + return undefined; + } + parameters = maybeParameters; + } + else { + parameters = parseParametersWorker(isAsync, allowAmbiguity); + } + if (!parseExpected(SyntaxKind.CloseParenToken) && !allowAmbiguity) { + return undefined; + } + } + + const hasReturnColon = token() === SyntaxKind.ColonToken; + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) { + return undefined; + } + + // Parsing a signature isn't enough. + // Parenthesized arrow signatures often look like other valid expressions. + // For instance: + // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. + // - "(x,y)" is a comma expression parsed as a signature with two parameters. + // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. + // - "a ? (b): function() {}" will too, since function() is a valid JSDoc function type. + // - "a ? (b): (function() {})" as well, but inside of a parenthesized type with an arbitrary amount of nesting. + // + // So we need just a bit of lookahead to ensure that it can only be a signature. + + let unwrappedType = type; + while (unwrappedType?.kind === SyntaxKind.ParenthesizedType) { + unwrappedType = (unwrappedType as ParenthesizedTypeNode).type; // Skip parens if need be + } + + const hasJSDocFunctionType = unwrappedType && isJSDocFunctionType(unwrappedType); + if (!allowAmbiguity && token() !== SyntaxKind.EqualsGreaterThanToken && (hasJSDocFunctionType || token() !== SyntaxKind.OpenBraceToken)) { + // Returning undefined here will cause our caller to rewind to where we started from. + return undefined; + } + + // If we have an arrow, then try to parse the body. Even if not, try to parse if we + // have an opening brace, just in case we're in an error state. + const lastToken = token(); + const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); + const body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) + ? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier), allowReturnTypeInArrowFunction) + : parseIdentifier(); + + // Given: + // x ? y => ({ y }) : z => ({ z }) + // We try to parse the body of the first arrow function by looking at: + // ({ y }) : z => ({ z }) + // This is a valid arrow function with "z" as the return type. + // + // But, if we're in the true side of a conditional expression, this colon + // terminates the expression, so we cannot allow a return type if we aren't + // certain whether or not the preceding text was parsed as a parameter list. + // + // For example, + // a() ? (b: number, c?: string): void => d() : e + // is determined by isParenthesizedArrowFunctionExpression to unambiguously + // be an arrow expression, so we allow a return type. + if (!allowReturnTypeInArrowFunction && hasReturnColon) { + // However, if the arrow function we were able to parse is followed by another colon + // as in: + // a ? (x): string => x : null + // Then allow the arrow function, and treat the second colon as terminating + // the conditional expression. It's okay to do this because this code would + // be a syntax error in JavaScript (as the second colon shouldn't be there). + if (token() !== SyntaxKind.ColonToken) { + return undefined; + } + } + + const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseArrowFunctionExpressionBody(isAsync: boolean, allowReturnTypeInArrowFunction: boolean): Block | Expression { + if (token() === SyntaxKind.OpenBraceToken) { + return parseFunctionBlock(isAsync ? SignatureFlags.Await : SignatureFlags.None); + } + + if ( + token() !== SyntaxKind.SemicolonToken && + token() !== SyntaxKind.FunctionKeyword && + token() !== SyntaxKind.ClassKeyword && + isStartOfStatement() && + !isStartOfExpressionStatement() + ) { + // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) + // + // Here we try to recover from a potential error situation in the case where the + // user meant to supply a block. For example, if the user wrote: + // + // a => + // let v = 0; + // } + // + // they may be missing an open brace. Check to see if that's the case so we can + // try to recover better. If we don't do this, then the next close curly we see may end + // up preemptively closing the containing construct. + // + // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error. + return parseFunctionBlock(SignatureFlags.IgnoreMissingOpenBrace | (isAsync ? SignatureFlags.Await : SignatureFlags.None)); + } + + const savedYieldContext = inYieldContext(); + setYieldContext(false); + const savedTopLevel = topLevel; + topLevel = false; + const node = isAsync + ? doInAwaitContext(() => parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction)) + : doOutsideOfAwaitContext(() => parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction)); + topLevel = savedTopLevel; + setYieldContext(savedYieldContext); + return node; + } + + function parseConditionalExpressionRest(leftOperand: Expression, pos: number, allowReturnTypeInArrowFunction: boolean): Expression { + // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + if (!questionToken) { + return leftOperand; + } + + // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and + // we do not that for the 'whenFalse' part. + let colonToken; + return finishNode( + factory.createConditionalExpression( + leftOperand, + questionToken, + doOutsideOfContext(disallowInAndDecoratorContext, () => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ false)), + colonToken = parseExpectedToken(SyntaxKind.ColonToken), + nodeIsPresent(colonToken) + ? parseAssignmentExpressionOrHigher(allowReturnTypeInArrowFunction) + : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)), + ), + pos, + ); + } + + function parseBinaryExpressionOrHigher(precedence: OperatorPrecedence): Expression { + const pos = getNodePos(); + const leftOperand = parseUnaryExpressionOrHigher(); + return parseBinaryExpressionRest(precedence, leftOperand, pos); + } + + function isInOrOfKeyword(t: SyntaxKind) { + return t === SyntaxKind.InKeyword || t === SyntaxKind.OfKeyword; + } + + function parseBinaryExpressionRest(precedence: OperatorPrecedence, leftOperand: Expression, pos: number): Expression { + while (true) { + // We either have a binary operator here, or we're finished. We call + // reScanGreaterToken so that we merge token sequences like > and = into >= + + reScanGreaterToken(); + const newPrecedence = getBinaryOperatorPrecedence(token()); + + // Check the precedence to see if we should "take" this operator + // - For left associative operator (all operator but **), consume the operator, + // recursively call the function below, and parse binaryExpression as a rightOperand + // of the caller if the new precedence of the operator is greater then or equal to the current precedence. + // For example: + // a - b - c; + // ^token; leftOperand = b. Return b to the caller as a rightOperand + // a * b - c + // ^token; leftOperand = b. Return b to the caller as a rightOperand + // a - b * c; + // ^token; leftOperand = b. Return b * c to the caller as a rightOperand + // - For right associative operator (**), consume the operator, recursively call the function + // and parse binaryExpression as a rightOperand of the caller if the new precedence of + // the operator is strictly grater than the current precedence + // For example: + // a ** b ** c; + // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand + // a - b ** c; + // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand + // a ** b - c + // ^token; leftOperand = b. Return b to the caller as a rightOperand + const consumeCurrentOperator = token() === SyntaxKind.AsteriskAsteriskToken ? + newPrecedence >= precedence : + newPrecedence > precedence; + + if (!consumeCurrentOperator) { + break; + } + + if (token() === SyntaxKind.InKeyword && inDisallowInContext()) { + break; + } + + if (token() === SyntaxKind.AsKeyword || token() === SyntaxKind.SatisfiesKeyword) { + // Make sure we *do* perform ASI for constructs like this: + // var x = foo + // as (Bar) + // This should be parsed as an initialized variable, followed + // by a function call to 'as' with the argument 'Bar' + if (scanner.hasPrecedingLineBreak()) { + break; + } + else { + const keywordKind = token(); + nextToken(); + leftOperand = keywordKind === SyntaxKind.SatisfiesKeyword ? makeSatisfiesExpression(leftOperand, parseType()) : + makeAsExpression(leftOperand, parseType()); + } + } + else { + leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence), pos); + } + } + + return leftOperand; + } + + function isBinaryOperator() { + if (inDisallowInContext() && token() === SyntaxKind.InKeyword) { + return false; + } + + return getBinaryOperatorPrecedence(token()) > 0; + } + + function makeSatisfiesExpression(left: Expression, right: TypeNode): SatisfiesExpression { + return finishNode(factory.createSatisfiesExpression(left, right), left.pos); + } + + function makeBinaryExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression, pos: number): BinaryExpression { + return finishNode(factory.createBinaryExpression(left, operatorToken, right), pos); + } + + function makeAsExpression(left: Expression, right: TypeNode): AsExpression { + return finishNode(factory.createAsExpression(left, right), left.pos); + } + + function parsePrefixUnaryExpression() { + const pos = getNodePos(); + return finishNode(factory.createPrefixUnaryExpression(token() as PrefixUnaryOperator, nextTokenAnd(parseSimpleUnaryExpression)), pos); + } + + function parseDeleteExpression() { + const pos = getNodePos(); + return finishNode(factory.createDeleteExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); + } + + function parseTypeOfExpression() { + const pos = getNodePos(); + return finishNode(factory.createTypeOfExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); + } + + function parseVoidExpression() { + const pos = getNodePos(); + return finishNode(factory.createVoidExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); + } + + function isAwaitExpression(): boolean { + if (token() === SyntaxKind.AwaitKeyword) { + if (inAwaitContext()) { + return true; + } + + // here we are using similar heuristics as 'isYieldExpression' + return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); + } + + return false; + } + + function parseAwaitExpression() { + const pos = getNodePos(); + return finishNode(factory.createAwaitExpression(nextTokenAnd(parseSimpleUnaryExpression)), pos); + } + + /** + * Parse ES7 exponential expression and await expression + * + * ES7 ExponentiationExpression: + * 1) UnaryExpression[?Yield] + * 2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield] + */ + function parseUnaryExpressionOrHigher(): UnaryExpression | BinaryExpression { + /** + * ES7 UpdateExpression: + * 1) LeftHandSideExpression[?Yield] + * 2) LeftHandSideExpression[?Yield][no LineTerminator here]++ + * 3) LeftHandSideExpression[?Yield][no LineTerminator here]-- + * 4) ++UnaryExpression[?Yield] + * 5) --UnaryExpression[?Yield] + */ + if (isUpdateExpression()) { + const pos = getNodePos(); + const updateExpression = parseUpdateExpression(); + return token() === SyntaxKind.AsteriskAsteriskToken ? + parseBinaryExpressionRest(getBinaryOperatorPrecedence(token()), updateExpression, pos) as BinaryExpression : + updateExpression; + } + + /** + * ES7 UnaryExpression: + * 1) UpdateExpression[?yield] + * 2) delete UpdateExpression[?yield] + * 3) void UpdateExpression[?yield] + * 4) typeof UpdateExpression[?yield] + * 5) + UpdateExpression[?yield] + * 6) - UpdateExpression[?yield] + * 7) ~ UpdateExpression[?yield] + * 8) ! UpdateExpression[?yield] + */ + const unaryOperator = token(); + const simpleUnaryExpression = parseSimpleUnaryExpression(); + if (token() === SyntaxKind.AsteriskAsteriskToken) { + const pos = skipTrivia(sourceText, simpleUnaryExpression.pos); + const { end } = simpleUnaryExpression; + if (simpleUnaryExpression.kind === SyntaxKind.TypeAssertionExpression) { + parseErrorAt(pos, end, Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); + } + else { + Debug.assert(isKeywordOrPunctuation(unaryOperator)); + parseErrorAt(pos, end, Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, tokenToString(unaryOperator)); + } + } + return simpleUnaryExpression; + } + + /** + * Parse ES7 simple-unary expression or higher: + * + * ES7 UnaryExpression: + * 1) UpdateExpression[?yield] + * 2) delete UnaryExpression[?yield] + * 3) void UnaryExpression[?yield] + * 4) typeof UnaryExpression[?yield] + * 5) + UnaryExpression[?yield] + * 6) - UnaryExpression[?yield] + * 7) ~ UnaryExpression[?yield] + * 8) ! UnaryExpression[?yield] + * 9) [+Await] await UnaryExpression[?yield] + */ + function parseSimpleUnaryExpression(): UnaryExpression { + switch (token()) { + case SyntaxKind.PlusToken: + case SyntaxKind.MinusToken: + case SyntaxKind.TildeToken: + case SyntaxKind.ExclamationToken: + return parsePrefixUnaryExpression(); + case SyntaxKind.DeleteKeyword: + return parseDeleteExpression(); + case SyntaxKind.TypeOfKeyword: + return parseTypeOfExpression(); + case SyntaxKind.VoidKeyword: + return parseVoidExpression(); + case SyntaxKind.LessThanToken: + // Just like in parseUpdateExpression, we need to avoid parsing type assertions when + // in JSX and we see an expression like "+ bar". + if (languageVariant === LanguageVariant.JSX) { + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, /*topInvalidNodePosition*/ undefined, /*openingTag*/ undefined, /*mustBeUnary*/ true); + } + // This is modified UnaryExpression grammar in TypeScript + // UnaryExpression (modified): + // < type > UnaryExpression + return parseTypeAssertion(); + case SyntaxKind.AwaitKeyword: + if (isAwaitExpression()) { + return parseAwaitExpression(); + } + // falls through + default: + return parseUpdateExpression(); + } + } + + /** + * Check if the current token can possibly be an ES7 increment expression. + * + * ES7 UpdateExpression: + * LeftHandSideExpression[?Yield] + * LeftHandSideExpression[?Yield][no LineTerminator here]++ + * LeftHandSideExpression[?Yield][no LineTerminator here]-- + * ++LeftHandSideExpression[?Yield] + * --LeftHandSideExpression[?Yield] + */ + function isUpdateExpression(): boolean { + // This function is called inside parseUnaryExpression to decide + // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly + switch (token()) { + case SyntaxKind.PlusToken: + case SyntaxKind.MinusToken: + case SyntaxKind.TildeToken: + case SyntaxKind.ExclamationToken: + case SyntaxKind.DeleteKeyword: + case SyntaxKind.TypeOfKeyword: + case SyntaxKind.VoidKeyword: + case SyntaxKind.AwaitKeyword: + return false; + case SyntaxKind.LessThanToken: + // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression + if (languageVariant !== LanguageVariant.JSX) { + return false; + } + // We are in JSX context and the token is part of JSXElement. + // falls through + default: + return true; + } + } + + /** + * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression. + * + * ES7 UpdateExpression[yield]: + * 1) LeftHandSideExpression[?yield] + * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++ + * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]-- + * 4) ++LeftHandSideExpression[?yield] + * 5) --LeftHandSideExpression[?yield] + * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression + */ + function parseUpdateExpression(): UpdateExpression { + if (token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) { + const pos = getNodePos(); + return finishNode(factory.createPrefixUnaryExpression(token() as PrefixUnaryOperator, nextTokenAnd(parseLeftHandSideExpressionOrHigher)), pos); + } + else if (languageVariant === LanguageVariant.JSX && token() === SyntaxKind.LessThanToken && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { + // JSXElement is part of primaryExpression + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); + } + + const expression = parseLeftHandSideExpressionOrHigher(); + + Debug.assert(isLeftHandSideExpression(expression)); + if ((token() === SyntaxKind.PlusPlusToken || token() === SyntaxKind.MinusMinusToken) && !scanner.hasPrecedingLineBreak()) { + const operator = token() as PostfixUnaryOperator; + nextToken(); + return finishNode(factory.createPostfixUnaryExpression(expression, operator), expression.pos); + } + + return expression; + } + + function parseLeftHandSideExpressionOrHigher(): LeftHandSideExpression { + // Original Ecma: + // LeftHandSideExpression: See 11.2 + // NewExpression + // CallExpression + // + // Our simplification: + // + // LeftHandSideExpression: See 11.2 + // MemberExpression + // CallExpression + // + // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with + // MemberExpression to make our lives easier. + // + // to best understand the below code, it's important to see how CallExpression expands + // out into its own productions: + // + // CallExpression: + // MemberExpression Arguments + // CallExpression Arguments + // CallExpression[Expression] + // CallExpression.IdentifierName + // import (AssignmentExpression) + // super Arguments + // super.IdentifierName + // + // Because of the recursion in these calls, we need to bottom out first. There are three + // bottom out states we can run into: 1) We see 'super' which must start either of + // the last two CallExpression productions. 2) We see 'import' which must start import call. + // 3)we have a MemberExpression which either completes the LeftHandSideExpression, + // or starts the beginning of the first four CallExpression productions. + const pos = getNodePos(); + let expression: MemberExpression; + if (token() === SyntaxKind.ImportKeyword) { + if (lookAhead(nextTokenIsOpenParenOrLessThan)) { + // We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "(" + // For example: + // var foo3 = require("subfolder + // import * as foo1 from "module-from-node + // We want this import to be a statement rather than import call expression + sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; + expression = parseTokenNode(); + } + else if (lookAhead(nextTokenIsDot)) { + // This is an 'import.*' metaproperty (i.e. 'import.meta') + nextToken(); // advance past the 'import' + nextToken(); // advance past the dot + expression = finishNode(factory.createMetaProperty(SyntaxKind.ImportKeyword, parseIdentifierName()), pos); + + if ((expression as MetaProperty).name.escapedText === "defer") { + if (token() === SyntaxKind.QuestionDotToken && lookAhead(() => nextToken() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken)) { + parseErrorAtCurrentToken(Diagnostics.import_defer_does_not_support_optional_invocation); + } + if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + sourceFlags |= NodeFlags.PossiblyContainsDynamicImport; + } + } + else { + sourceFlags |= NodeFlags.PossiblyContainsImportMeta; + } + } + else { + expression = parseMemberExpressionOrHigher(); + } + } + else { + expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher(); + } + + // Now, we *may* be complete. However, we might have consumed the start of a + // CallExpression or OptionalExpression. As such, we need to consume the rest + // of it here to be complete. + return parseCallExpressionRest(pos, expression); + } + + function parseMemberExpressionOrHigher(): MemberExpression { + // Note: to make our lives simpler, we decompose the NewExpression productions and + // place ObjectCreationExpression and FunctionExpression into PrimaryExpression. + // like so: + // + // PrimaryExpression : See 11.1 + // this + // Identifier + // Literal + // ArrayLiteral + // ObjectLiteral + // (Expression) + // FunctionExpression + // new MemberExpression Arguments? + // + // MemberExpression : See 11.2 + // PrimaryExpression + // MemberExpression[Expression] + // MemberExpression.IdentifierName + // + // CallExpression : See 11.2 + // MemberExpression + // CallExpression Arguments + // CallExpression[Expression] + // CallExpression.IdentifierName + // + // Technically this is ambiguous. i.e. CallExpression defines: + // + // CallExpression: + // CallExpression Arguments + // + // If you see: "new Foo()" + // + // Then that could be treated as a single ObjectCreationExpression, or it could be + // treated as the invocation of "new Foo". We disambiguate that in code (to match + // the original grammar) by making sure that if we see an ObjectCreationExpression + // we always consume arguments if they are there. So we treat "new Foo()" as an + // object creation only, and not at all as an invocation. Another way to think + // about this is that for every "new" that we see, we will consume an argument list if + // it is there as part of the *associated* object creation node. Any additional + // argument lists we see, will become invocation expressions. + // + // Because there are no other places in the grammar now that refer to FunctionExpression + // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression + // production. + // + // Because CallExpression and MemberExpression are left recursive, we need to bottom out + // of the recursion immediately. So we parse out a primary expression to start with. + const pos = getNodePos(); + const expression = parsePrimaryExpression(); + return parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); + } + + function parseSuperExpression(): MemberExpression { + const pos = getNodePos(); + let expression = parseTokenNode(); + if (token() === SyntaxKind.LessThanToken) { + const startPos = getNodePos(); + const typeArguments = tryParse(parseTypeArgumentsInExpression); + if (typeArguments !== undefined) { + parseErrorAt(startPos, getNodePos(), Diagnostics.super_may_not_use_type_arguments); + if (!isTemplateStartOfTaggedTemplate()) { + expression = factory.createExpressionWithTypeArguments(expression, typeArguments); + } + } + } + + if (token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.DotToken || token() === SyntaxKind.OpenBracketToken) { + return expression; + } + + // If we have seen "super" it must be followed by '(' or '.'. + // If it wasn't then just try to parse out a '.' and report an error. + parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); + // private names will never work with `super` (`super.#foo`), but that's a semantic error, not syntactic + return finishNode(factoryCreatePropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true, /*allowUnicodeEscapeSequenceInIdentifierName*/ true)), pos); + } + + function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean, topInvalidNodePosition?: number, openingTag?: JsxOpeningElement | JsxOpeningFragment, mustBeUnary = false): JsxElement | JsxSelfClosingElement | JsxFragment { + const pos = getNodePos(); + const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); + let result: JsxElement | JsxSelfClosingElement | JsxFragment; + if (opening.kind === SyntaxKind.JsxOpeningElement) { + let children = parseJsxChildren(opening); + let closingElement: JsxClosingElement; + + const lastChild: JsxChild | undefined = children[children.length - 1]; + if ( + lastChild?.kind === SyntaxKind.JsxElement + && !tagNamesAreEquivalent(lastChild.openingElement.tagName, lastChild.closingElement.tagName) + && tagNamesAreEquivalent(opening.tagName, lastChild.closingElement.tagName) + ) { + // when an unclosed JsxOpeningElement incorrectly parses its parent's JsxClosingElement, + // restructure (
(......
)) --> (
(......)
) + // (no need to error; the parent will error) + const end = lastChild.children.end; + const newLast = finishNode( + factory.createJsxElement( + lastChild.openingElement, + lastChild.children, + finishNode(factory.createJsxClosingElement(finishNode(factoryCreateIdentifier(""), end, end)), end, end), + ), + lastChild.openingElement.pos, + end, + ); + + children = createNodeArray([...children.slice(0, children.length - 1), newLast], children.pos, end); + closingElement = lastChild.closingElement; + } + else { + closingElement = parseJsxClosingElement(opening, inExpressionContext); + if (!tagNamesAreEquivalent(opening.tagName, closingElement.tagName)) { + if (openingTag && isJsxOpeningElement(openingTag) && tagNamesAreEquivalent(closingElement.tagName, openingTag.tagName)) { + // opening incorrectly matched with its parent's closing -- put error on opening + parseErrorAtRange(opening.tagName, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + } + else { + // other opening/closing mismatches -- put error on closing + parseErrorAtRange(closingElement.tagName, Diagnostics.Expected_corresponding_JSX_closing_tag_for_0, getTextOfNodeFromSourceText(sourceText, opening.tagName)); + } + } + } + result = finishNode(factory.createJsxElement(opening, children, closingElement), pos); + } + else if (opening.kind === SyntaxKind.JsxOpeningFragment) { + result = finishNode(factory.createJsxFragment(opening, parseJsxChildren(opening), parseJsxClosingFragment(inExpressionContext)), pos); + } + else { + Debug.assert(opening.kind === SyntaxKind.JsxSelfClosingElement); + // Nothing else to do for self-closing elements + result = opening; + } + + // If the user writes the invalid code '
' in an expression context (i.e. not wrapped in + // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag + // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX + // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter + // does less damage and we can report a better error. + // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios + // of one sort or another. + // If we are in a unary context, we can't do this recovery; the binary expression we return here is not + // a valid UnaryExpression and will cause problems later. + if (!mustBeUnary && inExpressionContext && token() === SyntaxKind.LessThanToken) { + const topBadPos = typeof topInvalidNodePosition === "undefined" ? result.pos : topInvalidNodePosition; + const invalidElement = tryParse(() => parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true, topBadPos)); + if (invalidElement) { + const operatorToken = createMissingNode(SyntaxKind.CommaToken, /*reportAtCurrentPosition*/ false); + setTextRangePosWidth(operatorToken, invalidElement.pos, 0); + parseErrorAt(skipTrivia(sourceText, topBadPos), invalidElement.end, Diagnostics.JSX_expressions_must_have_one_parent_element); + return finishNode(factory.createBinaryExpression(result, operatorToken as Token, invalidElement), pos) as Node as JsxElement; + } + } + + return result; + } + + function parseJsxText(): JsxText { + const pos = getNodePos(); + const node = factory.createJsxText(scanner.getTokenValue(), currentToken === SyntaxKind.JsxTextAllWhiteSpaces); + currentToken = scanner.scanJsxToken(); + return finishNode(node, pos); + } + + function parseJsxChild(openingTag: JsxOpeningElement | JsxOpeningFragment, token: JsxTokenSyntaxKind): JsxChild | undefined { + switch (token) { + case SyntaxKind.EndOfFileToken: + // If we hit EOF, issue the error at the tag that lacks the closing element + // rather than at the end of the file (which is useless) + if (isJsxOpeningFragment(openingTag)) { + parseErrorAtRange(openingTag, Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); + } + else { + // We want the error span to cover only 'Foo.Bar' in < Foo.Bar > + // or to cover only 'Foo' in < Foo > + const tag = openingTag.tagName; + const start = Math.min(skipTrivia(sourceText, tag.pos), tag.end); + parseErrorAt(start, tag.end, Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, getTextOfNodeFromSourceText(sourceText, openingTag.tagName)); + } + return undefined; + case SyntaxKind.LessThanSlashToken: + case SyntaxKind.ConflictMarkerTrivia: + return undefined; + case SyntaxKind.JsxText: + case SyntaxKind.JsxTextAllWhiteSpaces: + return parseJsxText(); + case SyntaxKind.OpenBraceToken: + return parseJsxExpression(/*inExpressionContext*/ false); + case SyntaxKind.LessThanToken: + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false, /*topInvalidNodePosition*/ undefined, openingTag); + default: + return Debug.assertNever(token); + } + } + + function parseJsxChildren(openingTag: JsxOpeningElement | JsxOpeningFragment): NodeArray { + const list = []; + const listPos = getNodePos(); + const saveParsingContext = parsingContext; + parsingContext |= 1 << ParsingContext.JsxChildren; + + while (true) { + const child = parseJsxChild(openingTag, currentToken = scanner.reScanJsxToken()); + if (!child) break; + list.push(child); + if ( + isJsxOpeningElement(openingTag) + && child?.kind === SyntaxKind.JsxElement + && !tagNamesAreEquivalent(child.openingElement.tagName, child.closingElement.tagName) + && tagNamesAreEquivalent(openingTag.tagName, child.closingElement.tagName) + ) { + // stop after parsing a mismatched child like
...(
) in order to reattach the higher + break; + } + } + + parsingContext = saveParsingContext; + return createNodeArray(list, listPos); + } + + function parseJsxAttributes(): JsxAttributes { + const pos = getNodePos(); + return finishNode(factory.createJsxAttributes(parseList(ParsingContext.JsxAttributes, parseJsxAttribute)), pos); + } + + function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement | JsxOpeningFragment { + const pos = getNodePos(); + + parseExpected(SyntaxKind.LessThanToken); + + if (token() === SyntaxKind.GreaterThanToken) { + // See below for explanation of scanJsxText + scanJsxText(); + return finishNode(factory.createJsxOpeningFragment(), pos); + } + const tagName = parseJsxElementName(); + const typeArguments = (contextFlags & NodeFlags.JavaScriptFile) === 0 ? tryParseTypeArguments() : undefined; + const attributes = parseJsxAttributes(); + + let node: JsxOpeningLikeElement; + + if (token() === SyntaxKind.GreaterThanToken) { + // Closing tag, so scan the immediately-following text with the JSX scanning instead + // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate + // scanning errors + scanJsxText(); + node = factory.createJsxOpeningElement(tagName, typeArguments, attributes); + } + else { + parseExpected(SyntaxKind.SlashToken); + if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnosticMessage*/ undefined, /*shouldAdvance*/ false)) { + // manually advance the scanner in order to look for jsx text inside jsx + if (inExpressionContext) { + nextToken(); + } + else { + scanJsxText(); + } + } + node = factory.createJsxSelfClosingElement(tagName, typeArguments, attributes); + } + + return finishNode(node, pos); + } + + function parseJsxElementName(): JsxTagNameExpression { + const pos = getNodePos(); + // JsxElement can have name in the form of + // propertyAccessExpression + // primaryExpression in the form of an identifier and "this" keyword + // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword + // We only want to consider "this" as a primaryExpression + const initialExpression = parseJsxTagName(); + if (isJsxNamespacedName(initialExpression)) { + return initialExpression; // `a:b.c` is invalid syntax, don't even look for the `.` if we parse `a:b`, and let `parseAttribute` report "unexpected :" instead. + } + let expression: PropertyAccessExpression | Identifier | ThisExpression = initialExpression; + while (parseOptional(SyntaxKind.DotToken)) { + expression = finishNode(factoryCreatePropertyAccessExpression(expression, parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ false, /*allowUnicodeEscapeSequenceInIdentifierName*/ false)), pos); + } + return expression as JsxTagNameExpression; + } + + function parseJsxTagName(): Identifier | JsxNamespacedName | ThisExpression { + const pos = getNodePos(); + scanJsxIdentifier(); + + const isThis = token() === SyntaxKind.ThisKeyword; + const tagName = parseIdentifierNameErrorOnUnicodeEscapeSequence(); + if (parseOptional(SyntaxKind.ColonToken)) { + scanJsxIdentifier(); + return finishNode(factory.createJsxNamespacedName(tagName, parseIdentifierNameErrorOnUnicodeEscapeSequence()), pos); + } + return isThis ? finishNode(factory.createToken(SyntaxKind.ThisKeyword), pos) : tagName; + } + + function parseJsxExpression(inExpressionContext: boolean): JsxExpression | undefined { + const pos = getNodePos(); + if (!parseExpected(SyntaxKind.OpenBraceToken)) { + return undefined; + } + + let dotDotDotToken: DotDotDotToken | undefined; + let expression: Expression | undefined; + if (token() !== SyntaxKind.CloseBraceToken) { + if (!inExpressionContext) { + dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + } + // Only an AssignmentExpression is valid here per the JSX spec, + // but we can unambiguously parse a comma sequence and provide + // a better error message in grammar checking. + expression = parseExpression(); + } + if (inExpressionContext) { + parseExpected(SyntaxKind.CloseBraceToken); + } + else { + if (parseExpected(SyntaxKind.CloseBraceToken, /*diagnosticMessage*/ undefined, /*shouldAdvance*/ false)) { + scanJsxText(); + } + } + + return finishNode(factory.createJsxExpression(dotDotDotToken, expression), pos); + } + + function parseJsxAttribute(): JsxAttribute | JsxSpreadAttribute { + if (token() === SyntaxKind.OpenBraceToken) { + return parseJsxSpreadAttribute(); + } + + const pos = getNodePos(); + return finishNode(factory.createJsxAttribute(parseJsxAttributeName(), parseJsxAttributeValue()), pos); + } + + function parseJsxAttributeValue(): JsxAttributeValue | undefined { + if (token() === SyntaxKind.EqualsToken) { + if (scanJsxAttributeValue() === SyntaxKind.StringLiteral) { + return parseLiteralNode() as StringLiteral; + } + if (token() === SyntaxKind.OpenBraceToken) { + return parseJsxExpression(/*inExpressionContext*/ true); + } + if (token() === SyntaxKind.LessThanToken) { + return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); + } + parseErrorAtCurrentToken(Diagnostics.or_JSX_element_expected); + } + return undefined; + } + + function parseJsxAttributeName() { + const pos = getNodePos(); + scanJsxIdentifier(); + + const attrName = parseIdentifierNameErrorOnUnicodeEscapeSequence(); + if (parseOptional(SyntaxKind.ColonToken)) { + scanJsxIdentifier(); + return finishNode(factory.createJsxNamespacedName(attrName, parseIdentifierNameErrorOnUnicodeEscapeSequence()), pos); + } + return attrName; + } + + function parseJsxSpreadAttribute(): JsxSpreadAttribute { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBraceToken); + parseExpected(SyntaxKind.DotDotDotToken); + const expression = parseExpression(); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(factory.createJsxSpreadAttribute(expression), pos); + } + + function parseJsxClosingElement(open: JsxOpeningElement, inExpressionContext: boolean): JsxClosingElement { + const pos = getNodePos(); + parseExpected(SyntaxKind.LessThanSlashToken); + const tagName = parseJsxElementName(); + if (parseExpected(SyntaxKind.GreaterThanToken, /*diagnosticMessage*/ undefined, /*shouldAdvance*/ false)) { + // manually advance the scanner in order to look for jsx text inside jsx + if (inExpressionContext || !tagNamesAreEquivalent(open.tagName, tagName)) { + nextToken(); + } + else { + scanJsxText(); + } + } + return finishNode(factory.createJsxClosingElement(tagName), pos); + } + + function parseJsxClosingFragment(inExpressionContext: boolean): JsxClosingFragment { + const pos = getNodePos(); + parseExpected(SyntaxKind.LessThanSlashToken); + if (parseExpected(SyntaxKind.GreaterThanToken, Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment, /*shouldAdvance*/ false)) { + // manually advance the scanner in order to look for jsx text inside jsx + if (inExpressionContext) { + nextToken(); + } + else { + scanJsxText(); + } + } + return finishNode(factory.createJsxJsxClosingFragment(), pos); + } + + function parseTypeAssertion(): TypeAssertion { + Debug.assert(languageVariant !== LanguageVariant.JSX, "Type assertions should never be parsed in JSX; they should be parsed as comparisons or JSX elements/fragments."); + const pos = getNodePos(); + parseExpected(SyntaxKind.LessThanToken); + const type = parseType(); + parseExpected(SyntaxKind.GreaterThanToken); + const expression = parseSimpleUnaryExpression(); + return finishNode(factory.createTypeAssertion(type, expression), pos); + } + + function nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate() { + nextToken(); + return tokenIsIdentifierOrKeyword(token()) + || token() === SyntaxKind.OpenBracketToken + || isTemplateStartOfTaggedTemplate(); + } + + function isStartOfOptionalPropertyOrElementAccessChain() { + return token() === SyntaxKind.QuestionDotToken + && lookAhead(nextTokenIsIdentifierOrKeywordOrOpenBracketOrTemplate); + } + + function tryReparseOptionalChain(node: Expression) { + if (node.flags & NodeFlags.OptionalChain) { + return true; + } + // check for an optional chain in a non-null expression + if (isNonNullExpression(node)) { + let expr = node.expression; + while (isNonNullExpression(expr) && !(expr.flags & NodeFlags.OptionalChain)) { + expr = expr.expression; + } + if (expr.flags & NodeFlags.OptionalChain) { + // this is part of an optional chain. Walk down from `node` to `expression` and set the flag. + while (isNonNullExpression(node)) { + (node as Mutable).flags |= NodeFlags.OptionalChain; + node = node.expression; + } + return true; + } + } + return false; + } + + function parsePropertyAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { + const name = parseRightSideOfDot(/*allowIdentifierNames*/ true, /*allowPrivateIdentifiers*/ true, /*allowUnicodeEscapeSequenceInIdentifierName*/ true); + const isOptionalChain = questionDotToken || tryReparseOptionalChain(expression); + const propertyAccess = isOptionalChain ? + factoryCreatePropertyAccessChain(expression, questionDotToken, name) : + factoryCreatePropertyAccessExpression(expression, name); + if (isOptionalChain && isPrivateIdentifier(propertyAccess.name)) { + parseErrorAtRange(propertyAccess.name, Diagnostics.An_optional_chain_cannot_contain_private_identifiers); + } + if (isExpressionWithTypeArguments(expression) && expression.typeArguments) { + const pos = expression.typeArguments.pos - 1; + const end = skipTrivia(sourceText, expression.typeArguments.end) + 1; + parseErrorAt(pos, end, Diagnostics.An_instantiation_expression_cannot_be_followed_by_a_property_access); + } + return finishNode(propertyAccess, pos); + } + + function parseElementAccessExpressionRest(pos: number, expression: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined) { + let argumentExpression: Expression; + if (token() === SyntaxKind.CloseBracketToken) { + argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument); + } + else { + const argument = allowInAnd(parseExpression); + if (isStringOrNumericLiteralLike(argument)) { + argument.text = internIdentifier(argument.text); + } + argumentExpression = argument; + } + + parseExpected(SyntaxKind.CloseBracketToken); + + const indexedAccess = questionDotToken || tryReparseOptionalChain(expression) ? + factoryCreateElementAccessChain(expression, questionDotToken, argumentExpression) : + factoryCreateElementAccessExpression(expression, argumentExpression); + return finishNode(indexedAccess, pos); + } + + function parseMemberExpressionRest(pos: number, expression: LeftHandSideExpression, allowOptionalChain: boolean): MemberExpression { + while (true) { + let questionDotToken: QuestionDotToken | undefined; + let isPropertyAccess = false; + if (allowOptionalChain && isStartOfOptionalPropertyOrElementAccessChain()) { + questionDotToken = parseExpectedToken(SyntaxKind.QuestionDotToken); + isPropertyAccess = tokenIsIdentifierOrKeyword(token()); + } + else { + isPropertyAccess = parseOptional(SyntaxKind.DotToken); + } + + if (isPropertyAccess) { + expression = parsePropertyAccessExpressionRest(pos, expression, questionDotToken); + continue; + } + + // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName + if ((questionDotToken || !inDecoratorContext()) && parseOptional(SyntaxKind.OpenBracketToken)) { + expression = parseElementAccessExpressionRest(pos, expression, questionDotToken); + continue; + } + + if (isTemplateStartOfTaggedTemplate()) { + // Absorb type arguments into TemplateExpression when preceding expression is ExpressionWithTypeArguments + expression = !questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments ? + parseTaggedTemplateRest(pos, (expression as ExpressionWithTypeArguments).expression, questionDotToken, (expression as ExpressionWithTypeArguments).typeArguments) : + parseTaggedTemplateRest(pos, expression, questionDotToken, /*typeArguments*/ undefined); + continue; + } + + if (!questionDotToken) { + if (token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { + nextToken(); + expression = finishNode(factory.createNonNullExpression(expression), pos); + continue; + } + const typeArguments = tryParse(parseTypeArgumentsInExpression); + if (typeArguments) { + expression = finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); + continue; + } + } + + return expression as MemberExpression; + } + } + + function isTemplateStartOfTaggedTemplate() { + return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead; + } + + function parseTaggedTemplateRest(pos: number, tag: LeftHandSideExpression, questionDotToken: QuestionDotToken | undefined, typeArguments: NodeArray | undefined) { + const tagExpression = factory.createTaggedTemplateExpression( + tag, + typeArguments, + token() === SyntaxKind.NoSubstitutionTemplateLiteral ? + (reScanTemplateToken(/*isTaggedTemplate*/ true), parseLiteralNode() as NoSubstitutionTemplateLiteral) : + parseTemplateExpression(/*isTaggedTemplate*/ true), + ); + if (questionDotToken || tag.flags & NodeFlags.OptionalChain) { + (tagExpression as Mutable).flags |= NodeFlags.OptionalChain; + } + tagExpression.questionDotToken = questionDotToken; + return finishNode(tagExpression, pos); + } + + function parseCallExpressionRest(pos: number, expression: LeftHandSideExpression): LeftHandSideExpression { + while (true) { + expression = parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); + let typeArguments: NodeArray | undefined; + const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken); + if (questionDotToken) { + typeArguments = tryParse(parseTypeArgumentsInExpression); + if (isTemplateStartOfTaggedTemplate()) { + expression = parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments); + continue; + } + } + if (typeArguments || token() === SyntaxKind.OpenParenToken) { + // Absorb type arguments into CallExpression when preceding expression is ExpressionWithTypeArguments + if (!questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments) { + typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; + expression = (expression as ExpressionWithTypeArguments).expression; + } + const argumentList = parseArgumentList(); + const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? + factoryCreateCallChain(expression, questionDotToken, typeArguments, argumentList) : + factoryCreateCallExpression(expression, typeArguments, argumentList); + expression = finishNode(callExpr, pos); + continue; + } + if (questionDotToken) { + // We parsed `?.` but then failed to parse anything, so report a missing identifier here. + const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected); + expression = finishNode(factoryCreatePropertyAccessChain(expression, questionDotToken, name), pos); + } + break; + } + return expression; + } + + function parseArgumentList() { + parseExpected(SyntaxKind.OpenParenToken); + const result = parseDelimitedList(ParsingContext.ArgumentExpressions, parseArgumentExpression); + parseExpected(SyntaxKind.CloseParenToken); + return result; + } + + function parseTypeArgumentsInExpression() { + if ((contextFlags & NodeFlags.JavaScriptFile) !== 0) { + // TypeArguments must not be parsed in JavaScript files to avoid ambiguity with binary operators. + return undefined; + } + + if (reScanLessThanToken() !== SyntaxKind.LessThanToken) { + return undefined; + } + nextToken(); + + const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType); + if (reScanGreaterToken() !== SyntaxKind.GreaterThanToken) { + // If it doesn't have the closing `>` then it's definitely not an type argument list. + return undefined; + } + nextToken(); + + // We successfully parsed a type argument list. The next token determines whether we want to + // treat it as such. If the type argument list is followed by `(` or a template literal, as in + // `f(42)`, we favor the type argument interpretation even though JavaScript would view + // it as a relational expression. + return typeArguments && canFollowTypeArgumentsInExpression() ? typeArguments : undefined; + } + + function canFollowTypeArgumentsInExpression(): boolean { + switch (token()) { + // These tokens can follow a type argument list in a call expression. + case SyntaxKind.OpenParenToken: // foo( + case SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` + case SyntaxKind.TemplateHead: // foo `...${100}...` + return true; + // A type argument list followed by `<` never makes sense, and a type argument list followed + // by `>` is ambiguous with a (re-scanned) `>>` operator, so we disqualify both. Also, in + // this context, `+` and `-` are unary operators, not binary operators. + case SyntaxKind.LessThanToken: + case SyntaxKind.GreaterThanToken: + case SyntaxKind.PlusToken: + case SyntaxKind.MinusToken: + return false; + } + // We favor the type argument list interpretation when it is immediately followed by + // a line break, a binary operator, or something that can't start an expression. + return scanner.hasPrecedingLineBreak() || isBinaryOperator() || !isStartOfExpression(); + } + + function parsePrimaryExpression(): PrimaryExpression { + switch (token()) { + case SyntaxKind.NoSubstitutionTemplateLiteral: + if (scanner.getTokenFlags() & TokenFlags.IsInvalid) { + reScanTemplateToken(/*isTaggedTemplate*/ false); + } + // falls through + case SyntaxKind.NumericLiteral: + case SyntaxKind.BigIntLiteral: + case SyntaxKind.StringLiteral: + return parseLiteralNode(); + case SyntaxKind.ThisKeyword: + case SyntaxKind.SuperKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: + return parseTokenNode(); + case SyntaxKind.OpenParenToken: + return parseParenthesizedExpression(); + case SyntaxKind.OpenBracketToken: + return parseArrayLiteralExpression(); + case SyntaxKind.OpenBraceToken: + return parseObjectLiteralExpression(); + case SyntaxKind.AsyncKeyword: + // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher. + // If we encounter `async [no LineTerminator here] function` then this is an async + // function; otherwise, its an identifier. + if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) { + break; + } + + return parseFunctionExpression(); + case SyntaxKind.AtToken: + return parseDecoratedExpression(); + case SyntaxKind.ClassKeyword: + return parseClassExpression(); + case SyntaxKind.FunctionKeyword: + return parseFunctionExpression(); + case SyntaxKind.NewKeyword: + return parseNewExpressionOrNewDotTarget(); + case SyntaxKind.SlashToken: + case SyntaxKind.SlashEqualsToken: + if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) { + return parseLiteralNode(); + } + break; + case SyntaxKind.TemplateHead: + return parseTemplateExpression(/*isTaggedTemplate*/ false); + case SyntaxKind.PrivateIdentifier: + return parsePrivateIdentifier(); + } + + return parseIdentifier(Diagnostics.Expression_expected); + } + + function parseParenthesizedExpression(): ParenthesizedExpression { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.OpenParenToken); + const expression = allowInAnd(parseExpression); + parseExpected(SyntaxKind.CloseParenToken); + return withJSDoc(finishNode(factoryCreateParenthesizedExpression(expression), pos), hasJSDoc); + } + + function parseSpreadElement(): Expression { + const pos = getNodePos(); + parseExpected(SyntaxKind.DotDotDotToken); + const expression = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); + return finishNode(factory.createSpreadElement(expression), pos); + } + + function parseArgumentOrArrayLiteralElement(): Expression { + return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() : + token() === SyntaxKind.CommaToken ? finishNode(factory.createOmittedExpression(), getNodePos()) : + parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); + } + + function parseArgumentExpression(): Expression { + return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement); + } + + function parseArrayLiteralExpression(): ArrayLiteralExpression { + const pos = getNodePos(); + const openBracketPosition = scanner.getTokenStart(); + const openBracketParsed = parseExpected(SyntaxKind.OpenBracketToken); + const multiLine = scanner.hasPrecedingLineBreak(); + const elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArgumentOrArrayLiteralElement); + parseExpectedMatchingBrackets(SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken, openBracketParsed, openBracketPosition); + return finishNode(factoryCreateArrayLiteralExpression(elements, multiLine), pos); + } + + function parseObjectLiteralElement(): ObjectLiteralElementLike { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + + if (parseOptionalToken(SyntaxKind.DotDotDotToken)) { + const expression = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); + return withJSDoc(finishNode(factory.createSpreadAssignment(expression), pos), hasJSDoc); + } + + const modifiers = parseModifiers(/*allowDecorators*/ true); + if (parseContextualModifier(SyntaxKind.GetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.GetAccessor, SignatureFlags.None); + } + if (parseContextualModifier(SyntaxKind.SetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.SetAccessor, SignatureFlags.None); + } + + const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const tokenIsIdentifier = isIdentifier(); + const name = parsePropertyName(); + + // Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker. + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + const exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken); + + if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + return parseMethodDeclaration(pos, hasJSDoc, modifiers, asteriskToken, name, questionToken, exclamationToken); + } + + // check if it is short-hand property assignment or normal property assignment + // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production + // CoverInitializedName[Yield] : + // IdentifierReference[?Yield] Initializer[In, ?Yield] + // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern + let node: Mutable; + const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken); + if (isShorthandPropertyAssignment) { + const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken); + const objectAssignmentInitializer = equalsToken ? allowInAnd(() => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true)) : undefined; + node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer); + // Save equals token for error reporting. + // TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful. + node.equalsToken = equalsToken; + } + else { + parseExpected(SyntaxKind.ColonToken); + const initializer = allowInAnd(() => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true)); + node = factory.createPropertyAssignment(name, initializer); + } + // Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker + node.modifiers = modifiers; + node.questionToken = questionToken; + node.exclamationToken = exclamationToken; + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseObjectLiteralExpression(): ObjectLiteralExpression { + const pos = getNodePos(); + const openBracePosition = scanner.getTokenStart(); + const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken); + const multiLine = scanner.hasPrecedingLineBreak(); + const properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); + parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); + return finishNode(factoryCreateObjectLiteralExpression(properties, multiLine), pos); + } + + function parseFunctionExpression(): FunctionExpression { + // GeneratorExpression: + // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody } + // + // FunctionExpression: + // function BindingIdentifier[opt](FormalParameters){ FunctionBody } + const savedDecoratorContext = inDecoratorContext(); + setDecoratorContext(/*val*/ false); + + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiers(/*allowDecorators*/ false); + parseExpected(SyntaxKind.FunctionKeyword); + const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; + const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalBindingIdentifier) : + isGenerator ? doInYieldContext(parseOptionalBindingIdentifier) : + isAsync ? doInAwaitContext(parseOptionalBindingIdentifier) : + parseOptionalBindingIdentifier(); + + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(isGenerator | isAsync); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlock(isGenerator | isAsync); + + setDecoratorContext(savedDecoratorContext); + + const node = factory.createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseOptionalBindingIdentifier(): Identifier | undefined { + return isBindingIdentifier() ? parseBindingIdentifier() : undefined; + } + + function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty { + const pos = getNodePos(); + parseExpected(SyntaxKind.NewKeyword); + if (parseOptional(SyntaxKind.DotToken)) { + const name = parseIdentifierName(); + return finishNode(factory.createMetaProperty(SyntaxKind.NewKeyword, name), pos); + } + const expressionPos = getNodePos(); + let expression: LeftHandSideExpression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); + let typeArguments: NodeArray | undefined; + // Absorb type arguments into NewExpression when preceding expression is ExpressionWithTypeArguments + if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { + typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; + expression = (expression as ExpressionWithTypeArguments).expression; + } + if (token() === SyntaxKind.QuestionDotToken) { + parseErrorAtCurrentToken(Diagnostics.Invalid_optional_chain_from_new_expression_Did_you_mean_to_call_0, getTextOfNodeFromSourceText(sourceText, expression)); + } + const argumentList = token() === SyntaxKind.OpenParenToken ? parseArgumentList() : undefined; + return finishNode(factoryCreateNewExpression(expression, typeArguments, argumentList), pos); + } + + // STATEMENTS + function parseBlock(ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const openBracePosition = scanner.getTokenStart(); + const openBraceParsed = parseExpected(SyntaxKind.OpenBraceToken, diagnosticMessage); + if (openBraceParsed || ignoreMissingOpenBrace) { + const multiLine = scanner.hasPrecedingLineBreak(); + const statements = parseList(ParsingContext.BlockStatements, parseStatement); + parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition); + const result = withJSDoc(finishNode(factoryCreateBlock(statements, multiLine), pos), hasJSDoc); + if (token() === SyntaxKind.EqualsToken) { + parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_whole_assignment_in_parentheses); + nextToken(); + } + + return result; + } + else { + const statements = createMissingList(); + return withJSDoc(finishNode(factoryCreateBlock(statements, /*multiLine*/ undefined), pos), hasJSDoc); + } + } + + function parseFunctionBlock(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block { + const savedYieldContext = inYieldContext(); + setYieldContext(!!(flags & SignatureFlags.Yield)); + + const savedAwaitContext = inAwaitContext(); + setAwaitContext(!!(flags & SignatureFlags.Await)); + + const savedTopLevel = topLevel; + topLevel = false; + + // We may be in a [Decorator] context when parsing a function expression or + // arrow function. The body of the function is not in [Decorator] context. + const saveDecoratorContext = inDecoratorContext(); + if (saveDecoratorContext) { + setDecoratorContext(/*val*/ false); + } + + const block = parseBlock(!!(flags & SignatureFlags.IgnoreMissingOpenBrace), diagnosticMessage); + + if (saveDecoratorContext) { + setDecoratorContext(/*val*/ true); + } + + topLevel = savedTopLevel; + setYieldContext(savedYieldContext); + setAwaitContext(savedAwaitContext); + + return block; + } + + function parseEmptyStatement(): Statement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.SemicolonToken); + return withJSDoc(finishNode(factory.createEmptyStatement(), pos), hasJSDoc); + } + + function parseIfStatement(): IfStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.IfKeyword); + const openParenPosition = scanner.getTokenStart(); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const expression = allowInAnd(parseExpression); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + const thenStatement = parseStatement(); + const elseStatement = parseOptional(SyntaxKind.ElseKeyword) ? parseStatement() : undefined; + return withJSDoc(finishNode(factoryCreateIfStatement(expression, thenStatement, elseStatement), pos), hasJSDoc); + } + + function parseDoStatement(): DoStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.DoKeyword); + const statement = parseStatement(); + parseExpected(SyntaxKind.WhileKeyword); + const openParenPosition = scanner.getTokenStart(); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const expression = allowInAnd(parseExpression); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + + // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html + // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in + // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby + // do;while(0)x will have a semicolon inserted before x. + parseOptional(SyntaxKind.SemicolonToken); + return withJSDoc(finishNode(factory.createDoStatement(statement, expression), pos), hasJSDoc); + } + + function parseWhileStatement(): WhileStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.WhileKeyword); + const openParenPosition = scanner.getTokenStart(); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const expression = allowInAnd(parseExpression); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + const statement = parseStatement(); + return withJSDoc(finishNode(factoryCreateWhileStatement(expression, statement), pos), hasJSDoc); + } + + function parseForOrForInOrForOfStatement(): Statement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.ForKeyword); + const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword); + parseExpected(SyntaxKind.OpenParenToken); + + let initializer!: VariableDeclarationList | Expression; + if (token() !== SyntaxKind.SemicolonToken) { + if ( + token() === SyntaxKind.VarKeyword || token() === SyntaxKind.LetKeyword || token() === SyntaxKind.ConstKeyword || + token() === SyntaxKind.UsingKeyword && lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLineDisallowOf) || + // this one is meant to allow of + token() === SyntaxKind.AwaitKeyword && lookAhead(nextTokenIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine) + ) { + initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true); + } + else { + initializer = disallowInAnd(parseExpression); + } + } + + let node: IterationStatement; + if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) { + const expression = allowInAnd(() => parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true)); + parseExpected(SyntaxKind.CloseParenToken); + node = factoryCreateForOfStatement(awaitToken, initializer, expression, parseStatement()); + } + else if (parseOptional(SyntaxKind.InKeyword)) { + const expression = allowInAnd(parseExpression); + parseExpected(SyntaxKind.CloseParenToken); + node = factory.createForInStatement(initializer, expression, parseStatement()); + } + else { + parseExpected(SyntaxKind.SemicolonToken); + const condition = token() !== SyntaxKind.SemicolonToken && token() !== SyntaxKind.CloseParenToken + ? allowInAnd(parseExpression) + : undefined; + parseExpected(SyntaxKind.SemicolonToken); + const incrementor = token() !== SyntaxKind.CloseParenToken + ? allowInAnd(parseExpression) + : undefined; + parseExpected(SyntaxKind.CloseParenToken); + node = factoryCreateForStatement(initializer, condition, incrementor, parseStatement()); + } + + return withJSDoc(finishNode(node, pos) as ForStatement | ForInOrOfStatement, hasJSDoc); + } + + function parseBreakOrContinueStatement(kind: SyntaxKind): BreakOrContinueStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + + parseExpected(kind === SyntaxKind.BreakStatement ? SyntaxKind.BreakKeyword : SyntaxKind.ContinueKeyword); + const label = canParseSemicolon() ? undefined : parseIdentifier(); + + parseSemicolon(); + const node = kind === SyntaxKind.BreakStatement + ? factory.createBreakStatement(label) + : factory.createContinueStatement(label); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseReturnStatement(): ReturnStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.ReturnKeyword); + const expression = canParseSemicolon() ? undefined : allowInAnd(parseExpression); + parseSemicolon(); + return withJSDoc(finishNode(factory.createReturnStatement(expression), pos), hasJSDoc); + } + + function parseWithStatement(): WithStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.WithKeyword); + const openParenPosition = scanner.getTokenStart(); + const openParenParsed = parseExpected(SyntaxKind.OpenParenToken); + const expression = allowInAnd(parseExpression); + parseExpectedMatchingBrackets(SyntaxKind.OpenParenToken, SyntaxKind.CloseParenToken, openParenParsed, openParenPosition); + const statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); + return withJSDoc(finishNode(factory.createWithStatement(expression, statement), pos), hasJSDoc); + } + + function parseCaseClause(): CaseClause { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.CaseKeyword); + const expression = allowInAnd(parseExpression); + parseExpected(SyntaxKind.ColonToken); + const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); + return withJSDoc(finishNode(factory.createCaseClause(expression, statements), pos), hasJSDoc); + } + + function parseDefaultClause(): DefaultClause { + const pos = getNodePos(); + parseExpected(SyntaxKind.DefaultKeyword); + parseExpected(SyntaxKind.ColonToken); + const statements = parseList(ParsingContext.SwitchClauseStatements, parseStatement); + return finishNode(factory.createDefaultClause(statements), pos); + } + + function parseCaseOrDefaultClause(): CaseOrDefaultClause { + return token() === SyntaxKind.CaseKeyword ? parseCaseClause() : parseDefaultClause(); + } + + function parseCaseBlock(): CaseBlock { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBraceToken); + const clauses = parseList(ParsingContext.SwitchClauses, parseCaseOrDefaultClause); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(factory.createCaseBlock(clauses), pos); + } + + function parseSwitchStatement(): SwitchStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.SwitchKeyword); + parseExpected(SyntaxKind.OpenParenToken); + const expression = allowInAnd(parseExpression); + parseExpected(SyntaxKind.CloseParenToken); + const caseBlock = parseCaseBlock(); + return withJSDoc(finishNode(factory.createSwitchStatement(expression, caseBlock), pos), hasJSDoc); + } + + function parseThrowStatement(): ThrowStatement { + // ThrowStatement[Yield] : + // throw [no LineTerminator here]Expression[In, ?Yield]; + + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.ThrowKeyword); + + // Because of automatic semicolon insertion, we need to report error if this + // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' + // directly as that might consume an expression on the following line. + // Instead, we create a "missing" identifier, but don't report an error. The actual error + // will be reported in the grammar walker. + let expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); + if (expression === undefined) { + identifierCount++; + expression = finishNode(factoryCreateIdentifier(""), getNodePos()); + } + if (!tryParseSemicolon()) { + parseErrorForMissingSemicolonAfter(expression); + } + return withJSDoc(finishNode(factory.createThrowStatement(expression), pos), hasJSDoc); + } + + // TODO: Review for error recovery + function parseTryStatement(): TryStatement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + + parseExpected(SyntaxKind.TryKeyword); + const tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); + const catchClause = token() === SyntaxKind.CatchKeyword ? parseCatchClause() : undefined; + + // If we don't have a catch clause, then we must have a finally clause. Try to parse + // one out no matter what. + let finallyBlock: Block | undefined; + if (!catchClause || token() === SyntaxKind.FinallyKeyword) { + parseExpected(SyntaxKind.FinallyKeyword, Diagnostics.catch_or_finally_expected); + finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); + } + + return withJSDoc(finishNode(factory.createTryStatement(tryBlock, catchClause, finallyBlock), pos), hasJSDoc); + } + + function parseCatchClause(): CatchClause { + const pos = getNodePos(); + parseExpected(SyntaxKind.CatchKeyword); + + let variableDeclaration; + if (parseOptional(SyntaxKind.OpenParenToken)) { + variableDeclaration = parseVariableDeclaration(); + parseExpected(SyntaxKind.CloseParenToken); + } + else { + // Keep shape of node to avoid degrading performance. + variableDeclaration = undefined; + } + + const block = parseBlock(/*ignoreMissingOpenBrace*/ false); + return finishNode(factory.createCatchClause(variableDeclaration, block), pos); + } + + function parseDebuggerStatement(): Statement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + parseExpected(SyntaxKind.DebuggerKeyword); + parseSemicolon(); + return withJSDoc(finishNode(factory.createDebuggerStatement(), pos), hasJSDoc); + } + + function parseExpressionOrLabeledStatement(): ExpressionStatement | LabeledStatement { + // Avoiding having to do the lookahead for a labeled statement by just trying to parse + // out an expression, seeing if it is identifier and then seeing if it is followed by + // a colon. + const pos = getNodePos(); + let hasJSDoc = hasPrecedingJSDocComment(); + let node: ExpressionStatement | LabeledStatement; + const hasParen = token() === SyntaxKind.OpenParenToken; + const expression = allowInAnd(parseExpression); + if (isIdentifierNode(expression) && parseOptional(SyntaxKind.ColonToken)) { + node = factory.createLabeledStatement(expression, parseStatement()); + } + else { + if (!tryParseSemicolon()) { + parseErrorForMissingSemicolonAfter(expression); + } + node = factoryCreateExpressionStatement(expression); + if (hasParen) { + // do not parse the same jsdoc twice + hasJSDoc = false; + } + } + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function nextTokenIsIdentifierOrKeywordOnSameLine() { + nextToken(); + return tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak(); + } + + function nextTokenIsClassKeywordOnSameLine() { + nextToken(); + return token() === SyntaxKind.ClassKeyword && !scanner.hasPrecedingLineBreak(); + } + + function nextTokenIsFunctionKeywordOnSameLine() { + nextToken(); + return token() === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak(); + } + + function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() { + nextToken(); + return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak(); + } + + function isDeclaration(): boolean { + while (true) { + switch (token()) { + case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: + case SyntaxKind.FunctionKeyword: + case SyntaxKind.ClassKeyword: + case SyntaxKind.EnumKeyword: + return true; + case SyntaxKind.UsingKeyword: + return isUsingDeclaration(); + case SyntaxKind.AwaitKeyword: + return isAwaitUsingDeclaration(); + + // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; + // however, an identifier cannot be followed by another identifier on the same line. This is what we + // count on to parse out the respective declarations. For instance, we exploit this to say that + // + // namespace n + // + // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees + // + // namespace + // n + // + // as the identifier 'namespace' on one line followed by the identifier 'n' on another. + // We need to look one token ahead to see if it permissible to try parsing a declaration. + // + // *Note*: 'interface' is actually a strict mode reserved word. So while + // + // "use strict" + // interface + // I {} + // + // could be legal, it would add complexity for very little gain. + case SyntaxKind.InterfaceKeyword: + case SyntaxKind.TypeKeyword: + case SyntaxKind.DeferKeyword: + return nextTokenIsIdentifierOnSameLine(); + case SyntaxKind.ModuleKeyword: + case SyntaxKind.NamespaceKeyword: + return nextTokenIsIdentifierOrStringLiteralOnSameLine(); + case SyntaxKind.AbstractKeyword: + case SyntaxKind.AccessorKeyword: + case SyntaxKind.AsyncKeyword: + case SyntaxKind.DeclareKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.PublicKeyword: + case SyntaxKind.ReadonlyKeyword: + const previousToken = token(); + nextToken(); + // ASI takes effect for this modifier. + if (scanner.hasPrecedingLineBreak()) { + return false; + } + if (previousToken === SyntaxKind.DeclareKeyword && token() === SyntaxKind.TypeKeyword) { + // If we see 'declare type', then commit to parsing a type alias. parseTypeAliasDeclaration will + // report Line_break_not_permitted_here if needed. + return true; + } + continue; + + case SyntaxKind.GlobalKeyword: + nextToken(); + return token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.Identifier || token() === SyntaxKind.ExportKeyword; + + case SyntaxKind.ImportKeyword: + nextToken(); + return token() === SyntaxKind.DeferKeyword || token() === SyntaxKind.StringLiteral || token() === SyntaxKind.AsteriskToken || + token() === SyntaxKind.OpenBraceToken || tokenIsIdentifierOrKeyword(token()); + case SyntaxKind.ExportKeyword: + let currentToken = nextToken(); + if (currentToken === SyntaxKind.TypeKeyword) { + currentToken = lookAhead(nextToken); + } + if ( + currentToken === SyntaxKind.EqualsToken || currentToken === SyntaxKind.AsteriskToken || + currentToken === SyntaxKind.OpenBraceToken || currentToken === SyntaxKind.DefaultKeyword || + currentToken === SyntaxKind.AsKeyword || currentToken === SyntaxKind.AtToken + ) { + return true; + } + continue; + + case SyntaxKind.StaticKeyword: + nextToken(); + continue; + + default: + return false; + } + } + } + + function isStartOfDeclaration(): boolean { + return lookAhead(isDeclaration); + } + + function isStartOfStatement(): boolean { + switch (token()) { + case SyntaxKind.AtToken: + case SyntaxKind.SemicolonToken: + case SyntaxKind.OpenBraceToken: + case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.UsingKeyword: + case SyntaxKind.FunctionKeyword: + case SyntaxKind.ClassKeyword: + case SyntaxKind.EnumKeyword: + case SyntaxKind.IfKeyword: + case SyntaxKind.DoKeyword: + case SyntaxKind.WhileKeyword: + case SyntaxKind.ForKeyword: + case SyntaxKind.ContinueKeyword: + case SyntaxKind.BreakKeyword: + case SyntaxKind.ReturnKeyword: + case SyntaxKind.WithKeyword: + case SyntaxKind.SwitchKeyword: + case SyntaxKind.ThrowKeyword: + case SyntaxKind.TryKeyword: + case SyntaxKind.DebuggerKeyword: + // 'catch' and 'finally' do not actually indicate that the code is part of a statement, + // however, we say they are here so that we may gracefully parse them and error later. + // falls through + case SyntaxKind.CatchKeyword: + case SyntaxKind.FinallyKeyword: + return true; + + case SyntaxKind.ImportKeyword: + return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot); + + case SyntaxKind.ConstKeyword: + case SyntaxKind.ExportKeyword: + return isStartOfDeclaration(); + + case SyntaxKind.AsyncKeyword: + case SyntaxKind.DeclareKeyword: + case SyntaxKind.InterfaceKeyword: + case SyntaxKind.ModuleKeyword: + case SyntaxKind.NamespaceKeyword: + case SyntaxKind.TypeKeyword: + case SyntaxKind.GlobalKeyword: + case SyntaxKind.DeferKeyword: + // When these don't start a declaration, they're an identifier in an expression statement + return true; + + case SyntaxKind.AccessorKeyword: + case SyntaxKind.PublicKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.StaticKeyword: + case SyntaxKind.ReadonlyKeyword: + // When these don't start a declaration, they may be the start of a class member if an identifier + // immediately follows. Otherwise they're an identifier in an expression statement. + return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); + + default: + return isStartOfExpression(); + } + } + + function nextTokenIsBindingIdentifierOrStartOfDestructuring() { + nextToken(); + return isBindingIdentifier() || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken; + } + + function isLetDeclaration() { + // In ES6 'let' always starts a lexical declaration if followed by an identifier or { + // or [. + return lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuring); + } + + function nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLineDisallowOf() { + return nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(/*disallowOf*/ true); + } + + function nextTokenIsEqualsOrSemicolonOrColonToken() { + nextToken(); + return token() === SyntaxKind.EqualsToken || token() === SyntaxKind.SemicolonToken || token() === SyntaxKind.ColonToken; + } + + function nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(disallowOf?: boolean) { + nextToken(); + if (disallowOf && token() === SyntaxKind.OfKeyword) { + return lookAhead(nextTokenIsEqualsOrSemicolonOrColonToken); + } + return (isBindingIdentifier() || token() === SyntaxKind.OpenBraceToken) && !scanner.hasPrecedingLineBreak(); + } + + function isUsingDeclaration() { + // 'using' always starts a lexical declaration if followed by an identifier. We also eagerly parse + // |ObjectBindingPattern| so that we can report a grammar error during check. We don't parse out + // |ArrayBindingPattern| since it potentially conflicts with element access (i.e., `using[x]`). + return lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine); + } + + function nextTokenIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine(disallowOf?: boolean) { + if (nextToken() === SyntaxKind.UsingKeyword) { + return nextTokenIsBindingIdentifierOrStartOfDestructuringOnSameLine(disallowOf); + } + return false; + } + + function isAwaitUsingDeclaration() { + // 'await using' always starts a lexical declaration if followed by an identifier. We also eagerly parse + // |ObjectBindingPattern| so that we can report a grammar error during check. We don't parse out + // |ArrayBindingPattern| since it potentially conflicts with element access (i.e., `await using[x]`). + return lookAhead(nextTokenIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine); + } + + function parseStatement(): Statement { + switch (token()) { + case SyntaxKind.SemicolonToken: + return parseEmptyStatement(); + case SyntaxKind.OpenBraceToken: + return parseBlock(/*ignoreMissingOpenBrace*/ false); + case SyntaxKind.VarKeyword: + return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); + case SyntaxKind.LetKeyword: + if (isLetDeclaration()) { + return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); + } + break; + case SyntaxKind.AwaitKeyword: + if (isAwaitUsingDeclaration()) { + return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); + } + break; + case SyntaxKind.UsingKeyword: + if (isUsingDeclaration()) { + return parseVariableStatement(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); + } + break; + case SyntaxKind.FunctionKeyword: + return parseFunctionDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); + case SyntaxKind.ClassKeyword: + return parseClassDeclaration(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined); + case SyntaxKind.IfKeyword: + return parseIfStatement(); + case SyntaxKind.DoKeyword: + return parseDoStatement(); + case SyntaxKind.WhileKeyword: + return parseWhileStatement(); + case SyntaxKind.ForKeyword: + return parseForOrForInOrForOfStatement(); + case SyntaxKind.ContinueKeyword: + return parseBreakOrContinueStatement(SyntaxKind.ContinueStatement); + case SyntaxKind.BreakKeyword: + return parseBreakOrContinueStatement(SyntaxKind.BreakStatement); + case SyntaxKind.ReturnKeyword: + return parseReturnStatement(); + case SyntaxKind.WithKeyword: + return parseWithStatement(); + case SyntaxKind.SwitchKeyword: + return parseSwitchStatement(); + case SyntaxKind.ThrowKeyword: + return parseThrowStatement(); + case SyntaxKind.TryKeyword: + // Include 'catch' and 'finally' for error recovery. + // falls through + case SyntaxKind.CatchKeyword: + case SyntaxKind.FinallyKeyword: + return parseTryStatement(); + case SyntaxKind.DebuggerKeyword: + return parseDebuggerStatement(); + case SyntaxKind.AtToken: + return parseDeclaration(); + case SyntaxKind.AsyncKeyword: + case SyntaxKind.InterfaceKeyword: + case SyntaxKind.TypeKeyword: + case SyntaxKind.ModuleKeyword: + case SyntaxKind.NamespaceKeyword: + case SyntaxKind.DeclareKeyword: + case SyntaxKind.ConstKeyword: + case SyntaxKind.EnumKeyword: + case SyntaxKind.ExportKeyword: + case SyntaxKind.ImportKeyword: + case SyntaxKind.PrivateKeyword: + case SyntaxKind.ProtectedKeyword: + case SyntaxKind.PublicKeyword: + case SyntaxKind.AbstractKeyword: + case SyntaxKind.AccessorKeyword: + case SyntaxKind.StaticKeyword: + case SyntaxKind.ReadonlyKeyword: + case SyntaxKind.GlobalKeyword: + if (isStartOfDeclaration()) { + return parseDeclaration(); + } + break; + } + return parseExpressionOrLabeledStatement(); + } + + function isDeclareModifier(modifier: ModifierLike) { + return modifier.kind === SyntaxKind.DeclareKeyword; + } + + function parseDeclaration(): Statement { + // `parseListElement` attempted to get the reused node at this position, + // but the ambient context flag was not yet set, so the node appeared + // not reusable in that context. + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiers(/*allowDecorators*/ true); + const isAmbient = some(modifiers, isDeclareModifier); + if (isAmbient) { + const node = tryReuseAmbientDeclaration(pos); + if (node) { + return node; + } + + for (const m of modifiers!) { + (m as Mutable).flags |= NodeFlags.Ambient; + } + return doInsideOfContext(NodeFlags.Ambient, () => parseDeclarationWorker(pos, hasJSDoc, modifiers)); + } + else { + return parseDeclarationWorker(pos, hasJSDoc, modifiers); + } + } + + function tryReuseAmbientDeclaration(pos: number): Statement | undefined { + return doInsideOfContext(NodeFlags.Ambient, () => { + // TODO(jakebailey): this is totally wrong; `parsingContext` is the result of ORing a bunch of `1 << ParsingContext.XYZ`. + // The enum should really be a bunch of flags. + const node = currentNode(parsingContext, pos); + if (node) { + return consumeNode(node) as Statement; + } + }); + } + + function parseDeclarationWorker(pos: number, hasJSDoc: boolean, modifiersIn: NodeArray | undefined): Statement { + switch (token()) { + case SyntaxKind.VarKeyword: + case SyntaxKind.LetKeyword: + case SyntaxKind.ConstKeyword: + case SyntaxKind.UsingKeyword: + return parseVariableStatement(pos, hasJSDoc, modifiersIn); + case SyntaxKind.AwaitKeyword: + if (!isAwaitUsingDeclaration()) { + break; + } + return parseVariableStatement(pos, hasJSDoc, modifiersIn); + case SyntaxKind.FunctionKeyword: + return parseFunctionDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.ClassKeyword: + return parseClassDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.InterfaceKeyword: + return parseInterfaceDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.TypeKeyword: + return parseTypeAliasDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.EnumKeyword: + return parseEnumDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.GlobalKeyword: + case SyntaxKind.ModuleKeyword: + case SyntaxKind.NamespaceKeyword: + return parseModuleDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.ImportKeyword: + return parseImportDeclarationOrImportEqualsDeclaration(pos, hasJSDoc, modifiersIn); + case SyntaxKind.ExportKeyword: + nextToken(); + switch (token()) { + case SyntaxKind.DefaultKeyword: + case SyntaxKind.EqualsToken: + return parseExportAssignment(pos, hasJSDoc, modifiersIn); + case SyntaxKind.AsKeyword: + return parseNamespaceExportDeclaration(pos, hasJSDoc, modifiersIn); + default: + return parseExportDeclaration(pos, hasJSDoc, modifiersIn); + } + } + if (modifiersIn) { + // We reached this point because we encountered decorators and/or modifiers and assumed a declaration + // would follow. For recovery and error reporting purposes, return an incomplete declaration. + const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + setTextRangePos(missing, pos); + (missing as Mutable).modifiers = modifiersIn; + return missing; + } + return undefined!; // TODO: GH#18217 + } + + function nextTokenIsStringLiteral() { + return nextToken() === SyntaxKind.StringLiteral; + } + + function nextTokenIsFromKeywordOrEqualsToken() { + nextToken(); + return token() === SyntaxKind.FromKeyword || token() === SyntaxKind.EqualsToken; + } + + function nextTokenIsIdentifierOrStringLiteralOnSameLine() { + nextToken(); + return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === SyntaxKind.StringLiteral); + } + + function parseFunctionBlockOrSemicolon(flags: SignatureFlags, diagnosticMessage?: DiagnosticMessage): Block | undefined { + if (token() !== SyntaxKind.OpenBraceToken) { + if (flags & SignatureFlags.Type) { + parseTypeMemberSemicolon(); + return; + } + if (canParseSemicolon()) { + parseSemicolon(); + return; + } + } + return parseFunctionBlock(flags, diagnosticMessage); + } + + // DECLARATIONS + + function parseArrayBindingElement(): ArrayBindingElement { + const pos = getNodePos(); + if (token() === SyntaxKind.CommaToken) { + return finishNode(factory.createOmittedExpression(), pos); + } + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const name = parseIdentifierOrPattern(); + const initializer = parseInitializer(); + return finishNode(factory.createBindingElement(dotDotDotToken, /*propertyName*/ undefined, name, initializer), pos); + } + + function parseObjectBindingElement(): BindingElement { + const pos = getNodePos(); + const dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken); + const tokenIsIdentifier = isBindingIdentifier(); + let propertyName: PropertyName | undefined = parsePropertyName(); + let name: BindingName; + if (tokenIsIdentifier && token() !== SyntaxKind.ColonToken) { + name = propertyName as Identifier; + propertyName = undefined; + } + else { + parseExpected(SyntaxKind.ColonToken); + name = parseIdentifierOrPattern(); + } + const initializer = parseInitializer(); + return finishNode(factory.createBindingElement(dotDotDotToken, propertyName, name, initializer), pos); + } + + function parseObjectBindingPattern(): ObjectBindingPattern { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBraceToken); + const elements = allowInAnd(() => parseDelimitedList(ParsingContext.ObjectBindingElements, parseObjectBindingElement)); + parseExpected(SyntaxKind.CloseBraceToken); + return finishNode(factory.createObjectBindingPattern(elements), pos); + } + + function parseArrayBindingPattern(): ArrayBindingPattern { + const pos = getNodePos(); + parseExpected(SyntaxKind.OpenBracketToken); + const elements = allowInAnd(() => parseDelimitedList(ParsingContext.ArrayBindingElements, parseArrayBindingElement)); + parseExpected(SyntaxKind.CloseBracketToken); + return finishNode(factory.createArrayBindingPattern(elements), pos); + } + + function isBindingIdentifierOrPrivateIdentifierOrPattern() { + return token() === SyntaxKind.OpenBraceToken + || token() === SyntaxKind.OpenBracketToken + || token() === SyntaxKind.PrivateIdentifier + || isBindingIdentifier(); + } + + function parseIdentifierOrPattern(privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier | BindingPattern { + if (token() === SyntaxKind.OpenBracketToken) { + return parseArrayBindingPattern(); + } + if (token() === SyntaxKind.OpenBraceToken) { + return parseObjectBindingPattern(); + } + return parseBindingIdentifier(privateIdentifierDiagnosticMessage); + } + + function parseVariableDeclarationAllowExclamation() { + return parseVariableDeclaration(/*allowExclamation*/ true); + } + + function parseVariableDeclaration(allowExclamation?: boolean): VariableDeclaration { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const name = parseIdentifierOrPattern(Diagnostics.Private_identifiers_are_not_allowed_in_variable_declarations); + let exclamationToken: ExclamationToken | undefined; + if ( + allowExclamation && name.kind === SyntaxKind.Identifier && + token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak() + ) { + exclamationToken = parseTokenNode>(); + } + const type = parseTypeAnnotation(); + const initializer = isInOrOfKeyword(token()) ? undefined : parseInitializer(); + const node = factoryCreateVariableDeclaration(name, exclamationToken, type, initializer); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseVariableDeclarationList(inForStatementInitializer: boolean): VariableDeclarationList { + const pos = getNodePos(); + + let flags: NodeFlags = 0; + switch (token()) { + case SyntaxKind.VarKeyword: + break; + case SyntaxKind.LetKeyword: + flags |= NodeFlags.Let; + break; + case SyntaxKind.ConstKeyword: + flags |= NodeFlags.Const; + break; + case SyntaxKind.UsingKeyword: + flags |= NodeFlags.Using; + break; + case SyntaxKind.AwaitKeyword: + if (!isAwaitUsingDeclaration()) { + break; + } + flags |= NodeFlags.AwaitUsing; + nextToken(); + break; + default: + Debug.fail(); + } + + nextToken(); + + // The user may have written the following: + // + // for (let of X) { } + // + // In this case, we want to parse an empty declaration list, and then parse 'of' + // as a keyword. The reason this is not automatic is that 'of' is a valid identifier. + // So we need to look ahead to determine if 'of' should be treated as a keyword in + // this context. + // The checker will then give an error that there is an empty declaration list. + let declarations: readonly VariableDeclaration[]; + if (token() === SyntaxKind.OfKeyword && lookAhead(canFollowContextualOfKeyword)) { + declarations = createMissingList(); + } + else { + const savedDisallowIn = inDisallowInContext(); + setDisallowInContext(inForStatementInitializer); + + declarations = parseDelimitedList( + ParsingContext.VariableDeclarations, + inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation, + ); + + setDisallowInContext(savedDisallowIn); + } + + return finishNode(factoryCreateVariableDeclarationList(declarations, flags), pos); + } + + function canFollowContextualOfKeyword(): boolean { + return nextTokenIsIdentifier() && nextToken() === SyntaxKind.CloseParenToken; + } + + function parseVariableStatement(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): VariableStatement { + const declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); + parseSemicolon(); + const node = factoryCreateVariableStatement(modifiers, declarationList); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseFunctionDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): FunctionDeclaration { + const savedAwaitContext = inAwaitContext(); + const modifierFlags = modifiersToFlags(modifiers); + parseExpected(SyntaxKind.FunctionKeyword); + const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + // We don't parse the name here in await context, instead we will report a grammar error in the checker. + const name = modifierFlags & ModifierFlags.Default ? parseOptionalBindingIdentifier() : parseBindingIdentifier(); + const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; + const isAsync = modifierFlags & ModifierFlags.Async ? SignatureFlags.Await : SignatureFlags.None; + const typeParameters = parseTypeParameters(); + if (modifierFlags & ModifierFlags.Export) setAwaitContext(/*value*/ true); + const parameters = parseParameters(isGenerator | isAsync); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, Diagnostics.or_expected); + setAwaitContext(savedAwaitContext); + const node = factory.createFunctionDeclaration(modifiers, asteriskToken, name, typeParameters, parameters, type, body); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseConstructorName() { + if (token() === SyntaxKind.ConstructorKeyword) { + return parseExpected(SyntaxKind.ConstructorKeyword); + } + if (token() === SyntaxKind.StringLiteral && lookAhead(nextToken) === SyntaxKind.OpenParenToken) { + return tryParse(() => { + const literalNode = parseLiteralNode(); + return literalNode.text === "constructor" ? literalNode : undefined; + }); + } + } + + function tryParseConstructorDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ConstructorDeclaration | undefined { + return tryParse(() => { + if (parseConstructorName()) { + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.None); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); + const node = factory.createConstructorDeclaration(modifiers, parameters, body); + + // Attach invalid nodes if they exist so that we can report them in the grammar checker. + (node as Mutable).typeParameters = typeParameters; + (node as Mutable).type = type; + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + }); + } + + function parseMethodDeclaration( + pos: number, + hasJSDoc: boolean, + modifiers: NodeArray | undefined, + asteriskToken: AsteriskToken | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + exclamationToken: ExclamationToken | undefined, + diagnosticMessage?: DiagnosticMessage, + ): MethodDeclaration { + const isGenerator = asteriskToken ? SignatureFlags.Yield : SignatureFlags.None; + const isAsync = some(modifiers, isAsyncModifier) ? SignatureFlags.Await : SignatureFlags.None; + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(isGenerator | isAsync); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); + const node = factory.createMethodDeclaration( + modifiers, + asteriskToken, + name, + questionToken, + typeParameters, + parameters, + type, + body, + ); + + // An exclamation token on a method is invalid syntax and will be handled by the grammar checker + (node as Mutable).exclamationToken = exclamationToken; + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parsePropertyDeclaration( + pos: number, + hasJSDoc: boolean, + modifiers: NodeArray | undefined, + name: PropertyName, + questionToken: QuestionToken | undefined, + ): PropertyDeclaration { + const exclamationToken = !questionToken && !scanner.hasPrecedingLineBreak() ? parseOptionalToken(SyntaxKind.ExclamationToken) : undefined; + const type = parseTypeAnnotation(); + const initializer = doOutsideOfContext(NodeFlags.YieldContext | NodeFlags.AwaitContext | NodeFlags.DisallowInContext, parseInitializer); + parseSemicolonAfterPropertyName(name, type, initializer); + const node = factory.createPropertyDeclaration( + modifiers, + name, + questionToken || exclamationToken, + type, + initializer, + ); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parsePropertyOrMethodDeclaration( + pos: number, + hasJSDoc: boolean, + modifiers: NodeArray | undefined, + ): PropertyDeclaration | MethodDeclaration { + const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken); + const name = parsePropertyName(); + // Note: this is not legal as per the grammar. But we allow it in the parser and + // report an error in the grammar checker. + const questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) { + return parseMethodDeclaration(pos, hasJSDoc, modifiers, asteriskToken, name, questionToken, /*exclamationToken*/ undefined, Diagnostics.or_expected); + } + return parsePropertyDeclaration(pos, hasJSDoc, modifiers, name, questionToken); + } + + function parseAccessorDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, kind: AccessorDeclaration["kind"], flags: SignatureFlags): AccessorDeclaration { + const name = parsePropertyName(); + const typeParameters = parseTypeParameters(); + const parameters = parseParameters(SignatureFlags.None); + const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false); + const body = parseFunctionBlockOrSemicolon(flags); + const node = kind === SyntaxKind.GetAccessor + ? factory.createGetAccessorDeclaration(modifiers, name, parameters, type, body) + : factory.createSetAccessorDeclaration(modifiers, name, parameters, body); + // Keep track of `typeParameters` (for both) and `type` (for setters) if they were parsed those indicate grammar errors + (node as Mutable).typeParameters = typeParameters; + if (isSetAccessorDeclaration(node)) (node as Mutable).type = type; + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function isClassMemberStart(): boolean { + let idToken: SyntaxKind | undefined; + + if (token() === SyntaxKind.AtToken) { + return true; + } + + // Eat up all modifiers, but hold on to the last one in case it is actually an identifier. + while (isModifierKind(token())) { + idToken = token(); + // If the idToken is a class modifier (protected, private, public, and static), it is + // certain that we are starting to parse class member. This allows better error recovery + // Example: + // public foo() ... // true + // public @dec blah ... // true; we will then report an error later + // export public ... // true; we will then report an error later + if (isClassMemberModifier(idToken)) { + return true; + } + + nextToken(); + } + + if (token() === SyntaxKind.AsteriskToken) { + return true; + } + + // Try to get the first property-like token following all modifiers. + // This can either be an identifier or the 'get' or 'set' keywords. + if (isLiteralPropertyName()) { + idToken = token(); + nextToken(); + } + + // Index signatures and computed properties are class members; we can parse. + if (token() === SyntaxKind.OpenBracketToken) { + return true; + } + + // If we were able to get any potential identifier... + if (idToken !== undefined) { + // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse. + if (!isKeyword(idToken) || idToken === SyntaxKind.SetKeyword || idToken === SyntaxKind.GetKeyword) { + return true; + } + + // If it *is* a keyword, but not an accessor, check a little farther along + // to see if it should actually be parsed as a class member. + switch (token()) { + case SyntaxKind.OpenParenToken: // Method declaration + case SyntaxKind.LessThanToken: // Generic Method declaration + case SyntaxKind.ExclamationToken: // Non-null assertion on property name + case SyntaxKind.ColonToken: // Type Annotation for declaration + case SyntaxKind.EqualsToken: // Initializer for declaration + case SyntaxKind.QuestionToken: // Not valid, but permitted so that it gets caught later on. + return true; + default: + // Covers + // - Semicolons (declaration termination) + // - Closing braces (end-of-class, must be declaration) + // - End-of-files (not valid, but permitted so that it gets caught later on) + // - Line-breaks (enabling *automatic semicolon insertion*) + return canParseSemicolon(); + } + } + + return false; + } + + function parseClassStaticBlockDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ClassStaticBlockDeclaration { + parseExpectedToken(SyntaxKind.StaticKeyword); + const body = parseClassStaticBlockBody(); + const node = withJSDoc(finishNode(factory.createClassStaticBlockDeclaration(body), pos), hasJSDoc); + (node as Mutable).modifiers = modifiers; + return node; + } + + function parseClassStaticBlockBody() { + const savedYieldContext = inYieldContext(); + const savedAwaitContext = inAwaitContext(); + + setYieldContext(false); + setAwaitContext(true); + + const body = parseBlock(/*ignoreMissingOpenBrace*/ false); + + setYieldContext(savedYieldContext); + setAwaitContext(savedAwaitContext); + + return body; + } + + function parseDecoratorExpression() { + if (inAwaitContext() && token() === SyntaxKind.AwaitKeyword) { + // `@await` is is disallowed in an [Await] context, but can cause parsing to go off the rails + // This simply parses the missing identifier and moves on. + const pos = getNodePos(); + const awaitExpression = parseIdentifier(Diagnostics.Expression_expected); + nextToken(); + const memberExpression = parseMemberExpressionRest(pos, awaitExpression, /*allowOptionalChain*/ true); + return parseCallExpressionRest(pos, memberExpression); + } + return parseLeftHandSideExpressionOrHigher(); + } + + function tryParseDecorator(): Decorator | undefined { + const pos = getNodePos(); + if (!parseOptional(SyntaxKind.AtToken)) { + return undefined; + } + const expression = doInDecoratorContext(parseDecoratorExpression); + return finishNode(factory.createDecorator(expression), pos); + } + + function tryParseModifier(hasSeenStaticModifier: boolean, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): Modifier | undefined { + const pos = getNodePos(); + const kind = token(); + + if (token() === SyntaxKind.ConstKeyword && permitConstAsModifier) { + // We need to ensure that any subsequent modifiers appear on the same line + // so that when 'const' is a standalone declaration, we don't issue an error. + if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { + return undefined; + } + } + else if (stopOnStartOfClassStaticBlock && token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { + return undefined; + } + else if (hasSeenStaticModifier && token() === SyntaxKind.StaticKeyword) { + return undefined; + } + else { + if (!parseAnyContextualModifier()) { + return undefined; + } + } + + return finishNode(factoryCreateToken(kind as Modifier["kind"]), pos); + } + + /* + * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member. + * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect + * and turns it into a standalone declaration), then it is better to parse it and report an error later. + * + * In such situations, 'permitConstAsModifier' should be set to true. + */ + function parseModifiers(allowDecorators: false, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined; + function parseModifiers(allowDecorators: true, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined; + function parseModifiers(allowDecorators: boolean, permitConstAsModifier?: boolean, stopOnStartOfClassStaticBlock?: boolean): NodeArray | undefined { + const pos = getNodePos(); + let list: ModifierLike[] | undefined; + let decorator, modifier, hasSeenStaticModifier = false, hasLeadingModifier = false, hasTrailingDecorator = false; + + // Decorators should be contiguous in a list of modifiers but can potentially appear in two places (i.e., `[...leadingDecorators, ...leadingModifiers, ...trailingDecorators, ...trailingModifiers]`). + // The leading modifiers *should* only contain `export` and `default` when trailingDecorators are present, but we'll handle errors for any other leading modifiers in the checker. + // It is illegal to have both leadingDecorators and trailingDecorators, but we will report that as a grammar check in the checker. + + // parse leading decorators + if (allowDecorators && token() === SyntaxKind.AtToken) { + while (decorator = tryParseDecorator()) { + list = append(list, decorator); + } + } + + // parse leading modifiers + while (modifier = tryParseModifier(hasSeenStaticModifier, permitConstAsModifier, stopOnStartOfClassStaticBlock)) { + if (modifier.kind === SyntaxKind.StaticKeyword) hasSeenStaticModifier = true; + list = append(list, modifier); + hasLeadingModifier = true; + } + + // parse trailing decorators, but only if we parsed any leading modifiers + if (hasLeadingModifier && allowDecorators && token() === SyntaxKind.AtToken) { + while (decorator = tryParseDecorator()) { + list = append(list, decorator); + hasTrailingDecorator = true; + } + } + + // parse trailing modifiers, but only if we parsed any trailing decorators + if (hasTrailingDecorator) { + while (modifier = tryParseModifier(hasSeenStaticModifier, permitConstAsModifier, stopOnStartOfClassStaticBlock)) { + if (modifier.kind === SyntaxKind.StaticKeyword) hasSeenStaticModifier = true; + list = append(list, modifier); + } + } + + return list && createNodeArray(list, pos); + } + + function parseModifiersForArrowFunction(): NodeArray | undefined { + let modifiers: NodeArray | undefined; + if (token() === SyntaxKind.AsyncKeyword) { + const pos = getNodePos(); + nextToken(); + const modifier = finishNode(factoryCreateToken(SyntaxKind.AsyncKeyword), pos); + modifiers = createNodeArray([modifier], pos); + } + return modifiers; + } + + function parseClassElement(): ClassElement { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + if (token() === SyntaxKind.SemicolonToken) { + nextToken(); + return withJSDoc(finishNode(factory.createSemicolonClassElement(), pos), hasJSDoc); + } + + const modifiers = parseModifiers(/*allowDecorators*/ true, /*permitConstAsModifier*/ true, /*stopOnStartOfClassStaticBlock*/ true); + if (token() === SyntaxKind.StaticKeyword && lookAhead(nextTokenIsOpenBrace)) { + return parseClassStaticBlockDeclaration(pos, hasJSDoc, modifiers); + } + + if (parseContextualModifier(SyntaxKind.GetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.GetAccessor, SignatureFlags.None); + } + + if (parseContextualModifier(SyntaxKind.SetKeyword)) { + return parseAccessorDeclaration(pos, hasJSDoc, modifiers, SyntaxKind.SetAccessor, SignatureFlags.None); + } + + if (token() === SyntaxKind.ConstructorKeyword || token() === SyntaxKind.StringLiteral) { + const constructorDeclaration = tryParseConstructorDeclaration(pos, hasJSDoc, modifiers); + if (constructorDeclaration) { + return constructorDeclaration; + } + } + + if (isIndexSignature()) { + return parseIndexSignatureDeclaration(pos, hasJSDoc, modifiers); + } + + // It is very important that we check this *after* checking indexers because + // the [ token can start an index signature or a computed property name + if ( + tokenIsIdentifierOrKeyword(token()) || + token() === SyntaxKind.StringLiteral || + token() === SyntaxKind.NumericLiteral || + token() === SyntaxKind.BigIntLiteral || + token() === SyntaxKind.AsteriskToken || + token() === SyntaxKind.OpenBracketToken + ) { + const isAmbient = some(modifiers, isDeclareModifier); + if (isAmbient) { + for (const m of modifiers!) { + (m as Mutable).flags |= NodeFlags.Ambient; + } + return doInsideOfContext(NodeFlags.Ambient, () => parsePropertyOrMethodDeclaration(pos, hasJSDoc, modifiers)); + } + else { + return parsePropertyOrMethodDeclaration(pos, hasJSDoc, modifiers); + } + } + + if (modifiers) { + // treat this as a property declaration with a missing name. + const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + return parsePropertyDeclaration(pos, hasJSDoc, modifiers, name, /*questionToken*/ undefined); + } + + // 'isClassMemberStart' should have hinted not to attempt parsing. + return Debug.fail("Should not have attempted to parse class member declaration."); + } + + function parseDecoratedExpression(): PrimaryExpression { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiers(/*allowDecorators*/ true); + if (token() === SyntaxKind.ClassKeyword) { + return parseClassDeclarationOrExpression(pos, hasJSDoc, modifiers, SyntaxKind.ClassExpression) as ClassExpression; + } + + const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Expression_expected); + setTextRangePos(missing, pos); + (missing as Mutable).modifiers = modifiers; + return missing; + } + + function parseClassExpression(): ClassExpression { + return parseClassDeclarationOrExpression(getNodePos(), hasPrecedingJSDocComment(), /*modifiers*/ undefined, SyntaxKind.ClassExpression) as ClassExpression; + } + + function parseClassDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ClassDeclaration { + return parseClassDeclarationOrExpression(pos, hasJSDoc, modifiers, SyntaxKind.ClassDeclaration) as ClassDeclaration; + } + + function parseClassDeclarationOrExpression(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, kind: ClassLikeDeclaration["kind"]): ClassLikeDeclaration { + const savedAwaitContext = inAwaitContext(); + parseExpected(SyntaxKind.ClassKeyword); + + // We don't parse the name here in await context, instead we will report a grammar error in the checker. + const name = parseNameOfClassDeclarationOrExpression(); + const typeParameters = parseTypeParameters(); + if (some(modifiers, isExportModifier)) setAwaitContext(/*value*/ true); + const heritageClauses = parseHeritageClauses(); + + let members; + if (parseExpected(SyntaxKind.OpenBraceToken)) { + // ClassTail[Yield,Await] : (Modified) See 14.5 + // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } + members = parseClassMembers(); + parseExpected(SyntaxKind.CloseBraceToken); + } + else { + members = createMissingList(); + } + setAwaitContext(savedAwaitContext); + const node = kind === SyntaxKind.ClassDeclaration + ? factory.createClassDeclaration(modifiers, name, typeParameters, heritageClauses, members) + : factory.createClassExpression(modifiers, name, typeParameters, heritageClauses, members); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseNameOfClassDeclarationOrExpression(): Identifier | undefined { + // implements is a future reserved word so + // 'class implements' might mean either + // - class expression with omitted name, 'implements' starts heritage clause + // - class with name 'implements' + // 'isImplementsClause' helps to disambiguate between these two cases + return isBindingIdentifier() && !isImplementsClause() + ? createIdentifier(isBindingIdentifier()) + : undefined; + } + + function isImplementsClause() { + return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword); + } + + function parseHeritageClauses(): NodeArray | undefined { + // ClassTail[Yield,Await] : (Modified) See 14.5 + // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } + + if (isHeritageClause()) { + return parseList(ParsingContext.HeritageClauses, parseHeritageClause); + } + + return undefined; + } + + function parseHeritageClause(): HeritageClause { + const pos = getNodePos(); + const tok = token(); + Debug.assert(tok === SyntaxKind.ExtendsKeyword || tok === SyntaxKind.ImplementsKeyword); // isListElement() should ensure this. + nextToken(); + const types = parseDelimitedList(ParsingContext.HeritageClauseElement, parseExpressionWithTypeArguments); + return finishNode(factory.createHeritageClause(tok, types), pos); + } + + function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments { + const pos = getNodePos(); + const expression = parseLeftHandSideExpressionOrHigher(); + if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { + return expression as ExpressionWithTypeArguments; + } + const typeArguments = tryParseTypeArguments(); + return finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); + } + + function tryParseTypeArguments(): NodeArray | undefined { + return token() === SyntaxKind.LessThanToken ? + parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken) : undefined; + } + + function isHeritageClause(): boolean { + return token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + } + + function parseClassMembers(): NodeArray { + return parseList(ParsingContext.ClassMembers, parseClassElement); + } + + function parseInterfaceDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): InterfaceDeclaration { + parseExpected(SyntaxKind.InterfaceKeyword); + const name = parseIdentifier(); + const typeParameters = parseTypeParameters(); + const heritageClauses = parseHeritageClauses(); + const members = parseObjectTypeMembers(); + const node = factory.createInterfaceDeclaration(modifiers, name, typeParameters, heritageClauses, members); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseTypeAliasDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): TypeAliasDeclaration { + parseExpected(SyntaxKind.TypeKeyword); + if (scanner.hasPrecedingLineBreak()) { + parseErrorAtCurrentToken(Diagnostics.Line_break_not_permitted_here); + } + const name = parseIdentifier(); + const typeParameters = parseTypeParameters(); + parseExpected(SyntaxKind.EqualsToken); + const type = token() === SyntaxKind.IntrinsicKeyword && tryParse(parseKeywordAndNoDot) || parseType(); + parseSemicolon(); + const node = factory.createTypeAliasDeclaration(modifiers, name, typeParameters, type); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + // In an ambient declaration, the grammar only allows integer literals as initializers. + // In a non-ambient declaration, the grammar allows uninitialized members only in a + // ConstantEnumMemberSection, which starts at the beginning of an enum declaration + // or any time an integer literal initializer is encountered. + function parseEnumMember(): EnumMember { + const pos = getNodePos(); + const hasJSDoc = hasPrecedingJSDocComment(); + const name = parsePropertyName(); + const initializer = allowInAnd(parseInitializer); + return withJSDoc(finishNode(factory.createEnumMember(name, initializer), pos), hasJSDoc); + } + + function parseEnumDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): EnumDeclaration { + parseExpected(SyntaxKind.EnumKeyword); + const name = parseIdentifier(); + let members; + if (parseExpected(SyntaxKind.OpenBraceToken)) { + members = doOutsideOfYieldAndAwaitContext(() => parseDelimitedList(ParsingContext.EnumMembers, parseEnumMember)); + parseExpected(SyntaxKind.CloseBraceToken); + } + else { + members = createMissingList(); + } + const node = factory.createEnumDeclaration(modifiers, name, members); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseModuleBlock(): ModuleBlock { + const pos = getNodePos(); + let statements; + if (parseExpected(SyntaxKind.OpenBraceToken)) { + statements = parseList(ParsingContext.BlockStatements, parseStatement); + parseExpected(SyntaxKind.CloseBraceToken); + } + else { + statements = createMissingList(); + } + return finishNode(factory.createModuleBlock(statements), pos); + } + + function parseModuleOrNamespaceDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, flags: NodeFlags): ModuleDeclaration { + // If we are parsing a dotted namespace name, we want to + // propagate the 'Namespace' flag across the names if set. + const namespaceFlag = flags & NodeFlags.Namespace; + const name = flags & NodeFlags.NestedNamespace ? parseIdentifierName() : parseIdentifier(); + const body = parseOptional(SyntaxKind.DotToken) + ? parseModuleOrNamespaceDeclaration(getNodePos(), /*hasJSDoc*/ false, /*modifiers*/ undefined, NodeFlags.NestedNamespace | namespaceFlag) as NamespaceDeclaration + : parseModuleBlock(); + const node = factory.createModuleDeclaration(modifiers, name, body, flags); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseAmbientExternalModuleDeclaration(pos: number, hasJSDoc: boolean, modifiersIn: NodeArray | undefined): ModuleDeclaration { + let flags: NodeFlags = 0; + let name; + if (token() === SyntaxKind.GlobalKeyword) { + // parse 'global' as name of global scope augmentation + name = parseIdentifier(); + flags |= NodeFlags.GlobalAugmentation; + } + else { + name = parseLiteralNode() as StringLiteral; + name.text = internIdentifier(name.text); + } + let body: ModuleBlock | undefined; + if (token() === SyntaxKind.OpenBraceToken) { + body = parseModuleBlock(); + } + else { + parseSemicolon(); + } + const node = factory.createModuleDeclaration(modifiersIn, name, body, flags); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseModuleDeclaration(pos: number, hasJSDoc: boolean, modifiersIn: NodeArray | undefined): ModuleDeclaration { + let flags: NodeFlags = 0; + if (token() === SyntaxKind.GlobalKeyword) { + // global augmentation + return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, modifiersIn); + } + else if (parseOptional(SyntaxKind.NamespaceKeyword)) { + flags |= NodeFlags.Namespace; + } + else { + parseExpected(SyntaxKind.ModuleKeyword); + if (token() === SyntaxKind.StringLiteral) { + return parseAmbientExternalModuleDeclaration(pos, hasJSDoc, modifiersIn); + } + } + return parseModuleOrNamespaceDeclaration(pos, hasJSDoc, modifiersIn, flags); + } + + function isExternalModuleReference() { + return token() === SyntaxKind.RequireKeyword && + lookAhead(nextTokenIsOpenParen); + } + + function nextTokenIsOpenParen() { + return nextToken() === SyntaxKind.OpenParenToken; + } + + function nextTokenIsOpenBrace() { + return nextToken() === SyntaxKind.OpenBraceToken; + } + + function nextTokenIsSlash() { + return nextToken() === SyntaxKind.SlashToken; + } + + function parseNamespaceExportDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): NamespaceExportDeclaration { + parseExpected(SyntaxKind.AsKeyword); + parseExpected(SyntaxKind.NamespaceKeyword); + const name = parseIdentifier(); + parseSemicolon(); + const node = factory.createNamespaceExportDeclaration(name); + // NamespaceExportDeclaration nodes cannot have decorators or modifiers, so we attach them here so we can report them in the grammar checker + (node as Mutable).modifiers = modifiers; + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseImportDeclarationOrImportEqualsDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ImportEqualsDeclaration | ImportDeclaration { + parseExpected(SyntaxKind.ImportKeyword); + + const afterImportPos = scanner.getTokenFullStart(); + + // We don't parse the identifier here in await context, instead we will report a grammar error in the checker. + let identifier: Identifier | undefined; + if (isIdentifier()) { + identifier = parseIdentifier(); + } + + let phaseModifier: ImportPhaseModifierSyntaxKind | undefined; + if ( + identifier?.escapedText === "type" && + (token() !== SyntaxKind.FromKeyword || isIdentifier() && lookAhead(nextTokenIsFromKeywordOrEqualsToken)) && + (isIdentifier() || tokenAfterImportDefinitelyProducesImportDeclaration()) + ) { + phaseModifier = SyntaxKind.TypeKeyword; + identifier = isIdentifier() ? parseIdentifier() : undefined; + } + else if ( + identifier?.escapedText === "defer" && + (token() === SyntaxKind.FromKeyword ? !lookAhead(nextTokenIsStringLiteral) : token() !== SyntaxKind.CommaToken && token() !== SyntaxKind.EqualsToken) + ) { + phaseModifier = SyntaxKind.DeferKeyword; + identifier = isIdentifier() ? parseIdentifier() : undefined; + } + + if (identifier && !tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() && phaseModifier !== SyntaxKind.DeferKeyword) { + return parseImportEqualsDeclaration(pos, hasJSDoc, modifiers, identifier, phaseModifier === SyntaxKind.TypeKeyword); + } + + const importClause = tryParseImportClause(identifier, afterImportPos, phaseModifier, /*skipJsDocLeadingAsterisks*/ undefined); + const moduleSpecifier = parseModuleSpecifier(); + const attributes = tryParseImportAttributes(); + + parseSemicolon(); + const node = factory.createImportDeclaration(modifiers, importClause, moduleSpecifier, attributes); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function tryParseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifierSyntaxKind, skipJsDocLeadingAsterisks = false) { + // ImportDeclaration: + // import ImportClause from ModuleSpecifier ; + // import ModuleSpecifier; + let importClause: ImportClause | undefined; + if ( + identifier || // import id + token() === SyntaxKind.AsteriskToken || // import * + token() === SyntaxKind.OpenBraceToken // import { + ) { + importClause = parseImportClause(identifier, pos, phaseModifier, skipJsDocLeadingAsterisks); + parseExpected(SyntaxKind.FromKeyword); + } + return importClause; + } + + function tryParseImportAttributes() { + const currentToken = token(); + if (currentToken === SyntaxKind.WithKeyword || (currentToken === SyntaxKind.AssertKeyword && !scanner.hasPrecedingLineBreak())) { + return parseImportAttributes(currentToken); + } + } + + function parseImportAttribute() { + const pos = getNodePos(); + const name = tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral; + parseExpected(SyntaxKind.ColonToken); + const value = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); + return finishNode(factory.createImportAttribute(name, value), pos); + } + + function parseImportAttributes(token: SyntaxKind.AssertKeyword | SyntaxKind.WithKeyword, skipKeyword?: true) { + const pos = getNodePos(); + if (!skipKeyword) { + parseExpected(token); + } + const openBracePosition = scanner.getTokenStart(); + if (parseExpected(SyntaxKind.OpenBraceToken)) { + const multiLine = scanner.hasPrecedingLineBreak(); + const elements = parseDelimitedList(ParsingContext.ImportAttributes, parseImportAttribute, /*considerSemicolonAsDelimiter*/ true); + if (!parseExpected(SyntaxKind.CloseBraceToken)) { + const lastError = lastOrUndefined(parseDiagnostics); + if (lastError && lastError.code === Diagnostics._0_expected.code) { + addRelatedInfo( + lastError, + createDetachedDiagnostic(fileName, sourceText, openBracePosition, 1, Diagnostics.The_parser_expected_to_find_a_1_to_match_the_0_token_here, "{", "}"), + ); + } + } + return finishNode(factory.createImportAttributes(elements, multiLine, token), pos); + } + else { + const elements = createNodeArray([], getNodePos(), /*end*/ undefined, /*hasTrailingComma*/ false); + return finishNode(factory.createImportAttributes(elements, /*multiLine*/ false, token), pos); + } + } + + function tokenAfterImportDefinitelyProducesImportDeclaration() { + return token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.OpenBraceToken; + } + + function tokenAfterImportedIdentifierDefinitelyProducesImportDeclaration() { + // In `import id ___`, the current token decides whether to produce + // an ImportDeclaration or ImportEqualsDeclaration. + return token() === SyntaxKind.CommaToken || token() === SyntaxKind.FromKeyword; + } + + function parseImportEqualsDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined, identifier: Identifier, isTypeOnly: boolean): ImportEqualsDeclaration { + parseExpected(SyntaxKind.EqualsToken); + const moduleReference = parseModuleReference(); + parseSemicolon(); + const node = factory.createImportEqualsDeclaration(modifiers, isTypeOnly, identifier, moduleReference); + const finished = withJSDoc(finishNode(node, pos), hasJSDoc); + return finished; + } + + function parseImportClause(identifier: Identifier | undefined, pos: number, phaseModifier: undefined | ImportPhaseModifierSyntaxKind, skipJsDocLeadingAsterisks: boolean) { + // ImportClause: + // ImportedDefaultBinding + // NameSpaceImport + // NamedImports + // ImportedDefaultBinding, NameSpaceImport + // ImportedDefaultBinding, NamedImports + + // If there was no default import or if there is comma token after default import + // parse namespace or named imports + let namedBindings: NamespaceImport | NamedImports | undefined; + if ( + !identifier || + parseOptional(SyntaxKind.CommaToken) + ) { + if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(true); + if (token() === SyntaxKind.AsteriskToken) { + namedBindings = parseNamespaceImport(); + } + else { + namedBindings = parseNamedImportsOrExports(SyntaxKind.NamedImports); + } + if (skipJsDocLeadingAsterisks) scanner.setSkipJsDocLeadingAsterisks(false); + } + + return finishNode(factory.createImportClause(phaseModifier, identifier, namedBindings), pos); + } + + function parseModuleReference() { + return isExternalModuleReference() + ? parseExternalModuleReference() + : parseEntityName(/*allowReservedWords*/ false); + } + + function parseExternalModuleReference() { + const pos = getNodePos(); + parseExpected(SyntaxKind.RequireKeyword); + parseExpected(SyntaxKind.OpenParenToken); + const expression = parseModuleSpecifier(); + parseExpected(SyntaxKind.CloseParenToken); + return finishNode(factory.createExternalModuleReference(expression), pos); + } + + function parseModuleSpecifier(): Expression { + if (token() === SyntaxKind.StringLiteral) { + const result = parseLiteralNode(); + result.text = internIdentifier(result.text); + return result; + } + else { + // We allow arbitrary expressions here, even though the grammar only allows string + // literals. We check to ensure that it is only a string literal later in the grammar + // check pass. + return parseExpression(); + } + } + + function parseNamespaceImport(): NamespaceImport { + // NameSpaceImport: + // * as ImportedBinding + const pos = getNodePos(); + parseExpected(SyntaxKind.AsteriskToken); + parseExpected(SyntaxKind.AsKeyword); + const name = parseIdentifier(); + return finishNode(factory.createNamespaceImport(name), pos); + } + + function canParseModuleExportName(): boolean { + return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral; + } + + function parseModuleExportName(parseName: () => Identifier): ModuleExportName { + return token() === SyntaxKind.StringLiteral ? parseLiteralNode() as StringLiteral : parseName(); + } + + function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports; + function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports; + function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports { + const pos = getNodePos(); + + // NamedImports: + // { } + // { ImportsList } + // { ImportsList, } + + // ImportsList: + // ImportSpecifier + // ImportsList, ImportSpecifier + const node = kind === SyntaxKind.NamedImports + ? factory.createNamedImports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseImportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)) + : factory.createNamedExports(parseBracketedList(ParsingContext.ImportOrExportSpecifiers, parseExportSpecifier, SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken)); + return finishNode(node, pos); + } + + function parseExportSpecifier() { + const hasJSDoc = hasPrecedingJSDocComment(); + return withJSDoc(parseImportOrExportSpecifier(SyntaxKind.ExportSpecifier) as ExportSpecifier, hasJSDoc); + } + + function parseImportSpecifier() { + return parseImportOrExportSpecifier(SyntaxKind.ImportSpecifier) as ImportSpecifier; + } + + function parseImportOrExportSpecifier(kind: SyntaxKind): ImportOrExportSpecifier { + const pos = getNodePos(); + // ImportSpecifier: + // BindingIdentifier + // ModuleExportName as BindingIdentifier + // ExportSpecifier: + // ModuleExportName + // ModuleExportName as ModuleExportName + let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); + let checkIdentifierStart = scanner.getTokenStart(); + let checkIdentifierEnd = scanner.getTokenEnd(); + let isTypeOnly = false; + let propertyName: ModuleExportName | undefined; + let canParseAsKeyword = true; + let name = parseModuleExportName(parseIdentifierName); + if (name.kind === SyntaxKind.Identifier && name.escapedText === "type") { + // If the first token of an import specifier is 'type', there are a lot of possibilities, + // especially if we see 'as' afterwards: + // + // import { type } from "mod"; - isTypeOnly: false, name: type + // import { type as } from "mod"; - isTypeOnly: true, name: as + // import { type as as } from "mod"; - isTypeOnly: false, name: as, propertyName: type + // import { type as as as } from "mod"; - isTypeOnly: true, name: as, propertyName: as + if (token() === SyntaxKind.AsKeyword) { + // { type as ...? } + const firstAs = parseIdentifierName(); + if (token() === SyntaxKind.AsKeyword) { + // { type as as ...? } + const secondAs = parseIdentifierName(); + if (canParseModuleExportName()) { + // { type as as something } + // { type as as "something" } + isTypeOnly = true; + propertyName = firstAs; + name = parseModuleExportName(parseNameWithKeywordCheck); + canParseAsKeyword = false; + } + else { + // { type as as } + propertyName = name; + name = secondAs; + canParseAsKeyword = false; + } + } + else if (canParseModuleExportName()) { + // { type as something } + // { type as "something" } + propertyName = name; + canParseAsKeyword = false; + name = parseModuleExportName(parseNameWithKeywordCheck); + } + else { + // { type as } + isTypeOnly = true; + name = firstAs; + } + } + else if (canParseModuleExportName()) { + // { type something ...? } + // { type "something" ...? } + isTypeOnly = true; + name = parseModuleExportName(parseNameWithKeywordCheck); + } + } + + if (canParseAsKeyword && token() === SyntaxKind.AsKeyword) { + propertyName = name; + parseExpected(SyntaxKind.AsKeyword); + name = parseModuleExportName(parseNameWithKeywordCheck); + } + if (kind === SyntaxKind.ImportSpecifier) { + if (name.kind !== SyntaxKind.Identifier) { + // ImportSpecifier casts "name" to Identifier below, so make sure it's an identifier + parseErrorAt(skipTrivia(sourceText, name.pos), name.end, Diagnostics.Identifier_expected); + name = setTextRangePosEnd(createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false), name.pos, name.pos); + } + else if (checkIdentifierIsKeyword) { + parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected); + } + } + const node = kind === SyntaxKind.ImportSpecifier + ? factory.createImportSpecifier(isTypeOnly, propertyName, name as Identifier) + : factory.createExportSpecifier(isTypeOnly, propertyName, name); + return finishNode(node, pos); + + function parseNameWithKeywordCheck() { + checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier(); + checkIdentifierStart = scanner.getTokenStart(); + checkIdentifierEnd = scanner.getTokenEnd(); + return parseIdentifierName(); + } + } + + function parseNamespaceExport(pos: number): NamespaceExport { + return finishNode(factory.createNamespaceExport(parseModuleExportName(parseIdentifierName)), pos); + } + + function parseExportDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ExportDeclaration { + const savedAwaitContext = inAwaitContext(); + setAwaitContext(/*value*/ true); + let exportClause: NamedExportBindings | undefined; + let moduleSpecifier: Expression | undefined; + let attributes: ImportAttributes | undefined; + const isTypeOnly = parseOptional(SyntaxKind.TypeKeyword); + const namespaceExportPos = getNodePos(); + if (parseOptional(SyntaxKind.AsteriskToken)) { + if (parseOptional(SyntaxKind.AsKeyword)) { + exportClause = parseNamespaceExport(namespaceExportPos); + } + parseExpected(SyntaxKind.FromKeyword); + moduleSpecifier = parseModuleSpecifier(); + } + else { + exportClause = parseNamedImportsOrExports(SyntaxKind.NamedExports); + // It is not uncommon to accidentally omit the 'from' keyword. Additionally, in editing scenarios, + // the 'from' keyword can be parsed as a named export when the export clause is unterminated (i.e. `export { from "moduleName";`) + // If we don't have a 'from' keyword, see if we have a string literal such that ASI won't take effect. + if (token() === SyntaxKind.FromKeyword || (token() === SyntaxKind.StringLiteral && !scanner.hasPrecedingLineBreak())) { + parseExpected(SyntaxKind.FromKeyword); + moduleSpecifier = parseModuleSpecifier(); + } + } + const currentToken = token(); + if (moduleSpecifier && (currentToken === SyntaxKind.WithKeyword || currentToken === SyntaxKind.AssertKeyword) && !scanner.hasPrecedingLineBreak()) { + attributes = parseImportAttributes(currentToken); + } + parseSemicolon(); + setAwaitContext(savedAwaitContext); + const node = factory.createExportDeclaration(modifiers, isTypeOnly, exportClause, moduleSpecifier, attributes); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + function parseExportAssignment(pos: number, hasJSDoc: boolean, modifiers: NodeArray | undefined): ExportAssignment { + const savedAwaitContext = inAwaitContext(); + setAwaitContext(/*value*/ true); + let isExportEquals: boolean | undefined; + if (parseOptional(SyntaxKind.EqualsToken)) { + isExportEquals = true; + } + else { + parseExpected(SyntaxKind.DefaultKeyword); + } + const expression = parseAssignmentExpressionOrHigher(/*allowReturnTypeInArrowFunction*/ true); + parseSemicolon(); + setAwaitContext(savedAwaitContext); + const node = factory.createExportAssignment(modifiers, isExportEquals, expression); + return withJSDoc(finishNode(node, pos), hasJSDoc); + } + + // dprint-ignore + const enum ParsingContext { + SourceElements, // Elements in source file + BlockStatements, // Statements in block + SwitchClauses, // Clauses in switch statement + SwitchClauseStatements, // Statements in switch clause + TypeMembers, // Members in interface or type literal + ClassMembers, // Members in class declaration + EnumMembers, // Members in enum declaration + HeritageClauseElement, // Elements in a heritage clause + VariableDeclarations, // Variable declarations in variable statement + ObjectBindingElements, // Binding elements in object binding list + ArrayBindingElements, // Binding elements in array binding list + ArgumentExpressions, // Expressions in argument list + ObjectLiteralMembers, // Members in object literal + JsxAttributes, // Attributes in jsx element + JsxChildren, // Things between opening and closing JSX tags + ArrayLiteralMembers, // Members in array literal + Parameters, // Parameters in parameter list + JSDocParameters, // JSDoc parameters in parameter list of JSDoc function type + RestProperties, // Property names in a rest type list + TypeParameters, // Type parameters in type parameter list + TypeArguments, // Type arguments in type argument list + TupleElementTypes, // Element types in tuple element type list + HeritageClauses, // Heritage clauses for a class or interface declaration. + ImportOrExportSpecifiers, // Named import clause's import specifier list, + ImportAttributes, // Import attributes + JSDocComment, // Parsing via JSDocParser + Count, // Number of parsing contexts + } + + const enum Tristate { + False, + True, + Unknown, + } + + export namespace JSDocParser { + export function parseJSDocTypeExpressionForTests(content: string, start: number | undefined, length: number | undefined): { jsDocTypeExpression: JSDocTypeExpression; diagnostics: Diagnostic[]; } | undefined { + initializeState("file.js", content, ScriptTarget.Latest, /*syntaxCursor*/ undefined, ScriptKind.JS, JSDocParsingMode.ParseAll); + scanner.setText(content, start, length); + currentToken = scanner.scan(); + const jsDocTypeExpression = parseJSDocTypeExpression(); + + const sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS, /*isDeclarationFile*/ false, [], factoryCreateToken(SyntaxKind.EndOfFileToken), NodeFlags.None, noop); + const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + if (jsDocDiagnostics) { + sourceFile.jsDocDiagnostics = attachFileToDiagnostics(jsDocDiagnostics, sourceFile); + } + + clearState(); + + return jsDocTypeExpression ? { jsDocTypeExpression, diagnostics } : undefined; + } + + // Parses out a JSDoc type expression. + export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression { + const pos = getNodePos(); + const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken); + const type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); + if (!mayOmitBraces || hasBrace) { + parseExpectedJSDoc(SyntaxKind.CloseBraceToken); + } + + const result = factory.createJSDocTypeExpression(type); + fixupParentReferences(result); + return finishNode(result, pos); + } + + export function parseJSDocNameReference(): JSDocNameReference { + const pos = getNodePos(); + const hasBrace = parseOptional(SyntaxKind.OpenBraceToken); + const p2 = getNodePos(); + let entityName: EntityName | JSDocMemberName = parseEntityName(/*allowReservedWords*/ false); + while (token() === SyntaxKind.PrivateIdentifier) { + reScanHashToken(); // rescan #id as # id + nextTokenJSDoc(); // then skip the # + entityName = finishNode(factory.createJSDocMemberName(entityName, parseIdentifier()), p2); + } + if (hasBrace) { + parseExpectedJSDoc(SyntaxKind.CloseBraceToken); + } + + const result = factory.createJSDocNameReference(entityName); + fixupParentReferences(result); + return finishNode(result, pos); + } + + export function parseIsolatedJSDocComment(content: string, start: number | undefined, length: number | undefined): { jsDoc: JSDoc; diagnostics: Diagnostic[]; } | undefined { + initializeState("", content, ScriptTarget.Latest, /*syntaxCursor*/ undefined, ScriptKind.JS, JSDocParsingMode.ParseAll); + const jsDoc = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); + + const sourceFile = { languageVariant: LanguageVariant.Standard, text: content } as SourceFile; + const diagnostics = attachFileToDiagnostics(parseDiagnostics, sourceFile); + clearState(); + + return jsDoc ? { jsDoc, diagnostics } : undefined; + } + + export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc | undefined { + const saveToken = currentToken; + const saveParseDiagnosticsLength = parseDiagnostics.length; + const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; + + const comment = doInsideOfContext(NodeFlags.JSDoc, () => parseJSDocCommentWorker(start, length)); + setParent(comment, parent); + + if (contextFlags & NodeFlags.JavaScriptFile) { + if (!jsDocDiagnostics) { + jsDocDiagnostics = []; + } + addRange(jsDocDiagnostics, parseDiagnostics, saveParseDiagnosticsLength); + } + currentToken = saveToken; + parseDiagnostics.length = saveParseDiagnosticsLength; + parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; + return comment; + } + + const enum JSDocState { + BeginningOfLine, + SawAsterisk, + SavingComments, + SavingBackticks, // NOTE: Only used when parsing tag comments + } + + const enum PropertyLikeParse { + Property = 1 << 0, + Parameter = 1 << 1, + CallbackParameter = 1 << 2, + } + + function parseJSDocCommentWorker(start = 0, length: number | undefined): JSDoc | undefined { + const content = sourceText; + const end = length === undefined ? content.length : start + length; + length = end - start; + + Debug.assert(start >= 0); + Debug.assert(start <= end); + Debug.assert(end <= content.length); + + // Check for /** (JSDoc opening part) + if (!isJSDocLikeText(content, start)) { + return undefined; + } + + let tags: JSDocTag[]; + let tagsPos: number; + let tagsEnd: number; + let linkEnd: number; + let commentsPos: number | undefined; + let comments: string[] = []; + const parts: JSDocComment[] = []; + + const saveParsingContext = parsingContext; + parsingContext |= 1 << ParsingContext.JSDocComment; + + // + 3 for leading /**, - 5 in total for /** */ + const result = scanner.scanRange(start + 3, length - 5, doJSDocScan); + parsingContext = saveParsingContext; + return result; + + function doJSDocScan() { + // Initially we can parse out a tag. We also have seen a starting asterisk. + // This is so that /** * @type */ doesn't parse. + let state = JSDocState.SawAsterisk; + let margin: number | undefined; + // + 4 for leading '/** ' + // + 1 because the last index of \n is always one index before the first character in the line and coincidentally, if there is no \n before start, it is -1, which is also one index before the first character + let indent = start - (content.lastIndexOf("\n", start) + 1) + 4; + function pushComment(text: string) { + if (!margin) { + margin = indent; + } + comments.push(text); + indent += text.length; + } + + nextTokenJSDoc(); + while (parseOptionalJsdoc(SyntaxKind.WhitespaceTrivia)); + if (parseOptionalJsdoc(SyntaxKind.NewLineTrivia)) { + state = JSDocState.BeginningOfLine; + indent = 0; + } + loop: + while (true) { + switch (token()) { + case SyntaxKind.AtToken: + removeTrailingWhitespace(comments); + if (!commentsPos) commentsPos = getNodePos(); + addTag(parseTag(indent)); + // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. + // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning + // for malformed examples like `/** @param {string} x @returns {number} the length */` + state = JSDocState.BeginningOfLine; + margin = undefined; + break; + case SyntaxKind.NewLineTrivia: + comments.push(scanner.getTokenText()); + state = JSDocState.BeginningOfLine; + indent = 0; + break; + case SyntaxKind.AsteriskToken: + const asterisk = scanner.getTokenText(); + if (state === JSDocState.SawAsterisk) { + // If we've already seen an asterisk, then we can no longer parse a tag on this line + state = JSDocState.SavingComments; + pushComment(asterisk); + } + else { + Debug.assert(state === JSDocState.BeginningOfLine); + // Ignore the first asterisk on a line + state = JSDocState.SawAsterisk; + indent += asterisk.length; + } + break; + case SyntaxKind.WhitespaceTrivia: + Debug.assert(state !== JSDocState.SavingComments, "whitespace shouldn't come from the scanner while saving top-level comment text"); + // only collect whitespace if we're already saving comments or have just crossed the comment indent margin + const whitespace = scanner.getTokenText(); + if (margin !== undefined && indent + whitespace.length > margin) { + comments.push(whitespace.slice(margin - indent)); + } + indent += whitespace.length; + break; + case SyntaxKind.EndOfFileToken: + break loop; + case SyntaxKind.JSDocCommentTextToken: + state = JSDocState.SavingComments; + pushComment(scanner.getTokenValue()); + break; + case SyntaxKind.OpenBraceToken: + state = JSDocState.SavingComments; + const commentEnd = scanner.getTokenFullStart(); + const linkStart = scanner.getTokenEnd() - 1; + const link = parseJSDocLink(linkStart); + if (link) { + if (!linkEnd) { + removeLeadingNewlines(comments); + } + parts.push(finishNode(factory.createJSDocText(comments.join("")), linkEnd ?? start, commentEnd)); + parts.push(link); + comments = []; + linkEnd = scanner.getTokenEnd(); + break; + } + // fallthrough if it's not a {@link sequence + default: + // Anything else is doc comment text. We just save it. Because it + // wasn't a tag, we can no longer parse a tag on this line until we hit the next + // line break. + state = JSDocState.SavingComments; + pushComment(scanner.getTokenText()); + break; + } + if (state === JSDocState.SavingComments) { + nextJSDocCommentTextToken(/*inBackticks*/ false); + } + else { + nextTokenJSDoc(); + } + } + const trimmedComments = comments.join("").trimEnd(); + if (parts.length && trimmedComments.length) { + parts.push(finishNode(factory.createJSDocText(trimmedComments), linkEnd ?? start, commentsPos)); + } + if (parts.length && tags) Debug.assertIsDefined(commentsPos, "having parsed tags implies that the end of the comment span should be set"); + const tagsArray = tags && createNodeArray(tags, tagsPos, tagsEnd); + return finishNode(factory.createJSDocComment(parts.length ? createNodeArray(parts, start, commentsPos) : trimmedComments.length ? trimmedComments : undefined, tagsArray), start, end); + } + + function removeLeadingNewlines(comments: string[]) { + while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) { + comments.shift(); + } + } + + function removeTrailingWhitespace(comments: string[]) { + while (comments.length) { + const trimmed = comments[comments.length - 1].trimEnd(); + if (trimmed === "") { + comments.pop(); + } + else if (trimmed.length < comments[comments.length - 1].length) { + comments[comments.length - 1] = trimmed; + break; + } + else { + break; + } + } + } + + function isNextNonwhitespaceTokenEndOfFile(): boolean { + // We must use infinite lookahead, as there could be any number of newlines :( + while (true) { + nextTokenJSDoc(); + if (token() === SyntaxKind.EndOfFileToken) { + return true; + } + if (!(token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia)) { + return false; + } + } + } + + function skipWhitespace(): void { + if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { + return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range + } + } + while (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + nextTokenJSDoc(); + } + } + + function skipWhitespaceOrAsterisk(): string { + if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) { + return ""; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range + } + } + + let precedingLineBreak = scanner.hasPrecedingLineBreak(); + let seenLineBreak = false; + let indentText = ""; + while ((precedingLineBreak && token() === SyntaxKind.AsteriskToken) || token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) { + indentText += scanner.getTokenText(); + if (token() === SyntaxKind.NewLineTrivia) { + precedingLineBreak = true; + seenLineBreak = true; + indentText = ""; + } + else if (token() === SyntaxKind.AsteriskToken) { + precedingLineBreak = false; + } + nextTokenJSDoc(); + } + return seenLineBreak ? indentText : ""; + } + + function parseTag(margin: number) { + Debug.assert(token() === SyntaxKind.AtToken); + const start = scanner.getTokenStart(); + nextTokenJSDoc(); + + const tagName = parseJSDocIdentifierName(/*message*/ undefined); + const indentText = skipWhitespaceOrAsterisk(); + + let tag: JSDocTag | undefined; + switch (tagName.escapedText) { + case "author": + tag = parseAuthorTag(start, tagName, margin, indentText); + break; + case "implements": + tag = parseImplementsTag(start, tagName, margin, indentText); + break; + case "augments": + case "extends": + tag = parseAugmentsTag(start, tagName, margin, indentText); + break; + case "class": + case "constructor": + tag = parseSimpleTag(start, factory.createJSDocClassTag, tagName, margin, indentText); + break; + case "public": + tag = parseSimpleTag(start, factory.createJSDocPublicTag, tagName, margin, indentText); + break; + case "private": + tag = parseSimpleTag(start, factory.createJSDocPrivateTag, tagName, margin, indentText); + break; + case "protected": + tag = parseSimpleTag(start, factory.createJSDocProtectedTag, tagName, margin, indentText); + break; + case "readonly": + tag = parseSimpleTag(start, factory.createJSDocReadonlyTag, tagName, margin, indentText); + break; + case "override": + tag = parseSimpleTag(start, factory.createJSDocOverrideTag, tagName, margin, indentText); + break; + case "deprecated": + hasDeprecatedTag = true; + tag = parseSimpleTag(start, factory.createJSDocDeprecatedTag, tagName, margin, indentText); + break; + case "this": + tag = parseThisTag(start, tagName, margin, indentText); + break; + case "enum": + tag = parseEnumTag(start, tagName, margin, indentText); + break; + case "arg": + case "argument": + case "param": + return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, margin); + case "return": + case "returns": + tag = parseReturnTag(start, tagName, margin, indentText); + break; + case "template": + tag = parseTemplateTag(start, tagName, margin, indentText); + break; + case "type": + tag = parseTypeTag(start, tagName, margin, indentText); + break; + case "typedef": + tag = parseTypedefTag(start, tagName, margin, indentText); + break; + case "callback": + tag = parseCallbackTag(start, tagName, margin, indentText); + break; + case "overload": + tag = parseOverloadTag(start, tagName, margin, indentText); + break; + case "satisfies": + tag = parseSatisfiesTag(start, tagName, margin, indentText); + break; + case "see": + tag = parseSeeTag(start, tagName, margin, indentText); + break; + case "exception": + case "throws": + tag = parseThrowsTag(start, tagName, margin, indentText); + break; + case "import": + tag = parseImportTag(start, tagName, margin, indentText); + break; + default: + tag = parseUnknownTag(start, tagName, margin, indentText); + break; + } + return tag; + } + + function parseTrailingTagComments(pos: number, end: number, margin: number, indentText: string) { + // some tags, like typedef and callback, have already parsed their comments earlier + if (!indentText) { + margin += end - pos; + } + return parseTagComments(margin, indentText.slice(margin)); + } + + function parseTagComments(indent: number, initialMargin?: string): string | NodeArray | undefined { + const commentsPos = getNodePos(); + let comments: string[] = []; + const parts: JSDocComment[] = []; + let linkEnd; + let state = JSDocState.BeginningOfLine; + let margin: number | undefined; + function pushComment(text: string) { + if (!margin) { + margin = indent; + } + comments.push(text); + indent += text.length; + } + if (initialMargin !== undefined) { + // jump straight to saving comments if there is some initial indentation + if (initialMargin !== "") { + pushComment(initialMargin); + } + state = JSDocState.SawAsterisk; + } + let tok = token() as JSDocSyntaxKind | SyntaxKind.JSDocCommentTextToken; + loop: + while (true) { + switch (tok) { + case SyntaxKind.NewLineTrivia: + state = JSDocState.BeginningOfLine; + // don't use pushComment here because we want to keep the margin unchanged + comments.push(scanner.getTokenText()); + indent = 0; + break; + case SyntaxKind.AtToken: + scanner.resetTokenState(scanner.getTokenEnd() - 1); + break loop; + case SyntaxKind.EndOfFileToken: + // Done + break loop; + case SyntaxKind.WhitespaceTrivia: + Debug.assert(state !== JSDocState.SavingComments && state !== JSDocState.SavingBackticks, "whitespace shouldn't come from the scanner while saving comment text"); + const whitespace = scanner.getTokenText(); + // if the whitespace crosses the margin, take only the whitespace that passes the margin + if (margin !== undefined && indent + whitespace.length > margin) { + comments.push(whitespace.slice(margin - indent)); + state = JSDocState.SavingComments; + } + indent += whitespace.length; + break; + case SyntaxKind.OpenBraceToken: + state = JSDocState.SavingComments; + const commentEnd = scanner.getTokenFullStart(); + const linkStart = scanner.getTokenEnd() - 1; + const link = parseJSDocLink(linkStart); + if (link) { + parts.push(finishNode(factory.createJSDocText(comments.join("")), linkEnd ?? commentsPos, commentEnd)); + parts.push(link); + comments = []; + linkEnd = scanner.getTokenEnd(); + } + else { + pushComment(scanner.getTokenText()); + } + break; + case SyntaxKind.BacktickToken: + if (state === JSDocState.SavingBackticks) { + state = JSDocState.SavingComments; + } + else { + state = JSDocState.SavingBackticks; + } + pushComment(scanner.getTokenText()); + break; + case SyntaxKind.JSDocCommentTextToken: + if (state !== JSDocState.SavingBackticks) { + state = JSDocState.SavingComments; // leading identifiers start recording as well + } + pushComment(scanner.getTokenValue()); + break; + case SyntaxKind.AsteriskToken: + if (state === JSDocState.BeginningOfLine) { + // leading asterisks start recording on the *next* (non-whitespace) token + state = JSDocState.SawAsterisk; + indent += 1; + break; + } + // record the * as a comment + // falls through + default: + if (state !== JSDocState.SavingBackticks) { + state = JSDocState.SavingComments; // leading identifiers start recording as well + } + pushComment(scanner.getTokenText()); + break; + } + if (state === JSDocState.SavingComments || state === JSDocState.SavingBackticks) { + tok = nextJSDocCommentTextToken(state === JSDocState.SavingBackticks); + } + else { + tok = nextTokenJSDoc(); + } + } + + removeLeadingNewlines(comments); + const trimmedComments = comments.join("").trimEnd(); + if (parts.length) { + if (trimmedComments.length) { + parts.push(finishNode(factory.createJSDocText(trimmedComments), linkEnd ?? commentsPos)); + } + return createNodeArray(parts, commentsPos, scanner.getTokenEnd()); + } + else if (trimmedComments.length) { + return trimmedComments; + } + } + + function parseJSDocLink(start: number) { + const linkType = tryParse(parseJSDocLinkPrefix); + if (!linkType) { + return undefined; + } + nextTokenJSDoc(); // start at token after link, then skip any whitespace + skipWhitespace(); + const name = parseJSDocLinkName(); + const text = []; + while (token() !== SyntaxKind.CloseBraceToken && token() !== SyntaxKind.NewLineTrivia && token() !== SyntaxKind.EndOfFileToken) { + text.push(scanner.getTokenText()); + nextTokenJSDoc(); + } + const create = linkType === "link" ? factory.createJSDocLink + : linkType === "linkcode" ? factory.createJSDocLinkCode + : factory.createJSDocLinkPlain; + return finishNode(create(name, text.join("")), start, scanner.getTokenEnd()); + } + + function parseJSDocLinkName() { + if (tokenIsIdentifierOrKeyword(token())) { + const pos = getNodePos(); + + let name: EntityName | JSDocMemberName = parseIdentifierName(); + while (parseOptional(SyntaxKind.DotToken)) { + name = finishNode(factory.createQualifiedName(name, token() === SyntaxKind.PrivateIdentifier ? createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false) : parseIdentifierName()), pos); + } + while (token() === SyntaxKind.PrivateIdentifier) { + reScanHashToken(); + nextTokenJSDoc(); + name = finishNode(factory.createJSDocMemberName(name, parseIdentifier()), pos); + } + return name; + } + return undefined; + } + + function parseJSDocLinkPrefix() { + skipWhitespaceOrAsterisk(); + if ( + token() === SyntaxKind.OpenBraceToken + && nextTokenJSDoc() === SyntaxKind.AtToken + && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) + ) { + const kind = scanner.getTokenValue(); + if (isJSDocLinkTag(kind)) return kind; + } + } + + function isJSDocLinkTag(kind: string) { + return kind === "link" || kind === "linkcode" || kind === "linkplain"; + } + + function parseUnknownTag(start: number, tagName: Identifier, indent: number, indentText: string) { + return finishNode(factory.createJSDocUnknownTag(tagName, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); + } + + function addTag(tag: JSDocTag | undefined): void { + if (!tag) { + return; + } + if (!tags) { + tags = [tag]; + tagsPos = tag.pos; + } + else { + tags.push(tag); + } + tagsEnd = tag.end; + } + + function tryParseTypeExpression(): JSDocTypeExpression | undefined { + skipWhitespaceOrAsterisk(); + return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; + } + + function parseBracketNameInPropertyAndParamTag(): { name: EntityName; isBracketed: boolean; } { + // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' + const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); + if (isBracketed) { + skipWhitespace(); + } + // a markdown-quoted name: `arg` is not legal jsdoc, but occurs in the wild + const isBackquoted = parseOptionalJsdoc(SyntaxKind.BacktickToken); + const name = parseJSDocEntityName(); + if (isBackquoted) { + parseExpectedTokenJSDoc(SyntaxKind.BacktickToken); + } + if (isBracketed) { + skipWhitespace(); + // May have an optional default, e.g. '[foo = 42]' + if (parseOptionalToken(SyntaxKind.EqualsToken)) { + parseExpression(); + } + + parseExpected(SyntaxKind.CloseBracketToken); + } + + return { name, isBracketed }; + } + + function isObjectOrObjectArrayTypeReference(node: TypeNode): boolean { + switch (node.kind) { + case SyntaxKind.ObjectKeyword: + return true; + case SyntaxKind.ArrayType: + return isObjectOrObjectArrayTypeReference((node as ArrayTypeNode).elementType); + default: + return isTypeReferenceNode(node) && isIdentifierNode(node.typeName) && node.typeName.escapedText === "Object" && !node.typeArguments; + } + } + + function parseParameterOrPropertyTag(start: number, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag { + let typeExpression = tryParseTypeExpression(); + let isNameFirst = !typeExpression; + skipWhitespaceOrAsterisk(); + + const { name, isBracketed } = parseBracketNameInPropertyAndParamTag(); + const indentText = skipWhitespaceOrAsterisk(); + + if (isNameFirst && !lookAhead(parseJSDocLinkPrefix)) { + typeExpression = tryParseTypeExpression(); + } + + const comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); + + const nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name, target, indent); + if (nestedTypeLiteral) { + typeExpression = nestedTypeLiteral; + isNameFirst = true; + } + const result = target === PropertyLikeParse.Property + ? factory.createJSDocPropertyTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment) + : factory.createJSDocParameterTag(tagName, name, isBracketed, typeExpression, isNameFirst, comment); + return finishNode(result, start); + } + + function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) { + if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { + const pos = getNodePos(); + let child: JSDocPropertyLikeTag | JSDocTypeTag | JSDocTemplateTag | JSDocThisTag | false; + let children: JSDocPropertyLikeTag[] | undefined; + while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) { + if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) { + children = append(children, child); + } + else if (child.kind === SyntaxKind.JSDocTemplateTag) { + parseErrorAtRange(child.tagName, Diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag); + } + } + if (children) { + const literal = finishNode(factory.createJSDocTypeLiteral(children, typeExpression.type.kind === SyntaxKind.ArrayType), pos); + return finishNode(factory.createJSDocTypeExpression(literal), pos); + } + } + } + + function parseReturnTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocReturnTag { + if (some(tags, isJSDocReturnTag)) { + parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, unescapeLeadingUnderscores(tagName.escapedText)); + } + + const typeExpression = tryParseTypeExpression(); + return finishNode(factory.createJSDocReturnTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); + } + + function parseTypeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocTypeTag { + if (some(tags, isJSDocTypeTag)) { + parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, unescapeLeadingUnderscores(tagName.escapedText)); + } + + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); + const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), indent, indentText) : undefined; + return finishNode(factory.createJSDocTypeTag(tagName, typeExpression, comments), start); + } + + function parseSeeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocSeeTag { + const isMarkdownOrJSDocLink = token() === SyntaxKind.OpenBracketToken + || lookAhead(() => nextTokenJSDoc() === SyntaxKind.AtToken && tokenIsIdentifierOrKeyword(nextTokenJSDoc()) && isJSDocLinkTag(scanner.getTokenValue())); + const nameExpression = isMarkdownOrJSDocLink ? undefined : parseJSDocNameReference(); + const comments = indent !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), indent, indentText) : undefined; + return finishNode(factory.createJSDocSeeTag(tagName, nameExpression, comments), start); + } + + function parseThrowsTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocThrowsTag { + const typeExpression = tryParseTypeExpression(); + const comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); + return finishNode(factory.createJSDocThrowsTag(tagName, typeExpression, comment), start); + } + + function parseAuthorTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocAuthorTag { + const commentStart = getNodePos(); + const textOnly = parseAuthorNameAndEmail(); + let commentEnd = scanner.getTokenFullStart(); + const comments = parseTrailingTagComments(start, commentEnd, indent, indentText); + if (!comments) { + commentEnd = scanner.getTokenFullStart(); + } + const allParts = typeof comments !== "string" + ? createNodeArray(concatenate([finishNode(textOnly, commentStart, commentEnd)], comments) as JSDocComment[], commentStart) // cast away readonly + : textOnly.text + comments; + return finishNode(factory.createJSDocAuthorTag(tagName, allParts), start); + } + + function parseAuthorNameAndEmail(): JSDocText { + const comments: string[] = []; + let inEmail = false; + let token = scanner.getToken(); + while (token !== SyntaxKind.EndOfFileToken && token !== SyntaxKind.NewLineTrivia) { + if (token === SyntaxKind.LessThanToken) { + inEmail = true; + } + else if (token === SyntaxKind.AtToken && !inEmail) { + break; + } + else if (token === SyntaxKind.GreaterThanToken && inEmail) { + comments.push(scanner.getTokenText()); + scanner.resetTokenState(scanner.getTokenEnd()); + break; + } + comments.push(scanner.getTokenText()); + token = nextTokenJSDoc(); + } + + return factory.createJSDocText(comments.join("")); + } + + function parseImplementsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocImplementsTag { + const className = parseExpressionWithTypeArgumentsForAugments(); + return finishNode(factory.createJSDocImplementsTag(tagName, className, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); + } + + function parseAugmentsTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocAugmentsTag { + const className = parseExpressionWithTypeArgumentsForAugments(); + return finishNode(factory.createJSDocAugmentsTag(tagName, className, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); + } + + function parseSatisfiesTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocSatisfiesTag { + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ false); + const comments = margin !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), margin, indentText) : undefined; + return finishNode(factory.createJSDocSatisfiesTag(tagName, typeExpression, comments), start); + } + + function parseImportTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocImportTag { + const afterImportTagPos = scanner.getTokenFullStart(); + + let identifier: Identifier | undefined; + if (isIdentifier()) { + identifier = parseIdentifier(); + } + + const importClause = tryParseImportClause(identifier, afterImportTagPos, SyntaxKind.TypeKeyword, /*skipJsDocLeadingAsterisks*/ true); + const moduleSpecifier = parseModuleSpecifier(); + const attributes = tryParseImportAttributes(); + + const comments = margin !== undefined && indentText !== undefined ? parseTrailingTagComments(start, getNodePos(), margin, indentText) : undefined; + return finishNode(factory.createJSDocImportTag(tagName, importClause, moduleSpecifier, attributes, comments), start); + } + + function parseExpressionWithTypeArgumentsForAugments(): ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression; } { + const usedBrace = parseOptional(SyntaxKind.OpenBraceToken); + const pos = getNodePos(); + const expression = parsePropertyAccessEntityNameExpression(); + scanner.setSkipJsDocLeadingAsterisks(true); + const typeArguments = tryParseTypeArguments(); + scanner.setSkipJsDocLeadingAsterisks(false); + const node = factory.createExpressionWithTypeArguments(expression, typeArguments) as ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression; }; + const res = finishNode(node, pos); + if (usedBrace) { + skipWhitespace(); + parseExpected(SyntaxKind.CloseBraceToken); + } + return res; + } + + function parsePropertyAccessEntityNameExpression() { + const pos = getNodePos(); + let node: Identifier | PropertyAccessEntityNameExpression = parseJSDocIdentifierName(); + while (parseOptional(SyntaxKind.DotToken)) { + const name = parseJSDocIdentifierName(); + node = finishNode(factoryCreatePropertyAccessExpression(node, name), pos) as PropertyAccessEntityNameExpression; + } + return node; + } + + function parseSimpleTag(start: number, createTag: (tagName: Identifier | undefined, comment?: string | NodeArray) => JSDocTag, tagName: Identifier, margin: number, indentText: string): JSDocTag { + return finishNode(createTag(tagName, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); + } + + function parseThisTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocThisTag { + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); + skipWhitespace(); + return finishNode(factory.createJSDocThisTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); + } + + function parseEnumTag(start: number, tagName: Identifier, margin: number, indentText: string): JSDocEnumTag { + const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); + skipWhitespace(); + return finishNode(factory.createJSDocEnumTag(tagName, typeExpression, parseTrailingTagComments(start, getNodePos(), margin, indentText)), start); + } + + function parseTypedefTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTypedefTag { + let typeExpression: JSDocTypeExpression | JSDocTypeLiteral | undefined = tryParseTypeExpression(); + skipWhitespaceOrAsterisk(); + + const fullName = parseJSDocTypeNameWithNamespace(); + skipWhitespace(); + let comment = parseTagComments(indent); + + let end: number | undefined; + if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { + let child: JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false; + let childTypeTag: JSDocTypeTag | undefined; + let jsDocPropertyTags: JSDocPropertyTag[] | undefined; + let hasChildren = false; + while (child = tryParse(() => parseChildPropertyTag(indent))) { + if (child.kind === SyntaxKind.JSDocTemplateTag) { + break; + } + hasChildren = true; + if (child.kind === SyntaxKind.JSDocTypeTag) { + if (childTypeTag) { + const lastError = parseErrorAtCurrentToken(Diagnostics.A_JSDoc_typedef_comment_may_not_contain_multiple_type_tags); + if (lastError) { + addRelatedInfo(lastError, createDetachedDiagnostic(fileName, sourceText, 0, 0, Diagnostics.The_tag_was_first_specified_here)); + } + break; + } + else { + childTypeTag = child; + } + } + else { + jsDocPropertyTags = append(jsDocPropertyTags, child); + } + } + if (hasChildren) { + const isArrayType = typeExpression && typeExpression.type.kind === SyntaxKind.ArrayType; + const jsdocTypeLiteral = factory.createJSDocTypeLiteral(jsDocPropertyTags, isArrayType); + typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? + childTypeTag.typeExpression : + finishNode(jsdocTypeLiteral, start); + end = typeExpression.end; + } + } + + // Only include the characters between the name end and the next token if a comment was actually parsed out - otherwise it's just whitespace + end = end || comment !== undefined ? + getNodePos() : + (fullName ?? typeExpression ?? tagName).end; + + if (!comment) { + comment = parseTrailingTagComments(start, end, indent, indentText); + } + + const typedefTag = factory.createJSDocTypedefTag(tagName, typeExpression, fullName, comment); + return finishNode(typedefTag, start, end); + } + + function parseJSDocTypeNameWithNamespace(nested?: boolean) { + const start = scanner.getTokenStart(); + if (!tokenIsIdentifierOrKeyword(token())) { + return undefined; + } + const typeNameOrNamespaceName = parseJSDocIdentifierName(); + if (parseOptional(SyntaxKind.DotToken)) { + const body = parseJSDocTypeNameWithNamespace(/*nested*/ true); + const jsDocNamespaceNode = factory.createModuleDeclaration( + /*modifiers*/ undefined, + typeNameOrNamespaceName, + body, + nested ? NodeFlags.NestedNamespace : undefined, + ) as JSDocNamespaceDeclaration; + return finishNode(jsDocNamespaceNode, start); + } + + if (nested) { + (typeNameOrNamespaceName as Mutable).flags |= NodeFlags.IdentifierIsInJSDocNamespace; + } + return typeNameOrNamespaceName; + } + + function parseCallbackTagParameters(indent: number) { + const pos = getNodePos(); + let child: JSDocParameterTag | JSDocTemplateTag | false; + let parameters; + while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag | JSDocTemplateTag)) { + if (child.kind === SyntaxKind.JSDocTemplateTag) { + parseErrorAtRange(child.tagName, Diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag); + break; + } + parameters = append(parameters, child); + } + return createNodeArray(parameters || [], pos); + } + + function parseJSDocSignature(start: number, indent: number): JSDocSignature { + const parameters = parseCallbackTagParameters(indent); + const returnTag = tryParse(() => { + if (parseOptionalJsdoc(SyntaxKind.AtToken)) { + const tag = parseTag(indent); + if (tag && tag.kind === SyntaxKind.JSDocReturnTag) { + return tag as JSDocReturnTag; + } + } + }); + return finishNode(factory.createJSDocSignature(/*typeParameters*/ undefined, parameters, returnTag), start); + } + + function parseCallbackTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocCallbackTag { + const fullName = parseJSDocTypeNameWithNamespace(); + skipWhitespace(); + let comment = parseTagComments(indent); + const typeExpression = parseJSDocSignature(start, indent); + if (!comment) { + comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); + } + const end = comment !== undefined ? getNodePos() : typeExpression.end; + return finishNode(factory.createJSDocCallbackTag(tagName, typeExpression, fullName, comment), start, end); + } + + function parseOverloadTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocOverloadTag { + skipWhitespace(); + let comment = parseTagComments(indent); + const typeExpression = parseJSDocSignature(start, indent); + if (!comment) { + comment = parseTrailingTagComments(start, getNodePos(), indent, indentText); + } + const end = comment !== undefined ? getNodePos() : typeExpression.end; + return finishNode(factory.createJSDocOverloadTag(tagName, typeExpression, comment), start, end); + } + + function escapedTextsEqual(a: EntityName, b: EntityName): boolean { + while (!isIdentifierNode(a) || !isIdentifierNode(b)) { + if (!isIdentifierNode(a) && !isIdentifierNode(b) && a.right.escapedText === b.right.escapedText) { + a = a.left; + b = b.left; + } + else { + return false; + } + } + return a.escapedText === b.escapedText; + } + + function parseChildPropertyTag(indent: number) { + return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false; + } + + function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | JSDocThisTag | false { + let canParseTag = true; + let seenAsterisk = false; + while (true) { + switch (nextTokenJSDoc()) { + case SyntaxKind.AtToken: + if (canParseTag) { + const child = tryParseChildTag(target, indent); + if ( + child && (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) && + name && (isIdentifierNode(child.name) || !escapedTextsEqual(name, child.name.left)) + ) { + return false; + } + return child; + } + seenAsterisk = false; + break; + case SyntaxKind.NewLineTrivia: + canParseTag = true; + seenAsterisk = false; + break; + case SyntaxKind.AsteriskToken: + if (seenAsterisk) { + canParseTag = false; + } + seenAsterisk = true; + break; + case SyntaxKind.Identifier: + canParseTag = false; + break; + case SyntaxKind.EndOfFileToken: + return false; + } + } + } + + function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | JSDocThisTag | false { + Debug.assert(token() === SyntaxKind.AtToken); + const start = scanner.getTokenFullStart(); + nextTokenJSDoc(); + + const tagName = parseJSDocIdentifierName(); + const indentText = skipWhitespaceOrAsterisk(); + let t: PropertyLikeParse; + switch (tagName.escapedText) { + case "type": + return target === PropertyLikeParse.Property && parseTypeTag(start, tagName); + case "prop": + case "property": + t = PropertyLikeParse.Property; + break; + case "arg": + case "argument": + case "param": + t = PropertyLikeParse.Parameter | PropertyLikeParse.CallbackParameter; + break; + case "template": + return parseTemplateTag(start, tagName, indent, indentText); + case "this": + return parseThisTag(start, tagName, indent, indentText); + default: + return false; + } + if (!(target & t)) { + return false; + } + return parseParameterOrPropertyTag(start, tagName, target, indent); + } + + function parseTemplateTagTypeParameter() { + const typeParameterPos = getNodePos(); + const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken); + if (isBracketed) { + skipWhitespace(); + } + + const modifiers = parseModifiers(/*allowDecorators*/ false, /*permitConstAsModifier*/ true); + const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); + let defaultType: TypeNode | undefined; + if (isBracketed) { + skipWhitespace(); + parseExpected(SyntaxKind.EqualsToken); + defaultType = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType); + parseExpected(SyntaxKind.CloseBracketToken); + } + + if (nodeIsMissing(name)) { + return undefined; + } + return finishNode(factory.createTypeParameterDeclaration(modifiers, name, /*constraint*/ undefined, defaultType), typeParameterPos); + } + + function parseTemplateTagTypeParameters() { + const pos = getNodePos(); + const typeParameters = []; + do { + skipWhitespace(); + const node = parseTemplateTagTypeParameter(); + if (node !== undefined) { + typeParameters.push(node); + } + skipWhitespaceOrAsterisk(); + } + while (parseOptionalJsdoc(SyntaxKind.CommaToken)); + return createNodeArray(typeParameters, pos); + } + + function parseTemplateTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocTemplateTag { + // The template tag looks like one of the following: + // @template T,U,V + // @template {Constraint} T + // + // According to the [closure docs](https://github.com/google/closure-compiler/wiki/Generic-Types#multiple-bounded-template-types): + // > Multiple bounded generics cannot be declared on the same line. For the sake of clarity, if multiple templates share the same + // > type bound they must be declared on separate lines. + // + // TODO: Determine whether we should enforce this in the checker. + // TODO: Consider moving the `constraint` to the first type parameter as we could then remove `getEffectiveConstraintOfTypeParameter`. + // TODO: Consider only parsing a single type parameter if there is a constraint. + const constraint = token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined; + const typeParameters = parseTemplateTagTypeParameters(); + return finishNode(factory.createJSDocTemplateTag(tagName, constraint, typeParameters, parseTrailingTagComments(start, getNodePos(), indent, indentText)), start); + } + + function parseOptionalJsdoc(t: JSDocSyntaxKind): boolean { + if (token() === t) { + nextTokenJSDoc(); + return true; + } + return false; + } + + function parseJSDocEntityName(): EntityName { + let entity: EntityName = parseJSDocIdentifierName(); + if (parseOptional(SyntaxKind.OpenBracketToken)) { + parseExpected(SyntaxKind.CloseBracketToken); + // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. + // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}> + // but it's not worth it to enforce that restriction. + } + while (parseOptional(SyntaxKind.DotToken)) { + const name = parseJSDocIdentifierName(); + if (parseOptional(SyntaxKind.OpenBracketToken)) { + parseExpected(SyntaxKind.CloseBracketToken); + } + entity = createQualifiedName(entity, name); + } + return entity; + } + + function parseJSDocIdentifierName(message?: DiagnosticMessage): Identifier { + if (!tokenIsIdentifierOrKeyword(token())) { + return createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || Diagnostics.Identifier_expected); + } + + identifierCount++; + const start = scanner.getTokenStart(); + const end = scanner.getTokenEnd(); + const originalKeywordKind = token(); + const text = internIdentifier(scanner.getTokenValue()); + const result = finishNode(factoryCreateIdentifier(text, originalKeywordKind), start, end); + nextTokenJSDoc(); + return result; + } + } + } +} + +const incrementallyParsedFiles = new WeakSet(); + +function markAsIncrementallyParsed(sourceFile: SourceFile) { + if (incrementallyParsedFiles.has(sourceFile)) { + Debug.fail("Source file has already been incrementally parsed"); + } + incrementallyParsedFiles.add(sourceFile); +} + +const intersectingChangeSet = new WeakSet>(); + +function intersectsIncrementalChange(node: Node | NodeArray): boolean { + return intersectingChangeSet.has(node); +} + +function markAsIntersectingIncrementalChange(node: Node | NodeArray) { + intersectingChangeSet.add(node); +} + +namespace IncrementalParser { + export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile { + aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive); + + checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); + if (textChangeRangeIsUnchanged(textChangeRange)) { + // if the text didn't change, then we can just return our current source file as-is. + return sourceFile; + } + + if (sourceFile.statements.length === 0) { + // If we don't have any statements in the current source file, then there's no real + // way to incrementally parse. So just do a full parse instead. + return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind, sourceFile.setExternalModuleIndicator, sourceFile.jsDocParsingMode); + } + + // Make sure we're not trying to incrementally update a source file more than once. Once + // we do an update the original source file is considered unusable from that point onwards. + // + // This is because we do incremental parsing in-place. i.e. we take nodes from the old + // tree and give them new positions and parents. From that point on, trusting the old + // tree at all is not possible as far too much of it may violate invariants. + markAsIncrementallyParsed(sourceFile); + Parser.fixupParentReferences(sourceFile); + const oldText = sourceFile.text; + const syntaxCursor = createSyntaxCursor(sourceFile); + + // Make the actual change larger so that we know to reparse anything whose lookahead + // might have intersected the change. + const changeRange = extendToAffectedRange(sourceFile, textChangeRange); + checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks); + + // Ensure that extending the affected range only moved the start of the change range + // earlier in the file. + Debug.assert(changeRange.span.start <= textChangeRange.span.start); + Debug.assert(textSpanEnd(changeRange.span) === textSpanEnd(textChangeRange.span)); + Debug.assert(textSpanEnd(textChangeRangeNewSpan(changeRange)) === textSpanEnd(textChangeRangeNewSpan(textChangeRange))); + + // The is the amount the nodes after the edit range need to be adjusted. It can be + // positive (if the edit added characters), negative (if the edit deleted characters) + // or zero (if this was a pure overwrite with nothing added/removed). + const delta = textChangeRangeNewSpan(changeRange).length - changeRange.span.length; + + // If we added or removed characters during the edit, then we need to go and adjust all + // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they + // may move backward (if we deleted chars). + // + // Doing this helps us out in two ways. First, it means that any nodes/tokens we want + // to reuse are already at the appropriate position in the new text. That way when we + // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes + // it very easy to determine if we can reuse a node. If the node's position is at where + // we are in the text, then we can reuse it. Otherwise we can't. If the node's position + // is ahead of us, then we'll need to rescan tokens. If the node's position is behind + // us, then we'll need to skip it or crumble it as appropriate + // + // We will also adjust the positions of nodes that intersect the change range as well. + // By doing this, we ensure that all the positions in the old tree are consistent, not + // just the positions of nodes entirely before/after the change range. By being + // consistent, we can then easily map from positions to nodes in the old tree easily. + // + // Also, mark any syntax elements that intersect the changed span. We know, up front, + // that we cannot reuse these elements. + updateTokenPositionsAndMarkElements(sourceFile, changeRange.span.start, textSpanEnd(changeRange.span), textSpanEnd(textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks); + + // Now that we've set up our internal incremental state just proceed and parse the + // source file in the normal fashion. When possible the parser will retrieve and + // reuse nodes from the old tree. + // + // Note: passing in 'true' for setNodeParents is very important. When incrementally + // parsing, we will be reusing nodes from the old tree, and placing it into new + // parents. If we don't set the parents now, we'll end up with an observably + // inconsistent tree. Setting the parents on the new tree should be very fast. We + // will immediately bail out of walking any subtrees when we can see that their parents + // are already correct. + const result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind, sourceFile.setExternalModuleIndicator, sourceFile.jsDocParsingMode); + result.commentDirectives = getNewCommentDirectives( + sourceFile.commentDirectives, + result.commentDirectives, + changeRange.span.start, + textSpanEnd(changeRange.span), + delta, + oldText, + newText, + aggressiveChecks, + ); + result.impliedNodeFormat = sourceFile.impliedNodeFormat; + transferSourceFileChildren(sourceFile, result); + return result; + } + + function getNewCommentDirectives( + oldDirectives: CommentDirective[] | undefined, + newDirectives: CommentDirective[] | undefined, + changeStart: number, + changeRangeOldEnd: number, + delta: number, + oldText: string, + newText: string, + aggressiveChecks: boolean, + ): CommentDirective[] | undefined { + if (!oldDirectives) return newDirectives; + let commentDirectives: CommentDirective[] | undefined; + let addedNewlyScannedDirectives = false; + for (const directive of oldDirectives) { + const { range, type } = directive; + // Range before the change + if (range.end < changeStart) { + commentDirectives = append(commentDirectives, directive); + } + else if (range.pos > changeRangeOldEnd) { + addNewlyScannedDirectives(); + // Node is entirely past the change range. We need to move both its pos and + // end, forward or backward appropriately. + const updatedDirective: CommentDirective = { + range: { pos: range.pos + delta, end: range.end + delta }, + type, + }; + commentDirectives = append(commentDirectives, updatedDirective); + if (aggressiveChecks) { + Debug.assert(oldText.substring(range.pos, range.end) === newText.substring(updatedDirective.range.pos, updatedDirective.range.end)); + } + } + // Ignore ranges that fall in change range + } + addNewlyScannedDirectives(); + return commentDirectives; + + function addNewlyScannedDirectives() { + if (addedNewlyScannedDirectives) return; + addedNewlyScannedDirectives = true; + if (!commentDirectives) { + commentDirectives = newDirectives; + } + else if (newDirectives) { + commentDirectives.push(...newDirectives); + } + } + } + + function moveElementEntirelyPastChangeRange(element: Node, origSourceFile: SourceFile, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void; + function moveElementEntirelyPastChangeRange(element: NodeArray, origSourceFile: SourceFile, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void; + function moveElementEntirelyPastChangeRange(element: Node | NodeArray, origSourceFile: SourceFile, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { + if (isArray) { + visitArray(element as NodeArray); + } + else { + visitNode(element as Node); + } + return; + + function visitNode(node: Node) { + let text = ""; + if (aggressiveChecks && shouldCheckNode(node)) { + text = oldText.substring(node.pos, node.end); + } + + // Ditch any existing LS children we may have created. This way we can avoid + // moving them forward. + unsetNodeChildren(node, origSourceFile); + + setTextRangePosEnd(node, node.pos + delta, node.end + delta); + + if (aggressiveChecks && shouldCheckNode(node)) { + Debug.assert(text === newText.substring(node.pos, node.end)); + } + + forEachChild(node, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray) => void); + if (hasJSDocNodes(node)) { + for (const jsDocComment of node.jsDoc!) { + visitNode(jsDocComment); + } + } + checkNodePositions(node, aggressiveChecks); + } + + function visitArray(array: NodeArray) { + setTextRangePosEnd(array, array.pos + delta, array.end + delta); + + for (const node of array) { + visitNode(node); + } + } + } + + function shouldCheckNode(node: Node) { + switch (node.kind) { + case SyntaxKind.StringLiteral: + case SyntaxKind.NumericLiteral: + case SyntaxKind.Identifier: + return true; + } + + return false; + } + + function adjustIntersectingElement(element: Node | NodeArray, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number) { + Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range"); + Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range"); + Debug.assert(element.pos <= element.end); + + // We have an element that intersects the change range in some way. It may have its + // start, or its end (or both) in the changed range. We want to adjust any part + // that intersects such that the final tree is in a consistent state. i.e. all + // children have spans within the span of their parent, and all siblings are ordered + // properly. + + // We may need to update both the 'pos' and the 'end' of the element. + + // If the 'pos' is before the start of the change, then we don't need to touch it. + // If it isn't, then the 'pos' must be inside the change. How we update it will + // depend if delta is positive or negative. If delta is positive then we have + // something like: + // + // -------------------AAA----------------- + // -------------------BBBCCCCCCC----------------- + // + // In this case, we consider any node that started in the change range to still be + // starting at the same position. + // + // however, if the delta is negative, then we instead have something like this: + // + // -------------------XXXYYYYYYY----------------- + // -------------------ZZZ----------------- + // + // In this case, any element that started in the 'X' range will keep its position. + // However any element that started after that will have their pos adjusted to be + // at the end of the new range. i.e. any node that started in the 'Y' range will + // be adjusted to have their start at the end of the 'Z' range. + // + // The element will keep its position if possible. Or Move backward to the new-end + // if it's in the 'Y' range. + const pos = Math.min(element.pos, changeRangeNewEnd); + + // If the 'end' is after the change range, then we always adjust it by the delta + // amount. However, if the end is in the change range, then how we adjust it + // will depend on if delta is positive or negative. If delta is positive then we + // have something like: + // + // -------------------AAA----------------- + // -------------------BBBCCCCCCC----------------- + // + // In this case, we consider any node that ended inside the change range to keep its + // end position. + // + // however, if the delta is negative, then we instead have something like this: + // + // -------------------XXXYYYYYYY----------------- + // -------------------ZZZ----------------- + // + // In this case, any element that ended in the 'X' range will keep its position. + // However any element that ended after that will have their pos adjusted to be + // at the end of the new range. i.e. any node that ended in the 'Y' range will + // be adjusted to have their end at the end of the 'Z' range. + const end = element.end >= changeRangeOldEnd ? + // Element ends after the change range. Always adjust the end pos. + element.end + delta : + // Element ends in the change range. The element will keep its position if + // possible. Or Move backward to the new-end if it's in the 'Y' range. + Math.min(element.end, changeRangeNewEnd); + + Debug.assert(pos <= end); + if ((element as any).parent) { + const parent = (element as any).parent as Node; + Debug.assertGreaterThanOrEqual(pos, parent.pos); + Debug.assertLessThanOrEqual(end, parent.end); + } + + setTextRangePosEnd(element, pos, end); + } + + function checkNodePositions(node: Node, aggressiveChecks: boolean) { + if (aggressiveChecks) { + let pos = node.pos; + const visitNode = (child: Node) => { + Debug.assert(child.pos >= pos); + pos = child.end; + }; + if (hasJSDocNodes(node)) { + for (const jsDocComment of node.jsDoc!) { + visitNode(jsDocComment); + } + } + forEachChild(node, visitNode); + Debug.assert(pos <= node.end); + } + } + + function updateTokenPositionsAndMarkElements( + sourceFile: SourceFile, + changeStart: number, + changeRangeOldEnd: number, + changeRangeNewEnd: number, + delta: number, + oldText: string, + newText: string, + aggressiveChecks: boolean, + ): void { + visitNode(sourceFile); + return; + + function visitNode(child: Node) { + Debug.assert(child.pos <= child.end); + if (child.pos > changeRangeOldEnd) { + // Node is entirely past the change range. We need to move both its pos and + // end, forward or backward appropriately. + moveElementEntirelyPastChangeRange(child, sourceFile, /*isArray*/ false, delta, oldText, newText, aggressiveChecks); + return; + } + + // Check if the element intersects the change range. If it does, then it is not + // reusable. Also, we'll need to recurse to see what constituent portions we may + // be able to use. + const fullEnd = child.end; + if (fullEnd >= changeStart) { + markAsIntersectingIncrementalChange(child); + unsetNodeChildren(child, sourceFile); + + // Adjust the pos or end (or both) of the intersecting element accordingly. + adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); + forEachChild(child, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray) => void); + if (hasJSDocNodes(child)) { + for (const jsDocComment of child.jsDoc!) { + visitNode(jsDocComment); + } + } + checkNodePositions(child, aggressiveChecks); + return; + } + + // Otherwise, the node is entirely before the change range. No need to do anything with it. + Debug.assert(fullEnd < changeStart); + } + + function visitArray(array: NodeArray) { + Debug.assert(array.pos <= array.end); + if (array.pos > changeRangeOldEnd) { + // Array is entirely after the change range. We need to move it, and move any of + // its children. + moveElementEntirelyPastChangeRange(array, sourceFile, /*isArray*/ true, delta, oldText, newText, aggressiveChecks); + return; + } + + // Check if the element intersects the change range. If it does, then it is not + // reusable. Also, we'll need to recurse to see what constituent portions we may + // be able to use. + const fullEnd = array.end; + if (fullEnd >= changeStart) { + markAsIntersectingIncrementalChange(array); + + // Adjust the pos or end (or both) of the intersecting array accordingly. + adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); + for (const node of array) { + visitNode(node); + } + return; + } + + // Otherwise, the array is entirely before the change range. No need to do anything with it. + Debug.assert(fullEnd < changeStart); + } + } + + function extendToAffectedRange(sourceFile: SourceFile, changeRange: TextChangeRange): TextChangeRange { + // Consider the following code: + // void foo() { /; } + // + // If the text changes with an insertion of / just before the semicolon then we end up with: + // void foo() { //; } + // + // If we were to just use the changeRange a is, then we would not rescan the { token + // (as it does not intersect the actual original change range). Because an edit may + // change the token touching it, we actually need to look back *at least* one token so + // that the prior token sees that change. + const maxLookahead = 1; + + let start = changeRange.span.start; + + // the first iteration aligns us with the change start. subsequent iteration move us to + // the left by maxLookahead tokens. We only need to do this as long as we're not at the + // start of the tree. + for (let i = 0; start > 0 && i <= maxLookahead; i++) { + const nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start); + Debug.assert(nearestNode.pos <= start); + const position = nearestNode.pos; + + start = Math.max(0, position - 1); + } + + const finalSpan = createTextSpanFromBounds(start, textSpanEnd(changeRange.span)); + const finalLength = changeRange.newLength + (changeRange.span.start - start); + + return createTextChangeRange(finalSpan, finalLength); + } + + function findNearestNodeStartingBeforeOrAtPosition(sourceFile: SourceFile, position: number): Node { + let bestResult: Node = sourceFile; + let lastNodeEntirelyBeforePosition: Node | undefined; + + forEachChild(sourceFile, visit); + + if (lastNodeEntirelyBeforePosition) { + const lastChildOfLastEntireNodeBeforePosition = getLastDescendant(lastNodeEntirelyBeforePosition); + if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) { + bestResult = lastChildOfLastEntireNodeBeforePosition; + } + } + + return bestResult; + + function getLastDescendant(node: Node): Node { + while (true) { + const lastChild = getLastChild(node); + if (lastChild) { + node = lastChild; + } + else { + return node; + } + } + } + + function visit(child: Node) { + if (nodeIsMissing(child)) { + // Missing nodes are effectively invisible to us. We never even consider them + // When trying to find the nearest node before us. + return; + } + + // If the child intersects this position, then this node is currently the nearest + // node that starts before the position. + if (child.pos <= position) { + if (child.pos >= bestResult.pos) { + // This node starts before the position, and is closer to the position than + // the previous best node we found. It is now the new best node. + bestResult = child; + } + + // Now, the node may overlap the position, or it may end entirely before the + // position. If it overlaps with the position, then either it, or one of its + // children must be the nearest node before the position. So we can just + // recurse into this child to see if we can find something better. + if (position < child.end) { + // The nearest node is either this child, or one of the children inside + // of it. We've already marked this child as the best so far. Recurse + // in case one of the children is better. + forEachChild(child, visit); + + // Once we look at the children of this node, then there's no need to + // continue any further. + return true; + } + else { + Debug.assert(child.end <= position); + // The child ends entirely before this position. Say you have the following + // (where $ is the position) + // + // ? $ : <...> <...> + // + // We would want to find the nearest preceding node in "complex expr 2". + // To support that, we keep track of this node, and once we're done searching + // for a best node, we recurse down this node to see if we can find a good + // result in it. + // + // This approach allows us to quickly skip over nodes that are entirely + // before the position, while still allowing us to find any nodes in the + // last one that might be what we want. + lastNodeEntirelyBeforePosition = child; + } + } + else { + Debug.assert(child.pos > position); + // We're now at a node that is entirely past the position we're searching for. + // This node (and all following nodes) could never contribute to the result, + // so just skip them by returning 'true' here. + return true; + } + } + } + + function checkChangeRange(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean) { + const oldText = sourceFile.text; + if (textChangeRange) { + Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); + + if (aggressiveChecks || Debug.shouldAssert(AssertionLevel.VeryAggressive)) { + const oldTextPrefix = oldText.substr(0, textChangeRange.span.start); + const newTextPrefix = newText.substr(0, textChangeRange.span.start); + Debug.assert(oldTextPrefix === newTextPrefix); + + const oldTextSuffix = oldText.substring(textSpanEnd(textChangeRange.span), oldText.length); + const newTextSuffix = newText.substring(textSpanEnd(textChangeRangeNewSpan(textChangeRange)), newText.length); + Debug.assert(oldTextSuffix === newTextSuffix); + } + } + } + + // Allows finding nodes in the source file at a certain position in an efficient manner. + // The implementation takes advantage of the calling pattern it knows the parser will + // make in order to optimize finding nodes as quickly as possible. + export interface SyntaxCursor { + currentNode(position: number): Node; + } + + export function createSyntaxCursor(sourceFile: SourceFile): SyntaxCursor { + let currentArray: NodeArray = sourceFile.statements; + let currentArrayIndex = 0; + + Debug.assert(currentArrayIndex < currentArray.length); + let current = currentArray[currentArrayIndex]; + let lastQueriedPosition = InvalidPosition.Value; + + return { + currentNode(position: number) { + // Only compute the current node if the position is different than the last time + // we were asked. The parser commonly asks for the node at the same position + // twice. Once to know if can read an appropriate list element at a certain point, + // and then to actually read and consume the node. + if (position !== lastQueriedPosition) { + // Much of the time the parser will need the very next node in the array that + // we just returned a node from.So just simply check for that case and move + // forward in the array instead of searching for the node again. + if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) { + currentArrayIndex++; + current = currentArray[currentArrayIndex]; + } + + // If we don't have a node, or the node we have isn't in the right position, + // then try to find a viable node at the position requested. + if (!current || current.pos !== position) { + findHighestListElementThatStartsAtPosition(position); + } + } + + // Cache this query so that we don't do any extra work if the parser calls back + // into us. Note: this is very common as the parser will make pairs of calls like + // 'isListElement -> parseListElement'. If we were unable to find a node when + // called with 'isListElement', we don't want to redo the work when parseListElement + // is called immediately after. + lastQueriedPosition = position; + + // Either we don'd have a node, or we have a node at the position being asked for. + Debug.assert(!current || current.pos === position); + return current; + }, + }; + + // Finds the highest element in the tree we can find that starts at the provided position. + // The element must be a direct child of some node list in the tree. This way after we + // return it, we can easily return its next sibling in the list. + function findHighestListElementThatStartsAtPosition(position: number) { + // Clear out any cached state about the last node we found. + currentArray = undefined!; + currentArrayIndex = InvalidPosition.Value; + current = undefined!; + + // Recurse into the source file to find the highest node at this position. + forEachChild(sourceFile, visitNode, visitArray); + return; + + function visitNode(node: Node) { + if (position >= node.pos && position < node.end) { + // Position was within this node. Keep searching deeper to find the node. + forEachChild(node, visitNode, visitArray); + + // don't proceed any further in the search. + return true; + } + + // position wasn't in this node, have to keep searching. + return false; + } + + function visitArray(array: NodeArray) { + if (position >= array.pos && position < array.end) { + // position was in this array. Search through this array to see if we find a + // viable element. + for (let i = 0; i < array.length; i++) { + const child = array[i]; + if (child) { + if (child.pos === position) { + // Found the right node. We're done. + currentArray = array; + currentArrayIndex = i; + current = child; + return true; + } + else { + if (child.pos < position && position < child.end) { + // Position in somewhere within this child. Search in it and + // stop searching in this array. + forEachChild(child, visitNode, visitArray); + return true; + } + } + } + } + } + + // position wasn't in this array, have to keep searching. + return false; + } + } + } + + const enum InvalidPosition { + Value = -1, + } +} + +/** @internal */ +export function isDeclarationFileName(fileName: string): boolean { + return getDeclarationFileExtension(fileName) !== undefined; +} + +/** @internal */ +export function getDeclarationFileExtension(fileName: string): string | undefined { + const standardExtension = getAnyExtensionFromPath(fileName, supportedDeclarationExtensions, /*ignoreCase*/ false); + if (standardExtension) { + return standardExtension; + } + if (fileExtensionIs(fileName, Extension.Ts)) { + const baseName = getBaseFileName(fileName); + const index = baseName.lastIndexOf(".d."); + if (index >= 0) { + return baseName.substring(index); + } + } + return undefined; +} + +function parseResolutionMode(mode: string | undefined, pos: number, end: number, reportDiagnostic: PragmaDiagnosticReporter): ResolutionMode { + if (!mode) { + return undefined; + } + if (mode === "import") { + return ModuleKind.ESNext; + } + if (mode === "require") { + return ModuleKind.CommonJS; + } + reportDiagnostic(pos, end - pos, Diagnostics.resolution_mode_should_be_either_require_or_import); + return undefined; +} + +/** @internal */ +export function processCommentPragmas(context: PragmaContext, sourceText: string): void { + const pragmas: PragmaPseudoMapEntry[] = []; + + for (const range of getLeadingCommentRanges(sourceText, 0) || emptyArray) { + const comment = sourceText.substring(range.pos, range.end); + extractPragmas(pragmas, range, comment); + } + + context.pragmas = new Map() as PragmaMap; + for (const pragma of pragmas) { + if (context.pragmas.has(pragma.name)) { + const currentValue = context.pragmas.get(pragma.name); + if (currentValue instanceof Array) { + currentValue.push(pragma.args); + } + else { + context.pragmas.set(pragma.name, [currentValue, pragma.args]); + } + continue; + } + context.pragmas.set(pragma.name, pragma.args); + } +} + +/** @internal */ +export type PragmaDiagnosticReporter = (pos: number, length: number, message: DiagnosticMessage) => void; + +/** @internal */ +export function processPragmasIntoFields(context: PragmaContext, reportDiagnostic: PragmaDiagnosticReporter): void { + context.checkJsDirective = undefined; + context.referencedFiles = []; + context.typeReferenceDirectives = []; + context.libReferenceDirectives = []; + context.amdDependencies = []; + context.pragmas!.forEach((entryOrList, key) => { // TODO: GH#18217 + // TODO: The below should be strongly type-guarded and not need casts/explicit annotations, since entryOrList is related to + // key and key is constrained to a union; but it's not (see GH#21483 for at least partial fix) :( + switch (key) { + case "reference": { + const referencedFiles = context.referencedFiles; + const typeReferenceDirectives = context.typeReferenceDirectives; + const libReferenceDirectives = context.libReferenceDirectives; + forEach(toArray(entryOrList) as PragmaPseudoMap["reference"][], arg => { + const { types, lib, path, ["resolution-mode"]: res, preserve: _preserve } = arg.arguments; + const preserve = _preserve === "true" ? true : undefined; + if (arg.arguments["no-default-lib"] === "true") { + // This has been removed; parse but ignore it. + } + else if (types) { + const parsed = parseResolutionMode(res, types.pos, types.end, reportDiagnostic); + typeReferenceDirectives.push({ pos: types.pos, end: types.end, fileName: types.value, ...(parsed ? { resolutionMode: parsed } : {}), ...(preserve ? { preserve } : {}) }); + } + else if (lib) { + libReferenceDirectives.push({ pos: lib.pos, end: lib.end, fileName: lib.value, ...(preserve ? { preserve } : {}) }); + } + else if (path) { + referencedFiles.push({ pos: path.pos, end: path.end, fileName: path.value, ...(preserve ? { preserve } : {}) }); + } + else { + reportDiagnostic(arg.range.pos, arg.range.end - arg.range.pos, Diagnostics.Invalid_reference_directive_syntax); + } + }); + break; + } + case "amd-dependency": { + context.amdDependencies = map( + toArray(entryOrList) as PragmaPseudoMap["amd-dependency"][], + x => ({ name: x.arguments.name, path: x.arguments.path }), + ); + break; + } + case "amd-module": { + if (entryOrList instanceof Array) { + for (const entry of entryOrList) { + if (context.moduleName) { + // TODO: It's probably fine to issue this diagnostic on all instances of the pragma + reportDiagnostic(entry.range.pos, entry.range.end - entry.range.pos, Diagnostics.An_AMD_module_cannot_have_multiple_name_assignments); + } + context.moduleName = (entry as PragmaPseudoMap["amd-module"]).arguments.name; + } + } + else { + context.moduleName = (entryOrList as PragmaPseudoMap["amd-module"]).arguments.name; + } + break; + } + case "ts-nocheck": + case "ts-check": { + // _last_ of either nocheck or check in a file is the "winner" + forEach(toArray(entryOrList), entry => { + if (!context.checkJsDirective || entry.range.pos > context.checkJsDirective.pos) { + context.checkJsDirective = { + enabled: key === "ts-check", + end: entry.range.end, + pos: entry.range.pos, + }; + } + }); + break; + } + case "jsx": + case "jsxfrag": + case "jsximportsource": + case "jsxruntime": + return; // Accessed directly + default: + Debug.fail("Unhandled pragma kind"); // Can this be made into an assertNever in the future? + } + }); +} + +const namedArgRegExCache = new Map(); +function getNamedArgRegEx(name: string): RegExp { + if (namedArgRegExCache.has(name)) { + return namedArgRegExCache.get(name)!; + } + const result = new RegExp(`(\\s${name}\\s*=\\s*)(?:(?:'([^']*)')|(?:"([^"]*)"))`, "im"); + namedArgRegExCache.set(name, result); + return result; +} + +const tripleSlashXMLCommentStartRegEx = /^\/\/\/\s*<(\S+)\s.*?\/>/m; +const singleLinePragmaRegEx = /^\/\/\/?\s*@([^\s:]+)((?:[^\S\r\n]|:).*)?$/m; +function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, text: string) { + const tripleSlash = range.kind === SyntaxKind.SingleLineCommentTrivia && tripleSlashXMLCommentStartRegEx.exec(text); + if (tripleSlash) { + const name = tripleSlash[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so the below check to make it safe typechecks + const pragma = commentPragmas[name] as PragmaDefinition; + if (!pragma || !(pragma.kind! & PragmaKindFlags.TripleSlashXML)) { + return; + } + if (pragma.args) { + const argument: { [index: string]: string | { value: string; pos: number; end: number; }; } = {}; + for (const arg of pragma.args) { + const matcher = getNamedArgRegEx(arg.name); + const matchResult = matcher.exec(text); + if (!matchResult && !arg.optional) { + return; // Missing required argument, don't parse + } + else if (matchResult) { + const value = matchResult[2] || matchResult[3]; + if (arg.captureSpan) { + const startPos = range.pos + matchResult.index + matchResult[1].length + 1; + argument[arg.name] = { + value, + pos: startPos, + end: startPos + value.length, + }; + } + else { + argument[arg.name] = value; + } + } + } + pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry); + } + else { + pragmas.push({ name, args: { arguments: {}, range } } as PragmaPseudoMapEntry); + } + return; + } + + const singleLine = range.kind === SyntaxKind.SingleLineCommentTrivia && singleLinePragmaRegEx.exec(text); + if (singleLine) { + return addPragmaForMatch(pragmas, range, PragmaKindFlags.SingleLine, singleLine); + } + + if (range.kind === SyntaxKind.MultiLineCommentTrivia) { + const multiLinePragmaRegEx = /@(\S+)(\s+(?:\S.*)?)?$/gm; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating) + let multiLineMatch: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax + while (multiLineMatch = multiLinePragmaRegEx.exec(text)) { + addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch); + } + } +} + +function addPragmaForMatch(pragmas: PragmaPseudoMapEntry[], range: CommentRange, kind: PragmaKindFlags, match: RegExpExecArray) { + if (!match) return; + const name = match[1].toLowerCase() as keyof PragmaPseudoMap; // Technically unsafe cast, but we do it so they below check to make it safe typechecks + const pragma = commentPragmas[name] as PragmaDefinition; + if (!pragma || !(pragma.kind! & kind)) { + return; + } + const args = match[2]; // Split on spaces and match up positionally with definition + const argument = getNamedPragmaArguments(pragma, args); + if (argument === "fail") return; // Missing required argument, fail to parse it + pragmas.push({ name, args: { arguments: argument, range } } as PragmaPseudoMapEntry); + return; +} + +function getNamedPragmaArguments(pragma: PragmaDefinition, text: string | undefined): { [index: string]: string; } | "fail" { + if (!text) return {}; + if (!pragma.args) return {}; + const args = text.trim().split(/\s+/); + const argMap: { [index: string]: string; } = {}; + for (let i = 0; i < pragma.args.length; i++) { + const argument = pragma.args[i]; + if (!args[i] && !argument.optional) { + return "fail"; + } + if (argument.captureSpan) { + return Debug.fail("Capture spans not yet implemented for non-xml pragmas"); + } + argMap[argument.name] = args[i]; + } + return argMap; +} + +/** @internal */ +export function tagNamesAreEquivalent(lhs: JsxTagNameExpression, rhs: JsxTagNameExpression): boolean { + if (lhs.kind !== rhs.kind) { + return false; + } + + if (lhs.kind === SyntaxKind.Identifier) { + return lhs.escapedText === (rhs as Identifier).escapedText; + } + + if (lhs.kind === SyntaxKind.ThisKeyword) { + return true; + } + + if (lhs.kind === SyntaxKind.JsxNamespacedName) { + return lhs.namespace.escapedText === (rhs as JsxNamespacedName).namespace.escapedText && + lhs.name.escapedText === (rhs as JsxNamespacedName).name.escapedText; + } + + // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only + // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression + // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element + return (lhs as PropertyAccessExpression).name.escapedText === (rhs as PropertyAccessExpression).name.escapedText && + tagNamesAreEquivalent((lhs as PropertyAccessExpression).expression as JsxTagNameExpression, (rhs as PropertyAccessExpression).expression as JsxTagNameExpression); +} diff --git a/tests/baselines/reference/importDeferOptionalCall.errors.txt b/tests/baselines/reference/importDeferOptionalCall.errors.txt new file mode 100644 index 0000000000000..7064caf9fc811 --- /dev/null +++ b/tests/baselines/reference/importDeferOptionalCall.errors.txt @@ -0,0 +1,13 @@ +b.ts(1,13): error TS18062: 'import.defer' does not support optional invocation. +b.ts(1,16): error TS2307: Cannot find module './x' or its corresponding type declarations. + + +==== x.ts (0 errors) ==== + export const x = 1; +==== b.ts (2 errors) ==== + import.defer?.('./x'); + ~~ +!!! error TS18062: 'import.defer' does not support optional invocation. + ~~~~~ +!!! error TS2307: Cannot find module './x' or its corresponding type declarations. + \ No newline at end of file diff --git a/tests/baselines/reference/importDeferOptionalCall.js b/tests/baselines/reference/importDeferOptionalCall.js new file mode 100644 index 0000000000000..c9d74a9d27a2c --- /dev/null +++ b/tests/baselines/reference/importDeferOptionalCall.js @@ -0,0 +1,14 @@ +//// [tests/cases/conformance/importDefer/importDeferOptionalCall.ts] //// + +//// [x.ts] +export const x = 1; +//// [b.ts] +import.defer?.('./x'); + + +//// [x.js] +export const x = 1; +//// [b.js] +"use strict"; +var _a; +(_a = import.defer) === null || _a === void 0 ? void 0 : _a('./x'); diff --git a/tests/baselines/reference/importDeferOptionalCall.symbols b/tests/baselines/reference/importDeferOptionalCall.symbols new file mode 100644 index 0000000000000..e816d59ba7a60 --- /dev/null +++ b/tests/baselines/reference/importDeferOptionalCall.symbols @@ -0,0 +1,10 @@ +//// [tests/cases/conformance/importDefer/importDeferOptionalCall.ts] //// + +=== x.ts === +export const x = 1; +>x : Symbol(x, Decl(x.ts, 0, 12)) + +=== b.ts === + +import.defer?.('./x'); + diff --git a/tests/baselines/reference/importDeferOptionalCall.types b/tests/baselines/reference/importDeferOptionalCall.types new file mode 100644 index 0000000000000..ae0625bd65477 --- /dev/null +++ b/tests/baselines/reference/importDeferOptionalCall.types @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/importDefer/importDeferOptionalCall.ts] //// + +=== x.ts === +export const x = 1; +>x : 1 +> : ^ +>1 : 1 +> : ^ + +=== b.ts === +import.defer?.('./x'); +>import.defer?.('./x') : Promise +> : ^^^^^^^^^^^^ +>defer : any +> : ^^^ +>'./x' : "./x" +> : ^^^^^ + diff --git a/tests/cases/conformance/importDefer/importDeferOptionalCall.ts b/tests/cases/conformance/importDefer/importDeferOptionalCall.ts new file mode 100644 index 0000000000000..21bdc6f544dc4 --- /dev/null +++ b/tests/cases/conformance/importDefer/importDeferOptionalCall.ts @@ -0,0 +1,6 @@ +// @target: es2015 +// @module: esnext +// @filename: x.ts +export const x = 1; +// @filename: b.ts +import.defer?.('./x');