From ab4e8129d5c94ff96e6c85d0d2b66a04a052b4e5 Mon Sep 17 00:00:00 2001 From: HelenHuang <LinHuang@pollex.com.tw> Date: 星期四, 09 六月 2022 15:26:15 +0800 Subject: [PATCH] TODO#139888 嚴選配對 - 文案修改 --- PAMapp/node_modules/@babel/parser/lib/index.js | 7105 ++++++++++++++++++++++++++++++++++++----------------------- 1 files changed, 4,361 insertions(+), 2,744 deletions(-) diff --git a/PAMapp/node_modules/@babel/parser/lib/index.js b/PAMapp/node_modules/@babel/parser/lib/index.js index da6fe1f..e943188 100644 --- a/PAMapp/node_modules/@babel/parser/lib/index.js +++ b/PAMapp/node_modules/@babel/parser/lib/index.js @@ -2,59 +2,29 @@ Object.defineProperty(exports, '__esModule', { value: true }); -const lineBreak = /\r\n?|[\n\u2028\u2029]/; -const lineBreakG = new RegExp(lineBreak.source, "g"); -function isNewLine(code) { - switch (code) { - case 10: - case 13: - case 8232: - case 8233: - return true; +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; - default: - return false; + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; } -} -const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; -const skipWhiteSpaceInLine = /(?:[^\S\n\r\u2028\u2029]|\/\/.*|\/\*.*?\*\/)*/y; -const skipWhiteSpaceToLineBreak = new RegExp("(?=(" + skipWhiteSpaceInLine.source + "))\\1" + /(?=[\n\r\u2028\u2029]|\/\*(?!.*?\*\/)|$)/.source, "y"); -function isWhitespace(code) { - switch (code) { - case 0x0009: - case 0x000b: - case 0x000c: - case 32: - case 160: - case 5760: - case 0x2000: - case 0x2001: - case 0x2002: - case 0x2003: - case 0x2004: - case 0x2005: - case 0x2006: - case 0x2007: - case 0x2008: - case 0x2009: - case 0x200a: - case 0x202f: - case 0x205f: - case 0x3000: - case 0xfeff: - return true; - default: - return false; - } + return target; } class Position { - constructor(line, col) { + constructor(line, col, index) { this.line = void 0; this.column = void 0; + this.index = void 0; this.line = line; this.column = col; + this.index = index; } } @@ -69,489 +39,413 @@ } } -function getLineInfo(input, offset) { - let line = 1; - let lineStart = 0; - let match; - lineBreakG.lastIndex = 0; - - while ((match = lineBreakG.exec(input)) && match.index < offset) { - line++; - lineStart = lineBreakG.lastIndex; - } - - return new Position(line, offset - lineStart); +function createPositionWithColumnOffset(position, columnOffset) { + const { + line, + column, + index + } = position; + return new Position(line, column + columnOffset, index + columnOffset); } -class BaseParser { - constructor() { - this.sawUnambiguousESM = false; - this.ambiguousScriptDifferentAst = false; - } - - hasPlugin(name) { - return this.plugins.has(name); - } - - getPluginOption(plugin, name) { - if (this.hasPlugin(plugin)) return this.plugins.get(plugin)[name]; - } - -} - -function setTrailingComments(node, comments) { - if (node.trailingComments === undefined) { - node.trailingComments = comments; - } else { - node.trailingComments.unshift(...comments); - } -} - -function setLeadingComments(node, comments) { - if (node.leadingComments === undefined) { - node.leadingComments = comments; - } else { - node.leadingComments.unshift(...comments); - } -} - -function setInnerComments(node, comments) { - if (node.innerComments === undefined) { - node.innerComments = comments; - } else { - node.innerComments.unshift(...comments); - } -} - -function adjustInnerComments(node, elements, commentWS) { - let lastElement = null; - let i = elements.length; - - while (lastElement === null && i > 0) { - lastElement = elements[--i]; - } - - if (lastElement === null || lastElement.start > commentWS.start) { - setInnerComments(node, commentWS.comments); - } else { - setTrailingComments(lastElement, commentWS.comments); - } -} - -class CommentsParser extends BaseParser { - addComment(comment) { - if (this.filename) comment.loc.filename = this.filename; - this.state.comments.push(comment); - } - - processComment(node) { - const { - commentStack - } = this.state; - const commentStackLength = commentStack.length; - if (commentStackLength === 0) return; - let i = commentStackLength - 1; - const lastCommentWS = commentStack[i]; - - if (lastCommentWS.start === node.end) { - lastCommentWS.leadingNode = node; - i--; - } - - const { - start: nodeStart - } = node; - - for (; i >= 0; i--) { - const commentWS = commentStack[i]; - const commentEnd = commentWS.end; - - if (commentEnd > nodeStart) { - commentWS.containingNode = node; - this.finalizeComment(commentWS); - commentStack.splice(i, 1); - } else { - if (commentEnd === nodeStart) { - commentWS.trailingNode = node; - } - - break; - } - } - } - - finalizeComment(commentWS) { - const { - comments - } = commentWS; - - if (commentWS.leadingNode !== null || commentWS.trailingNode !== null) { - if (commentWS.leadingNode !== null) { - setTrailingComments(commentWS.leadingNode, comments); - } - - if (commentWS.trailingNode !== null) { - setLeadingComments(commentWS.trailingNode, comments); - } - } else { - const { - containingNode: node, - start: commentStart - } = commentWS; - - if (this.input.charCodeAt(commentStart - 1) === 44) { - switch (node.type) { - case "ObjectExpression": - case "ObjectPattern": - case "RecordExpression": - adjustInnerComments(node, node.properties, commentWS); - break; - - case "CallExpression": - case "OptionalCallExpression": - adjustInnerComments(node, node.arguments, commentWS); - break; - - case "FunctionDeclaration": - case "FunctionExpression": - case "ArrowFunctionExpression": - case "ObjectMethod": - case "ClassMethod": - case "ClassPrivateMethod": - adjustInnerComments(node, node.params, commentWS); - break; - - case "ArrayExpression": - case "ArrayPattern": - case "TupleExpression": - adjustInnerComments(node, node.elements, commentWS); - break; - - case "ExportNamedDeclaration": - case "ImportDeclaration": - adjustInnerComments(node, node.specifiers, commentWS); - break; - - default: - { - setInnerComments(node, comments); - } - } - } else { - setInnerComments(node, comments); - } - } - } - - finalizeRemainingComments() { - const { - commentStack - } = this.state; - - for (let i = commentStack.length - 1; i >= 0; i--) { - this.finalizeComment(commentStack[i]); - } - - this.state.commentStack = []; - } - - resetPreviousNodeTrailingComments(node) { - const { - commentStack - } = this.state; - const { - length - } = commentStack; - if (length === 0) return; - const commentWS = commentStack[length - 1]; - - if (commentWS.leadingNode === node) { - commentWS.leadingNode = null; - } - } - - takeSurroundingComments(node, start, end) { - const { - commentStack - } = this.state; - const commentStackLength = commentStack.length; - if (commentStackLength === 0) return; - let i = commentStackLength - 1; - - for (; i >= 0; i--) { - const commentWS = commentStack[i]; - const commentEnd = commentWS.end; - const commentStart = commentWS.start; - - if (commentStart === end) { - commentWS.leadingNode = node; - } else if (commentEnd === start) { - commentWS.trailingNode = node; - } else if (commentEnd < start) { - break; - } - } - } - -} - -const ErrorCodes = Object.freeze({ +const ParseErrorCodes = Object.freeze({ SyntaxError: "BABEL_PARSER_SYNTAX_ERROR", SourceTypeModuleError: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" }); -const ErrorMessages = makeErrorTemplates({ - AccessorIsGenerator: "A %0ter cannot be a generator.", - ArgumentsInClass: "'arguments' is only allowed in functions and class methods.", - AsyncFunctionInSingleStatementContext: "Async functions can only be declared at the top level or inside a block.", - AwaitBindingIdentifier: "Can not use 'await' as identifier inside an async function.", - AwaitBindingIdentifierInStaticBlock: "Can not use 'await' as identifier inside a static block.", - AwaitExpressionFormalParameter: "'await' is not allowed in async function parameters.", - AwaitNotInAsyncContext: "'await' is only allowed within async functions and at the top levels of modules.", - AwaitNotInAsyncFunction: "'await' is only allowed within async functions.", - BadGetterArity: "A 'get' accesor must not have any formal parameters.", - BadSetterArity: "A 'set' accesor must have exactly one formal parameter.", - BadSetterRestParameter: "A 'set' accesor function argument must not be a rest parameter.", - ConstructorClassField: "Classes may not have a field named 'constructor'.", - ConstructorClassPrivateField: "Classes may not have a private field named '#constructor'.", - ConstructorIsAccessor: "Class constructor may not be an accessor.", - ConstructorIsAsync: "Constructor can't be an async function.", - ConstructorIsGenerator: "Constructor can't be a generator.", - DeclarationMissingInitializer: "'%0' require an initialization value.", - DecoratorBeforeExport: "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax.", - DecoratorConstructor: "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?", - DecoratorExportClass: "Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.", - DecoratorSemicolon: "Decorators must not be followed by a semicolon.", - DecoratorStaticBlock: "Decorators can't be used with a static block.", - DeletePrivateField: "Deleting a private field is not allowed.", - DestructureNamedImport: "ES2015 named imports do not destructure. Use another statement for destructuring after the import.", - DuplicateConstructor: "Duplicate constructor in the same class.", - DuplicateDefaultExport: "Only one default export allowed per module.", - DuplicateExport: "`%0` has already been exported. Exported identifiers must be unique.", - DuplicateProto: "Redefinition of __proto__ property.", - DuplicateRegExpFlags: "Duplicate regular expression flag.", - ElementAfterRest: "Rest element must be last element.", - EscapedCharNotAnIdentifier: "Invalid Unicode escape.", - ExportBindingIsString: "A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { '%0' as '%1' } from 'some-module'`?", - ExportDefaultFromAsIdentifier: "'from' is not allowed as an identifier after 'export default'.", - ForInOfLoopInitializer: "'%0' loop variable declaration may not have an initializer.", - ForOfAsync: "The left-hand side of a for-of loop may not be 'async'.", - ForOfLet: "The left-hand side of a for-of loop may not start with 'let'.", - GeneratorInSingleStatementContext: "Generators can only be declared at the top level or inside a block.", - IllegalBreakContinue: "Unsyntactic %0.", - IllegalLanguageModeDirective: "Illegal 'use strict' directive in function with non-simple parameter list.", - IllegalReturn: "'return' outside of function.", - ImportBindingIsString: 'A string literal cannot be used as an imported binding.\n- Did you mean `import { "%0" as foo }`?', - ImportCallArgumentTrailingComma: "Trailing comma is disallowed inside import(...) arguments.", - ImportCallArity: "`import()` requires exactly %0.", - ImportCallNotNewExpression: "Cannot use new with import(...).", - ImportCallSpreadArgument: "`...` is not allowed in `import()`.", - InvalidBigIntLiteral: "Invalid BigIntLiteral.", - InvalidCodePoint: "Code point out of bounds.", - InvalidDecimal: "Invalid decimal.", - InvalidDigit: "Expected number in radix %0.", - InvalidEscapeSequence: "Bad character escape sequence.", - InvalidEscapeSequenceTemplate: "Invalid escape sequence in template.", - InvalidEscapedReservedWord: "Escape sequence in keyword %0.", - InvalidIdentifier: "Invalid identifier %0.", - InvalidLhs: "Invalid left-hand side in %0.", - InvalidLhsBinding: "Binding invalid left-hand side in %0.", - InvalidNumber: "Invalid number.", - InvalidOrMissingExponent: "Floating-point numbers require a valid exponent after the 'e'.", - InvalidOrUnexpectedToken: "Unexpected character '%0'.", - InvalidParenthesizedAssignment: "Invalid parenthesized assignment pattern.", - InvalidPrivateFieldResolution: "Private name #%0 is not defined.", - InvalidPropertyBindingPattern: "Binding member expression.", - InvalidRecordProperty: "Only properties and spread elements are allowed in record definitions.", - InvalidRestAssignmentPattern: "Invalid rest operator's argument.", - LabelRedeclaration: "Label '%0' is already declared.", - LetInLexicalBinding: "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", - LineTerminatorBeforeArrow: "No line break is allowed before '=>'.", - MalformedRegExpFlags: "Invalid regular expression flag.", - MissingClassName: "A class name is required.", - MissingEqInAssignment: "Only '=' operator can be used for specifying default value.", - MissingSemicolon: "Missing semicolon.", - MissingUnicodeEscape: "Expecting Unicode escape sequence \\uXXXX.", - MixingCoalesceWithLogical: "Nullish coalescing operator(??) requires parens when mixing with logical operators.", - ModuleAttributeDifferentFromType: "The only accepted module attribute is `type`.", - ModuleAttributeInvalidValue: "Only string literals are allowed as module attribute values.", - ModuleAttributesWithDuplicateKeys: 'Duplicate key "%0" is not allowed in module attributes.', - ModuleExportNameHasLoneSurrogate: "An export name cannot include a lone surrogate, found '\\u%0'.", - ModuleExportUndefined: "Export '%0' is not defined.", - MultipleDefaultsInSwitch: "Multiple default clauses.", - NewlineAfterThrow: "Illegal newline after throw.", - NoCatchOrFinally: "Missing catch or finally clause.", - NumberIdentifier: "Identifier directly after number.", - NumericSeparatorInEscapeSequence: "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences.", - ObsoleteAwaitStar: "'await*' has been removed from the async functions proposal. Use Promise.all() instead.", - OptionalChainingNoNew: "Constructors in/after an Optional Chain are not allowed.", - OptionalChainingNoTemplate: "Tagged Template Literals are not allowed in optionalChain.", - OverrideOnConstructor: "'override' modifier cannot appear on a constructor declaration.", - ParamDupe: "Argument name clash.", - PatternHasAccessor: "Object pattern can't contain getter or setter.", - PatternHasMethod: "Object pattern can't contain methods.", - PipeBodyIsTighter: "Unexpected %0 after pipeline body; any %0 expression acting as Hack-style pipe body must be parenthesized due to its loose operator precedence.", - PipeTopicRequiresHackPipes: 'Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.', - PipeTopicUnbound: "Topic reference is unbound; it must be inside a pipe body.", - PipeTopicUnconfiguredToken: 'Invalid topic token %0. In order to use %0 as a topic reference, the pipelineOperator plugin must be configured with { "proposal": "hack", "topicToken": "%0" }.', - PipeTopicUnused: "Hack-style pipe body does not contain a topic reference; Hack-style pipes must use topic at least once.", - PipeUnparenthesizedBody: "Hack-style pipe body cannot be an unparenthesized %0 expression; please wrap it in parentheses.", - PipelineBodyNoArrow: 'Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized.', - PipelineBodySequenceExpression: "Pipeline body may not be a comma-separated sequence expression.", - PipelineHeadSequenceExpression: "Pipeline head should not be a comma-separated sequence expression.", - PipelineTopicUnused: "Pipeline is in topic style but does not use topic reference.", - PrimaryTopicNotAllowed: "Topic reference was used in a lexical context without topic binding.", - PrimaryTopicRequiresSmartPipeline: 'Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.', - PrivateInExpectedIn: "Private names are only allowed in property accesses (`obj.#%0`) or in `in` expressions (`#%0 in obj`).", - PrivateNameRedeclaration: "Duplicate private name #%0.", - RecordExpressionBarIncorrectEndSyntaxType: "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", - RecordExpressionBarIncorrectStartSyntaxType: "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", - RecordExpressionHashIncorrectStartSyntaxType: "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'.", - RecordNoProto: "'__proto__' is not allowed in Record expressions.", - RestTrailingComma: "Unexpected trailing comma after rest element.", - SloppyFunction: "In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement.", - StaticPrototype: "Classes may not have static property named prototype.", - StrictDelete: "Deleting local variable in strict mode.", - StrictEvalArguments: "Assigning to '%0' in strict mode.", - StrictEvalArgumentsBinding: "Binding '%0' in strict mode.", - StrictFunction: "In strict mode code, functions can only be declared at top level or inside a block.", - StrictNumericEscape: "The only valid numeric escape in strict mode is '\\0'.", - StrictOctalLiteral: "Legacy octal literals are not allowed in strict mode.", - StrictWith: "'with' in strict mode.", - SuperNotAllowed: "`super()` is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class?", - SuperPrivateField: "Private fields can't be accessed on super.", - TrailingDecorator: "Decorators must be attached to a class element.", - TupleExpressionBarIncorrectEndSyntaxType: "Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", - TupleExpressionBarIncorrectStartSyntaxType: "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'.", - TupleExpressionHashIncorrectStartSyntaxType: "Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'.", - UnexpectedArgumentPlaceholder: "Unexpected argument placeholder.", - UnexpectedAwaitAfterPipelineBody: 'Unexpected "await" after pipeline body; await must have parentheses in minimal proposal.', - UnexpectedDigitAfterHash: "Unexpected digit after hash token.", - UnexpectedImportExport: "'import' and 'export' may only appear at the top level.", - UnexpectedKeyword: "Unexpected keyword '%0'.", - UnexpectedLeadingDecorator: "Leading decorators must be attached to a class declaration.", - UnexpectedLexicalDeclaration: "Lexical declaration cannot appear in a single-statement context.", - UnexpectedNewTarget: "`new.target` can only be used in functions or class properties.", - UnexpectedNumericSeparator: "A numeric separator is only allowed between two digits.", - UnexpectedPrivateField: "Private names can only be used as the name of a class element (i.e. class C { #p = 42; #m() {} } )\n or a property of member expression (i.e. this.#p).", - UnexpectedReservedWord: "Unexpected reserved word '%0'.", - UnexpectedSuper: "'super' is only allowed in object methods and classes.", - UnexpectedToken: "Unexpected token '%0'.", - UnexpectedTokenUnaryExponentiation: "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.", - UnsupportedBind: "Binding should be performed on object property.", - UnsupportedDecoratorExport: "A decorated export must export a class declaration.", - UnsupportedDefaultExport: "Only expressions, functions or classes are allowed as the `default` export.", - UnsupportedImport: "`import` can only be used in `import()` or `import.meta`.", - UnsupportedMetaProperty: "The only valid meta property for %0 is %0.%1.", - UnsupportedParameterDecorator: "Decorators cannot be used to decorate parameters.", - UnsupportedPropertyDecorator: "Decorators cannot be used to decorate object literal properties.", - UnsupportedSuper: "'super' can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop]).", - UnterminatedComment: "Unterminated comment.", - UnterminatedRegExp: "Unterminated regular expression.", - UnterminatedString: "Unterminated string constant.", - UnterminatedTemplate: "Unterminated template.", - VarRedeclaration: "Identifier '%0' has already been declared.", - YieldBindingIdentifier: "Can not use 'yield' as identifier inside a generator.", - YieldInParameter: "Yield expression is not allowed in formal parameters.", - ZeroDigitNumericSeparator: "Numeric separator can not be used after leading 0." -}, ErrorCodes.SyntaxError); -const SourceTypeModuleErrorMessages = makeErrorTemplates({ - ImportMetaOutsideModule: `import.meta may appear only with 'sourceType: "module"'`, - ImportOutsideModule: `'import' and 'export' may appear only with 'sourceType: "module"'` -}, ErrorCodes.SourceTypeModuleError); +const reflect = (keys, last = keys.length - 1) => ({ + get() { + return keys.reduce((object, key) => object[key], this); + }, -function keepReasonCodeCompat(reasonCode, syntaxPlugin) { - { - if (syntaxPlugin === "flow" && reasonCode === "PatternIsOptional") { - return "OptionalBindingPattern"; - } - } - return reasonCode; -} - -function makeErrorTemplates(messages, code, syntaxPlugin) { - const templates = {}; - Object.keys(messages).forEach(reasonCode => { - templates[reasonCode] = Object.freeze({ - code, - reasonCode: keepReasonCodeCompat(reasonCode, syntaxPlugin), - template: messages[reasonCode] - }); - }); - return Object.freeze(templates); -} -class ParserError extends CommentsParser { - getLocationForPosition(pos) { - let loc; - if (pos === this.state.start) loc = this.state.startLoc;else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc;else if (pos === this.state.end) loc = this.state.endLoc;else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc;else loc = getLineInfo(this.input, pos); - return loc; + set(value) { + keys.reduce((item, key, i) => i === last ? item[key] = value : item[key], this); } - raise(pos, { - code, - reasonCode, - template - }, ...params) { - return this.raiseWithData(pos, { - code, - reasonCode - }, template, ...params); - } +}); - raiseOverwrite(pos, { - code, - template - }, ...params) { - const loc = this.getLocationForPosition(pos); - const message = template.replace(/%(\d+)/g, (_, i) => params[i]) + ` (${loc.line}:${loc.column})`; +const instantiate = (constructor, properties, descriptors) => Object.keys(descriptors).map(key => [key, descriptors[key]]).filter(([, descriptor]) => !!descriptor).map(([key, descriptor]) => [key, typeof descriptor === "function" ? { + value: descriptor, + enumerable: false +} : typeof descriptor.reflect === "string" ? Object.assign({}, descriptor, reflect(descriptor.reflect.split("."))) : descriptor]).reduce((instance, [key, descriptor]) => Object.defineProperty(instance, key, Object.assign({ + configurable: true +}, descriptor)), Object.assign(new constructor(), properties)); - if (this.options.errorRecovery) { - const errors = this.state.errors; +var ModuleErrors = (_ => ({ + ImportMetaOutsideModule: _(`import.meta may appear only with 'sourceType: "module"'`, { + code: ParseErrorCodes.SourceTypeModuleError + }), + ImportOutsideModule: _(`'import' and 'export' may appear only with 'sourceType: "module"'`, { + code: ParseErrorCodes.SourceTypeModuleError + }) +})); - for (let i = errors.length - 1; i >= 0; i--) { - const error = errors[i]; +const NodeDescriptions = { + ArrayPattern: "array destructuring pattern", + AssignmentExpression: "assignment expression", + AssignmentPattern: "assignment expression", + ArrowFunctionExpression: "arrow function expression", + ConditionalExpression: "conditional expression", + ForOfStatement: "for-of statement", + ForInStatement: "for-in statement", + ForStatement: "for-loop", + FormalParameters: "function parameter list", + Identifier: "identifier", + ObjectPattern: "object destructuring pattern", + ParenthesizedExpression: "parenthesized expression", + RestElement: "rest element", + UpdateExpression: { + true: "prefix operation", + false: "postfix operation" + }, + VariableDeclarator: "variable declaration", + YieldExpression: "yield expression" +}; - if (error.pos === pos) { - return Object.assign(error, { - message +const toNodeDescription = ({ + type, + prefix +}) => type === "UpdateExpression" ? NodeDescriptions.UpdateExpression[String(prefix)] : NodeDescriptions[type]; + +var StandardErrors = (_ => ({ + AccessorIsGenerator: _(({ + kind + }) => `A ${kind}ter cannot be a generator.`), + ArgumentsInClass: _("'arguments' is only allowed in functions and class methods."), + AsyncFunctionInSingleStatementContext: _("Async functions can only be declared at the top level or inside a block."), + AwaitBindingIdentifier: _("Can not use 'await' as identifier inside an async function."), + AwaitBindingIdentifierInStaticBlock: _("Can not use 'await' as identifier inside a static block."), + AwaitExpressionFormalParameter: _("'await' is not allowed in async function parameters."), + AwaitNotInAsyncContext: _("'await' is only allowed within async functions and at the top levels of modules."), + AwaitNotInAsyncFunction: _("'await' is only allowed within async functions."), + BadGetterArity: _("A 'get' accesor must not have any formal parameters."), + BadSetterArity: _("A 'set' accesor must have exactly one formal parameter."), + BadSetterRestParameter: _("A 'set' accesor function argument must not be a rest parameter."), + ConstructorClassField: _("Classes may not have a field named 'constructor'."), + ConstructorClassPrivateField: _("Classes may not have a private field named '#constructor'."), + ConstructorIsAccessor: _("Class constructor may not be an accessor."), + ConstructorIsAsync: _("Constructor can't be an async function."), + ConstructorIsGenerator: _("Constructor can't be a generator."), + DeclarationMissingInitializer: _(({ + kind + }) => `Missing initializer in ${kind} declaration.`), + DecoratorBeforeExport: _("Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax."), + DecoratorConstructor: _("Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?"), + DecoratorExportClass: _("Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead."), + DecoratorSemicolon: _("Decorators must not be followed by a semicolon."), + DecoratorStaticBlock: _("Decorators can't be used with a static block."), + DeletePrivateField: _("Deleting a private field is not allowed."), + DestructureNamedImport: _("ES2015 named imports do not destructure. Use another statement for destructuring after the import."), + DuplicateConstructor: _("Duplicate constructor in the same class."), + DuplicateDefaultExport: _("Only one default export allowed per module."), + DuplicateExport: _(({ + exportName + }) => `\`${exportName}\` has already been exported. Exported identifiers must be unique.`), + DuplicateProto: _("Redefinition of __proto__ property."), + DuplicateRegExpFlags: _("Duplicate regular expression flag."), + ElementAfterRest: _("Rest element must be last element."), + EscapedCharNotAnIdentifier: _("Invalid Unicode escape."), + ExportBindingIsString: _(({ + localName, + exportName + }) => `A string literal cannot be used as an exported binding without \`from\`.\n- Did you mean \`export { '${localName}' as '${exportName}' } from 'some-module'\`?`), + ExportDefaultFromAsIdentifier: _("'from' is not allowed as an identifier after 'export default'."), + ForInOfLoopInitializer: _(({ + type + }) => `'${type === "ForInStatement" ? "for-in" : "for-of"}' loop variable declaration may not have an initializer.`), + ForOfAsync: _("The left-hand side of a for-of loop may not be 'async'."), + ForOfLet: _("The left-hand side of a for-of loop may not start with 'let'."), + GeneratorInSingleStatementContext: _("Generators can only be declared at the top level or inside a block."), + IllegalBreakContinue: _(({ + type + }) => `Unsyntactic ${type === "BreakStatement" ? "break" : "continue"}.`), + IllegalLanguageModeDirective: _("Illegal 'use strict' directive in function with non-simple parameter list."), + IllegalReturn: _("'return' outside of function."), + ImportBindingIsString: _(({ + importName + }) => `A string literal cannot be used as an imported binding.\n- Did you mean \`import { "${importName}" as foo }\`?`), + ImportCallArgumentTrailingComma: _("Trailing comma is disallowed inside import(...) arguments."), + ImportCallArity: _(({ + maxArgumentCount + }) => `\`import()\` requires exactly ${maxArgumentCount === 1 ? "one argument" : "one or two arguments"}.`), + ImportCallNotNewExpression: _("Cannot use new with import(...)."), + ImportCallSpreadArgument: _("`...` is not allowed in `import()`."), + IncompatibleRegExpUVFlags: _("The 'u' and 'v' regular expression flags cannot be enabled at the same time."), + InvalidBigIntLiteral: _("Invalid BigIntLiteral."), + InvalidCodePoint: _("Code point out of bounds."), + InvalidCoverInitializedName: _("Invalid shorthand property initializer."), + InvalidDecimal: _("Invalid decimal."), + InvalidDigit: _(({ + radix + }) => `Expected number in radix ${radix}.`), + InvalidEscapeSequence: _("Bad character escape sequence."), + InvalidEscapeSequenceTemplate: _("Invalid escape sequence in template."), + InvalidEscapedReservedWord: _(({ + reservedWord + }) => `Escape sequence in keyword ${reservedWord}.`), + InvalidIdentifier: _(({ + identifierName + }) => `Invalid identifier ${identifierName}.`), + InvalidLhs: _(({ + ancestor + }) => `Invalid left-hand side in ${toNodeDescription(ancestor)}.`), + InvalidLhsBinding: _(({ + ancestor + }) => `Binding invalid left-hand side in ${toNodeDescription(ancestor)}.`), + InvalidNumber: _("Invalid number."), + InvalidOrMissingExponent: _("Floating-point numbers require a valid exponent after the 'e'."), + InvalidOrUnexpectedToken: _(({ + unexpected + }) => `Unexpected character '${unexpected}'.`), + InvalidParenthesizedAssignment: _("Invalid parenthesized assignment pattern."), + InvalidPrivateFieldResolution: _(({ + identifierName + }) => `Private name #${identifierName} is not defined.`), + InvalidPropertyBindingPattern: _("Binding member expression."), + InvalidRecordProperty: _("Only properties and spread elements are allowed in record definitions."), + InvalidRestAssignmentPattern: _("Invalid rest operator's argument."), + LabelRedeclaration: _(({ + labelName + }) => `Label '${labelName}' is already declared.`), + LetInLexicalBinding: _("'let' is not allowed to be used as a name in 'let' or 'const' declarations."), + LineTerminatorBeforeArrow: _("No line break is allowed before '=>'."), + MalformedRegExpFlags: _("Invalid regular expression flag."), + MissingClassName: _("A class name is required."), + MissingEqInAssignment: _("Only '=' operator can be used for specifying default value."), + MissingSemicolon: _("Missing semicolon."), + MissingPlugin: _(({ + missingPlugin + }) => `This experimental syntax requires enabling the parser plugin: ${missingPlugin.map(name => JSON.stringify(name)).join(", ")}.`), + MissingOneOfPlugins: _(({ + missingPlugin + }) => `This experimental syntax requires enabling one of the following parser plugin(s): ${missingPlugin.map(name => JSON.stringify(name)).join(", ")}.`), + MissingUnicodeEscape: _("Expecting Unicode escape sequence \\uXXXX."), + MixingCoalesceWithLogical: _("Nullish coalescing operator(??) requires parens when mixing with logical operators."), + ModuleAttributeDifferentFromType: _("The only accepted module attribute is `type`."), + ModuleAttributeInvalidValue: _("Only string literals are allowed as module attribute values."), + ModuleAttributesWithDuplicateKeys: _(({ + key + }) => `Duplicate key "${key}" is not allowed in module attributes.`), + ModuleExportNameHasLoneSurrogate: _(({ + surrogateCharCode + }) => `An export name cannot include a lone surrogate, found '\\u${surrogateCharCode.toString(16)}'.`), + ModuleExportUndefined: _(({ + localName + }) => `Export '${localName}' is not defined.`), + MultipleDefaultsInSwitch: _("Multiple default clauses."), + NewlineAfterThrow: _("Illegal newline after throw."), + NoCatchOrFinally: _("Missing catch or finally clause."), + NumberIdentifier: _("Identifier directly after number."), + NumericSeparatorInEscapeSequence: _("Numeric separators are not allowed inside unicode escape sequences or hex escape sequences."), + ObsoleteAwaitStar: _("'await*' has been removed from the async functions proposal. Use Promise.all() instead."), + OptionalChainingNoNew: _("Constructors in/after an Optional Chain are not allowed."), + OptionalChainingNoTemplate: _("Tagged Template Literals are not allowed in optionalChain."), + OverrideOnConstructor: _("'override' modifier cannot appear on a constructor declaration."), + ParamDupe: _("Argument name clash."), + PatternHasAccessor: _("Object pattern can't contain getter or setter."), + PatternHasMethod: _("Object pattern can't contain methods."), + PrivateInExpectedIn: _(({ + identifierName + }) => `Private names are only allowed in property accesses (\`obj.#${identifierName}\`) or in \`in\` expressions (\`#${identifierName} in obj\`).`), + PrivateNameRedeclaration: _(({ + identifierName + }) => `Duplicate private name #${identifierName}.`), + RecordExpressionBarIncorrectEndSyntaxType: _("Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'."), + RecordExpressionBarIncorrectStartSyntaxType: _("Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'."), + RecordExpressionHashIncorrectStartSyntaxType: _("Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'."), + RecordNoProto: _("'__proto__' is not allowed in Record expressions."), + RestTrailingComma: _("Unexpected trailing comma after rest element."), + SloppyFunction: _("In non-strict mode code, functions can only be declared at top level, inside a block, or as the body of an if statement."), + StaticPrototype: _("Classes may not have static property named prototype."), + SuperNotAllowed: _("`super()` is only valid inside a class constructor of a subclass. Maybe a typo in the method name ('constructor') or not extending another class?"), + SuperPrivateField: _("Private fields can't be accessed on super."), + TrailingDecorator: _("Decorators must be attached to a class element."), + TupleExpressionBarIncorrectEndSyntaxType: _("Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'."), + TupleExpressionBarIncorrectStartSyntaxType: _("Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'."), + TupleExpressionHashIncorrectStartSyntaxType: _("Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'."), + UnexpectedArgumentPlaceholder: _("Unexpected argument placeholder."), + UnexpectedAwaitAfterPipelineBody: _('Unexpected "await" after pipeline body; await must have parentheses in minimal proposal.'), + UnexpectedDigitAfterHash: _("Unexpected digit after hash token."), + UnexpectedImportExport: _("'import' and 'export' may only appear at the top level."), + UnexpectedKeyword: _(({ + keyword + }) => `Unexpected keyword '${keyword}'.`), + UnexpectedLeadingDecorator: _("Leading decorators must be attached to a class declaration."), + UnexpectedLexicalDeclaration: _("Lexical declaration cannot appear in a single-statement context."), + UnexpectedNewTarget: _("`new.target` can only be used in functions or class properties."), + UnexpectedNumericSeparator: _("A numeric separator is only allowed between two digits."), + UnexpectedPrivateField: _("Unexpected private name."), + UnexpectedReservedWord: _(({ + reservedWord + }) => `Unexpected reserved word '${reservedWord}'.`), + UnexpectedSuper: _("'super' is only allowed in object methods and classes."), + UnexpectedToken: _(({ + expected, + unexpected + }) => `Unexpected token${unexpected ? ` '${unexpected}'.` : ""}${expected ? `, expected "${expected}"` : ""}`), + UnexpectedTokenUnaryExponentiation: _("Illegal expression. Wrap left hand side or entire exponentiation in parentheses."), + UnsupportedBind: _("Binding should be performed on object property."), + UnsupportedDecoratorExport: _("A decorated export must export a class declaration."), + UnsupportedDefaultExport: _("Only expressions, functions or classes are allowed as the `default` export."), + UnsupportedImport: _("`import` can only be used in `import()` or `import.meta`."), + UnsupportedMetaProperty: _(({ + target, + onlyValidPropertyName + }) => `The only valid meta property for ${target} is ${target}.${onlyValidPropertyName}.`), + UnsupportedParameterDecorator: _("Decorators cannot be used to decorate parameters."), + UnsupportedPropertyDecorator: _("Decorators cannot be used to decorate object literal properties."), + UnsupportedSuper: _("'super' can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop])."), + UnterminatedComment: _("Unterminated comment."), + UnterminatedRegExp: _("Unterminated regular expression."), + UnterminatedString: _("Unterminated string constant."), + UnterminatedTemplate: _("Unterminated template."), + VarRedeclaration: _(({ + identifierName + }) => `Identifier '${identifierName}' has already been declared.`), + YieldBindingIdentifier: _("Can not use 'yield' as identifier inside a generator."), + YieldInParameter: _("Yield expression is not allowed in formal parameters."), + ZeroDigitNumericSeparator: _("Numeric separator can not be used after leading 0.") +})); + +var StrictModeErrors = (_ => ({ + StrictDelete: _("Deleting local variable in strict mode."), + StrictEvalArguments: _(({ + referenceName + }) => `Assigning to '${referenceName}' in strict mode.`), + StrictEvalArgumentsBinding: _(({ + bindingName + }) => `Binding '${bindingName}' in strict mode.`), + StrictFunction: _("In strict mode code, functions can only be declared at top level or inside a block."), + StrictNumericEscape: _("The only valid numeric escape in strict mode is '\\0'."), + StrictOctalLiteral: _("Legacy octal literals are not allowed in strict mode."), + StrictWith: _("'with' in strict mode.") +})); + +const UnparenthesizedPipeBodyDescriptions = new Set(["ArrowFunctionExpression", "AssignmentExpression", "ConditionalExpression", "YieldExpression"]); +var PipelineOperatorErrors = (_ => ({ + PipeBodyIsTighter: _("Unexpected yield after pipeline body; any yield expression acting as Hack-style pipe body must be parenthesized due to its loose operator precedence."), + PipeTopicRequiresHackPipes: _('Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.'), + PipeTopicUnbound: _("Topic reference is unbound; it must be inside a pipe body."), + PipeTopicUnconfiguredToken: _(({ + token + }) => `Invalid topic token ${token}. In order to use ${token} as a topic reference, the pipelineOperator plugin must be configured with { "proposal": "hack", "topicToken": "${token}" }.`), + PipeTopicUnused: _("Hack-style pipe body does not contain a topic reference; Hack-style pipes must use topic at least once."), + PipeUnparenthesizedBody: _(({ + type + }) => `Hack-style pipe body cannot be an unparenthesized ${toNodeDescription({ + type + })}; please wrap it in parentheses.`), + PipelineBodyNoArrow: _('Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized.'), + PipelineBodySequenceExpression: _("Pipeline body may not be a comma-separated sequence expression."), + PipelineHeadSequenceExpression: _("Pipeline head should not be a comma-separated sequence expression."), + PipelineTopicUnused: _("Pipeline is in topic style but does not use topic reference."), + PrimaryTopicNotAllowed: _("Topic reference was used in a lexical context without topic binding."), + PrimaryTopicRequiresSmartPipeline: _('Topic reference is used, but the pipelineOperator plugin was not passed a "proposal": "hack" or "smart" option.') +})); + +const _excluded$1 = ["toMessage"]; + +function toParseErrorConstructor(_ref) { + let { + toMessage + } = _ref, + properties = _objectWithoutPropertiesLoose(_ref, _excluded$1); + + return function constructor({ + loc, + details + }) { + return instantiate(SyntaxError, Object.assign({}, properties, { + loc + }), { + clone(overrides = {}) { + const loc = overrides.loc || {}; + return constructor({ + loc: new Position("line" in loc ? loc.line : this.loc.line, "column" in loc ? loc.column : this.loc.column, "index" in loc ? loc.index : this.loc.index), + details: Object.assign({}, this.details, overrides.details) + }); + }, + + details: { + value: details, + enumerable: false + }, + message: { + get() { + return `${toMessage(this.details)} (${this.loc.line}:${this.loc.column})`; + }, + + set(value) { + Object.defineProperty(this, "message", { + value }); - } else if (error.pos < pos) { - break; } + + }, + pos: { + reflect: "loc.index", + enumerable: true + }, + missingPlugin: "missingPlugin" in details && { + reflect: "details.missingPlugin", + enumerable: true } - } + }); + }; +} - return this._raise({ - code, - loc, - pos - }, message); +function toParseErrorCredentials(toMessageOrMessage, credentials) { + return Object.assign({ + toMessage: typeof toMessageOrMessage === "string" ? () => toMessageOrMessage : toMessageOrMessage + }, credentials); +} +function ParseErrorEnum(argument, syntaxPlugin) { + if (Array.isArray(argument)) { + return toParseErrorCredentialsMap => ParseErrorEnum(toParseErrorCredentialsMap, argument[0]); } - raiseWithData(pos, data, errorTemplate, ...params) { - const loc = this.getLocationForPosition(pos); - const message = errorTemplate.replace(/%(\d+)/g, (_, i) => params[i]) + ` (${loc.line}:${loc.column})`; - return this._raise(Object.assign({ - loc, - pos - }, data), message); + const partialCredentials = argument(toParseErrorCredentials); + const ParseErrorConstructors = {}; + + for (const reasonCode of Object.keys(partialCredentials)) { + ParseErrorConstructors[reasonCode] = toParseErrorConstructor(Object.assign({ + code: ParseErrorCodes.SyntaxError, + reasonCode + }, syntaxPlugin ? { + syntaxPlugin + } : {}, partialCredentials[reasonCode])); } - _raise(errorContext, message) { - const err = new SyntaxError(message); - Object.assign(err, errorContext); + return ParseErrorConstructors; +} +const Errors = Object.assign({}, ParseErrorEnum(ModuleErrors), ParseErrorEnum(StandardErrors), ParseErrorEnum(StrictModeErrors), ParseErrorEnum`pipelineOperator`(PipelineOperatorErrors)); - if (this.options.errorRecovery) { - if (!this.isLookahead) this.state.errors.push(err); - return err; - } else { - throw err; - } - } +const { + defineProperty +} = Object; +const toUnenumerable = (object, key) => defineProperty(object, key, { + enumerable: false, + value: object[key] +}); + +function toESTreeLocation(node) { + toUnenumerable(node.loc.start, "index"); + toUnenumerable(node.loc.end, "index"); + return node; } var estree = (superClass => class extends superClass { + parse() { + const file = toESTreeLocation(super.parse()); + + if (this.options.tokens) { + file.tokens = file.tokens.map(toESTreeLocation); + } + + return file; + } + parseRegExpLiteral({ pattern, flags @@ -617,9 +511,9 @@ const expression = this.startNodeAt(directiveLiteral.start, directiveLiteral.loc.start); expression.value = directiveLiteral.extra.expressionValue; expression.raw = directiveLiteral.extra.raw; - stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.end, directiveLiteral.loc.end); + stmt.expression = this.finishNodeAt(expression, "Literal", directiveLiteral.loc.end); stmt.directive = directiveLiteral.extra.raw.slice(1, -1); - return this.finishNodeAt(stmt, "ExpressionStatement", directive.end, directive.loc.end); + return this.finishNodeAt(stmt, "ExpressionStatement", directive.loc.end); } initFunction(node, isAsync) { @@ -643,13 +537,6 @@ var _stmt$expression$extr; return stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && typeof stmt.expression.value === "string" && !((_stmt$expression$extr = stmt.expression.extra) != null && _stmt$expression$extr.parenthesized); - } - - stmtToDirective(stmt) { - const value = stmt.expression.value; - const directive = super.stmtToDirective(stmt); - this.addExtra(directive.value, "expressionValue", value); - return directive; } parseBlockBody(node, ...args) { @@ -781,6 +668,10 @@ return node; } + isValidLVal(type, ...rest) { + return type === "Property" ? "value" : super.isValidLVal(type, ...rest); + } + isAssignable(node, isBinding) { if (node != null && this.isObjectProperty(node)) { return this.isAssignable(node.value, isBinding); @@ -791,20 +682,32 @@ toAssignable(node, isLHS = false) { if (node != null && this.isObjectProperty(node)) { - this.toAssignable(node.value, isLHS); - return node; - } + const { + key, + value + } = node; - return super.toAssignable(node, isLHS); + if (this.isPrivateName(key)) { + this.classScope.usePrivateName(this.getPrivateNameSV(key), key.loc.start); + } + + this.toAssignable(value, isLHS); + } else { + super.toAssignable(node, isLHS); + } } - toAssignableObjectExpressionProp(prop, ...args) { + toAssignableObjectExpressionProp(prop) { if (prop.kind === "get" || prop.kind === "set") { - this.raise(prop.key.start, ErrorMessages.PatternHasAccessor); + this.raise(Errors.PatternHasAccessor, { + at: prop.key + }); } else if (prop.method) { - this.raise(prop.key.start, ErrorMessages.PatternHasMethod); + this.raise(Errors.PatternHasMethod, { + at: prop.key + }); } else { - super.toAssignableObjectExpressionProp(prop, ...args); + super.toAssignableObjectExpressionProp(...arguments); } } @@ -897,6 +800,15 @@ return node.method || node.kind === "get" || node.kind === "set"; } + finishNodeAt(node, type, endLoc) { + return toESTreeLocation(super.finishNodeAt(node, type, endLoc)); + } + + resetEndLocation(node, endLoc = this.state.lastTokEndLoc) { + super.resetEndLocation(node, endLoc); + toESTreeLocation(node); + } + }); class TokContext { @@ -910,8 +822,13 @@ } const types = { brace: new TokContext("{"), - template: new TokContext("`", true) + j_oTag: new TokContext("<tag"), + j_cTag: new TokContext("</tag"), + j_expr: new TokContext("<tag>...</tag>", true) }; +{ + types.template = new TokContext("`", true); +} const beforeExpr = true; const startsExpr = true; @@ -1065,6 +982,13 @@ beforeExpr, startsExpr }), + templateTail: createToken("...`", { + startsExpr + }), + templateNonTail: createToken("...${", { + beforeExpr, + startsExpr + }), at: createToken("@"), hash: createToken("#", { startsExpr @@ -1079,6 +1003,10 @@ isAssign }), slashAssign: createToken("_=", { + beforeExpr, + isAssign + }), + xorAssign: createToken("_=", { beforeExpr, isAssign }), @@ -1101,6 +1029,12 @@ prefix, startsExpr }), + doubleCaret: createToken("^^", { + startsExpr + }), + doubleAt: createToken("@@", { + startsExpr + }), pipeline: createBinop("|>", 0), nullishCoalescing: createBinop("??", 1), logicalOR: createBinop("||", 1), @@ -1109,8 +1043,12 @@ bitwiseXOR: createBinop("^", 4), bitwiseAND: createBinop("&", 5), equality: createBinop("==/!=/===/!==", 6), + lt: createBinop("</>/<=/>=", 7), + gt: createBinop("</>/<=/>=", 7), relational: createBinop("</>/<=/>=", 7), bitShift: createBinop("<</>>/>>>", 8), + bitShiftL: createBinop("<</>>/>>>", 8), + bitShiftR: createBinop("<</>>/>>>", 8), plusMin: createToken("+/-", { beforeExpr, binop: 9, @@ -1363,13 +1301,16 @@ }) }; function tokenIsIdentifier(token) { - return token >= 84 && token <= 119; + return token >= 93 && token <= 128; +} +function tokenKeywordOrIdentifierIsKeyword(token) { + return token <= 92; } function tokenIsKeywordOrIdentifier(token) { - return token >= 49 && token <= 119; + return token >= 58 && token <= 128; } function tokenIsLiteralPropertyName(token) { - return token >= 49 && token <= 123; + return token >= 58 && token <= 132; } function tokenComesBeforeExpression(token) { return tokenBeforeExprs[token]; @@ -1378,31 +1319,31 @@ return tokenStartsExprs[token]; } function tokenIsAssignment(token) { - return token >= 27 && token <= 30; + return token >= 29 && token <= 33; } function tokenIsFlowInterfaceOrTypeOrOpaque(token) { - return token >= 116 && token <= 118; + return token >= 125 && token <= 127; } function tokenIsLoop(token) { - return token >= 81 && token <= 83; + return token >= 90 && token <= 92; } function tokenIsKeyword(token) { - return token >= 49 && token <= 83; + return token >= 58 && token <= 92; } function tokenIsOperator(token) { - return token >= 34 && token <= 50; + return token >= 39 && token <= 59; } function tokenIsPostfix(token) { - return token === 31; + return token === 34; } function tokenIsPrefix(token) { return tokenPrefixes[token]; } function tokenIsTSTypeOperator(token) { - return token >= 108 && token <= 110; + return token >= 117 && token <= 119; } function tokenIsTSDeclarationStart(token) { - return token >= 111 && token <= 117; + return token >= 120 && token <= 126; } function tokenLabelName(token) { return tokenLabels[token]; @@ -1411,13 +1352,13 @@ return tokenBinops[token]; } function tokenIsRightAssociative(token) { - return token === 48; + return token === 57; +} +function tokenIsTemplate(token) { + return token >= 24 && token <= 25; } function getExportedToken(token) { return tokenTypes[token]; -} -function isTokenType(obj) { - return typeof obj === "number"; } { tokenTypes[8].updateContext = context => { @@ -1436,7 +1377,7 @@ } }; - tokenTypes[129].updateContext = context => { + tokenTypes[138].updateContext = context => { context.push(types.j_expr, types.j_oTag); }; } @@ -1513,8 +1454,8 @@ return keywords.has(word); } -function isIteratorStart(current, next) { - return current === 64 && next === 64; +function isIteratorStart(current, next, next2) { + return current === 64 && next === 64 && isIdentifierStart(next2); } const reservedWordLikeSet = new Set(["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete", "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "eval", "arguments", "enum", "await"]); function canBeReservedWord(word) { @@ -1566,230 +1507,290 @@ CLASS_ELEMENT_INSTANCE_SETTER = CLASS_ELEMENT_KIND_SETTER, CLASS_ELEMENT_OTHER = 0; -class Scope { - constructor(flags) { - this.var = new Set(); - this.lexical = new Set(); - this.functions = new Set(); - this.flags = flags; +class BaseParser { + constructor() { + this.sawUnambiguousESM = false; + this.ambiguousScriptDifferentAst = false; } -} -class ScopeHandler { - constructor(raise, inModule) { - this.scopeStack = []; - this.undefinedExports = new Map(); - this.undefinedPrivateNames = new Map(); - this.raise = raise; - this.inModule = inModule; - } + hasPlugin(pluginConfig) { + if (typeof pluginConfig === "string") { + return this.plugins.has(pluginConfig); + } else { + const [pluginName, pluginOptions] = pluginConfig; - get inFunction() { - return (this.currentVarScopeFlags() & SCOPE_FUNCTION) > 0; - } - - get allowSuper() { - return (this.currentThisScopeFlags() & SCOPE_SUPER) > 0; - } - - get allowDirectSuper() { - return (this.currentThisScopeFlags() & SCOPE_DIRECT_SUPER) > 0; - } - - get inClass() { - return (this.currentThisScopeFlags() & SCOPE_CLASS) > 0; - } - - get inClassAndNotInNonArrowFunction() { - const flags = this.currentThisScopeFlags(); - return (flags & SCOPE_CLASS) > 0 && (flags & SCOPE_FUNCTION) === 0; - } - - get inStaticBlock() { - for (let i = this.scopeStack.length - 1;; i--) { - const { - flags - } = this.scopeStack[i]; - - if (flags & SCOPE_STATIC_BLOCK) { - return true; - } - - if (flags & (SCOPE_VAR | SCOPE_CLASS)) { + if (!this.hasPlugin(pluginName)) { return false; } - } - } - get inNonArrowFunction() { - return (this.currentThisScopeFlags() & SCOPE_FUNCTION) > 0; - } + const actualOptions = this.plugins.get(pluginName); - get treatFunctionsAsVar() { - return this.treatFunctionsAsVarInScope(this.currentScope()); - } - - createScope(flags) { - return new Scope(flags); - } - - enter(flags) { - this.scopeStack.push(this.createScope(flags)); - } - - exit() { - this.scopeStack.pop(); - } - - treatFunctionsAsVarInScope(scope) { - return !!(scope.flags & SCOPE_FUNCTION || !this.inModule && scope.flags & SCOPE_PROGRAM); - } - - declareName(name, bindingType, pos) { - let scope = this.currentScope(); - - if (bindingType & BIND_SCOPE_LEXICAL || bindingType & BIND_SCOPE_FUNCTION) { - this.checkRedeclarationInScope(scope, name, bindingType, pos); - - if (bindingType & BIND_SCOPE_FUNCTION) { - scope.functions.add(name); - } else { - scope.lexical.add(name); + for (const key of Object.keys(pluginOptions)) { + if ((actualOptions == null ? void 0 : actualOptions[key]) !== pluginOptions[key]) { + return false; + } } - if (bindingType & BIND_SCOPE_LEXICAL) { - this.maybeExportDefined(scope, name); - } - } else if (bindingType & BIND_SCOPE_VAR) { - for (let i = this.scopeStack.length - 1; i >= 0; --i) { - scope = this.scopeStack[i]; - this.checkRedeclarationInScope(scope, name, bindingType, pos); - scope.var.add(name); - this.maybeExportDefined(scope, name); - if (scope.flags & SCOPE_VAR) break; - } - } - - if (this.inModule && scope.flags & SCOPE_PROGRAM) { - this.undefinedExports.delete(name); + return true; } } - maybeExportDefined(scope, name) { - if (this.inModule && scope.flags & SCOPE_PROGRAM) { - this.undefinedExports.delete(name); - } + getPluginOption(plugin, name) { + var _this$plugins$get; + + return (_this$plugins$get = this.plugins.get(plugin)) == null ? void 0 : _this$plugins$get[name]; } - checkRedeclarationInScope(scope, name, bindingType, pos) { - if (this.isRedeclaredInScope(scope, name, bindingType)) { - this.raise(pos, ErrorMessages.VarRedeclaration, name); - } +} + +function setTrailingComments(node, comments) { + if (node.trailingComments === undefined) { + node.trailingComments = comments; + } else { + node.trailingComments.unshift(...comments); + } +} + +function setLeadingComments(node, comments) { + if (node.leadingComments === undefined) { + node.leadingComments = comments; + } else { + node.leadingComments.unshift(...comments); + } +} + +function setInnerComments(node, comments) { + if (node.innerComments === undefined) { + node.innerComments = comments; + } else { + node.innerComments.unshift(...comments); + } +} + +function adjustInnerComments(node, elements, commentWS) { + let lastElement = null; + let i = elements.length; + + while (lastElement === null && i > 0) { + lastElement = elements[--i]; } - isRedeclaredInScope(scope, name, bindingType) { - if (!(bindingType & BIND_KIND_VALUE)) return false; + if (lastElement === null || lastElement.start > commentWS.start) { + setInnerComments(node, commentWS.comments); + } else { + setTrailingComments(lastElement, commentWS.comments); + } +} - if (bindingType & BIND_SCOPE_LEXICAL) { - return scope.lexical.has(name) || scope.functions.has(name) || scope.var.has(name); - } - - if (bindingType & BIND_SCOPE_FUNCTION) { - return scope.lexical.has(name) || !this.treatFunctionsAsVarInScope(scope) && scope.var.has(name); - } - - return scope.lexical.has(name) && !(scope.flags & SCOPE_SIMPLE_CATCH && scope.lexical.values().next().value === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.has(name); +class CommentsParser extends BaseParser { + addComment(comment) { + if (this.filename) comment.loc.filename = this.filename; + this.state.comments.push(comment); } - checkLocalExport(id) { + processComment(node) { const { - name - } = id; - const topLevelScope = this.scopeStack[0]; + commentStack + } = this.state; + const commentStackLength = commentStack.length; + if (commentStackLength === 0) return; + let i = commentStackLength - 1; + const lastCommentWS = commentStack[i]; - if (!topLevelScope.lexical.has(name) && !topLevelScope.var.has(name) && !topLevelScope.functions.has(name)) { - this.undefinedExports.set(name, id.start); + if (lastCommentWS.start === node.end) { + lastCommentWS.leadingNode = node; + i--; } - } - currentScope() { - return this.scopeStack[this.scopeStack.length - 1]; - } + const { + start: nodeStart + } = node; - currentVarScopeFlags() { - for (let i = this.scopeStack.length - 1;; i--) { - const { - flags - } = this.scopeStack[i]; + for (; i >= 0; i--) { + const commentWS = commentStack[i]; + const commentEnd = commentWS.end; - if (flags & SCOPE_VAR) { - return flags; + if (commentEnd > nodeStart) { + commentWS.containingNode = node; + this.finalizeComment(commentWS); + commentStack.splice(i, 1); + } else { + if (commentEnd === nodeStart) { + commentWS.trailingNode = node; + } + + break; } } } - currentThisScopeFlags() { - for (let i = this.scopeStack.length - 1;; i--) { - const { - flags - } = this.scopeStack[i]; + finalizeComment(commentWS) { + const { + comments + } = commentWS; - if (flags & (SCOPE_VAR | SCOPE_CLASS) && !(flags & SCOPE_ARROW)) { - return flags; + if (commentWS.leadingNode !== null || commentWS.trailingNode !== null) { + if (commentWS.leadingNode !== null) { + setTrailingComments(commentWS.leadingNode, comments); + } + + if (commentWS.trailingNode !== null) { + setLeadingComments(commentWS.trailingNode, comments); + } + } else { + const { + containingNode: node, + start: commentStart + } = commentWS; + + if (this.input.charCodeAt(commentStart - 1) === 44) { + switch (node.type) { + case "ObjectExpression": + case "ObjectPattern": + case "RecordExpression": + adjustInnerComments(node, node.properties, commentWS); + break; + + case "CallExpression": + case "OptionalCallExpression": + adjustInnerComments(node, node.arguments, commentWS); + break; + + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": + case "ObjectMethod": + case "ClassMethod": + case "ClassPrivateMethod": + adjustInnerComments(node, node.params, commentWS); + break; + + case "ArrayExpression": + case "ArrayPattern": + case "TupleExpression": + adjustInnerComments(node, node.elements, commentWS); + break; + + case "ExportNamedDeclaration": + case "ImportDeclaration": + adjustInnerComments(node, node.specifiers, commentWS); + break; + + default: + { + setInnerComments(node, comments); + } + } + } else { + setInnerComments(node, comments); + } + } + } + + finalizeRemainingComments() { + const { + commentStack + } = this.state; + + for (let i = commentStack.length - 1; i >= 0; i--) { + this.finalizeComment(commentStack[i]); + } + + this.state.commentStack = []; + } + + resetPreviousNodeTrailingComments(node) { + const { + commentStack + } = this.state; + const { + length + } = commentStack; + if (length === 0) return; + const commentWS = commentStack[length - 1]; + + if (commentWS.leadingNode === node) { + commentWS.leadingNode = null; + } + } + + takeSurroundingComments(node, start, end) { + const { + commentStack + } = this.state; + const commentStackLength = commentStack.length; + if (commentStackLength === 0) return; + let i = commentStackLength - 1; + + for (; i >= 0; i--) { + const commentWS = commentStack[i]; + const commentEnd = commentWS.end; + const commentStart = commentWS.start; + + if (commentStart === end) { + commentWS.leadingNode = node; + } else if (commentEnd === start) { + commentWS.trailingNode = node; + } else if (commentEnd < start) { + break; } } } } -class FlowScope extends Scope { - constructor(...args) { - super(...args); - this.declareFunctions = new Set(); - } +const lineBreak = /\r\n?|[\n\u2028\u2029]/; +const lineBreakG = new RegExp(lineBreak.source, "g"); +function isNewLine(code) { + switch (code) { + case 10: + case 13: + case 8232: + case 8233: + return true; + default: + return false; + } } +const skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g; +const skipWhiteSpaceInLine = /(?:[^\S\n\r\u2028\u2029]|\/\/.*|\/\*.*?\*\/)*/y; +const skipWhiteSpaceToLineBreak = new RegExp("(?=(" + skipWhiteSpaceInLine.source + "))\\1" + /(?=[\n\r\u2028\u2029]|\/\*(?!.*?\*\/)|$)/.source, "y"); +function isWhitespace(code) { + switch (code) { + case 0x0009: + case 0x000b: + case 0x000c: + case 32: + case 160: + case 5760: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200a: + case 0x202f: + case 0x205f: + case 0x3000: + case 0xfeff: + return true; -class FlowScopeHandler extends ScopeHandler { - createScope(flags) { - return new FlowScope(flags); + default: + return false; } - - declareName(name, bindingType, pos) { - const scope = this.currentScope(); - - if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) { - this.checkRedeclarationInScope(scope, name, bindingType, pos); - this.maybeExportDefined(scope, name); - scope.declareFunctions.add(name); - return; - } - - super.declareName(...arguments); - } - - isRedeclaredInScope(scope, name, bindingType) { - if (super.isRedeclaredInScope(...arguments)) return true; - - if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) { - return !scope.declareFunctions.has(name) && (scope.lexical.has(name) || scope.functions.has(name)); - } - - return false; - } - - checkLocalExport(id) { - if (!this.scopeStack[0].declareFunctions.has(id.name)) { - super.checkLocalExport(id); - } - } - } class State { constructor() { this.strict = void 0; this.curLine = void 0; + this.lineStart = void 0; this.startLoc = void 0; this.endLoc = void 0; this.errors = []; @@ -1799,7 +1800,6 @@ this.maybeInArrowParameters = false; this.inType = false; this.noAnonFunctionType = false; - this.inPropertyName = false; this.hasFlowComment = false; this.isAmbientContext = false; this.inAbstractClass = false; @@ -1814,30 +1814,34 @@ this.comments = []; this.commentStack = []; this.pos = 0; - this.lineStart = 0; - this.type = 126; + this.type = 135; this.value = null; this.start = 0; this.end = 0; this.lastTokEndLoc = null; this.lastTokStartLoc = null; this.lastTokStart = 0; - this.lastTokEnd = 0; this.context = [types.brace]; - this.exprAllowed = true; + this.canStartJSXElement = true; this.containsEsc = false; this.strictErrors = new Map(); this.tokensLength = 0; } - init(options) { - this.strict = options.strictMode === false ? false : options.strictMode === true ? true : options.sourceType === "module"; - this.curLine = options.startLine; - this.startLoc = this.endLoc = this.curPosition(); + init({ + strictMode, + sourceType, + startLine, + startColumn + }) { + this.strict = strictMode === false ? false : strictMode === true ? true : sourceType === "module"; + this.curLine = startLine; + this.lineStart = -startColumn; + this.startLoc = this.endLoc = new Position(startLine, startColumn, 0); } curPosition() { - return new Position(this.curLine, this.pos - this.lineStart); + return new Position(this.curLine, this.pos - this.lineStart, this.pos); } clone(skipArrays) { @@ -1860,19 +1864,23 @@ } +const _excluded = ["at"], + _excluded2 = ["at"]; + var _isDigit = function isDigit(code) { return code >= 48 && code <= 57; }; -const VALID_REGEX_FLAGS = new Set([103, 109, 115, 105, 121, 117, 100]); +const VALID_REGEX_FLAGS = new Set([103, 109, 115, 105, 121, 117, 100, 118]); const forbiddenNumericSeparatorSiblings = { - decBinOct: [46, 66, 69, 79, 95, 98, 101, 111], - hex: [46, 88, 95, 120] + decBinOct: new Set([46, 66, 69, 79, 95, 98, 101, 111]), + hex: new Set([46, 88, 95, 120]) }; -const allowedNumericSeparatorSiblings = {}; -allowedNumericSeparatorSiblings.bin = [48, 49]; -allowedNumericSeparatorSiblings.oct = [...allowedNumericSeparatorSiblings.bin, 50, 51, 52, 53, 54, 55]; -allowedNumericSeparatorSiblings.dec = [...allowedNumericSeparatorSiblings.oct, 56, 57]; -allowedNumericSeparatorSiblings.hex = [...allowedNumericSeparatorSiblings.dec, 65, 66, 67, 68, 69, 70, 97, 98, 99, 100, 101, 102]; +const isAllowedNumericSeparatorSibling = { + bin: ch => ch === 48 || ch === 49, + oct: ch => ch >= 48 && ch <= 55, + dec: ch => ch >= 48 && ch <= 57, + hex: ch => ch >= 48 && ch <= 57 || ch >= 65 && ch <= 70 || ch >= 97 && ch <= 102 +}; class Token { constructor(state) { this.type = state.type; @@ -1883,7 +1891,7 @@ } } -class Tokenizer extends ParserError { +class Tokenizer extends CommentsParser { constructor(options, input) { super(); this.isLookahead = void 0; @@ -1908,7 +1916,6 @@ this.pushToken(new Token(this.state)); } - this.state.lastTokEnd = this.state.end; this.state.lastTokStart = this.state.start; this.state.lastTokEndLoc = this.state.endLoc; this.state.lastTokStartLoc = this.state.startLoc; @@ -1935,9 +1942,13 @@ type: state.type, start: state.start, end: state.end, - lastTokEnd: state.end, context: [this.curContext()], - inType: state.inType + inType: state.inType, + startLoc: state.startLoc, + lastTokEndLoc: state.lastTokEndLoc, + curLine: state.curLine, + lineStart: state.lineStart, + curPosition: state.curPosition }; } @@ -1983,7 +1994,9 @@ this.state.strict = strict; if (strict) { - this.state.strictErrors.forEach((message, pos) => this.raise(pos, message)); + this.state.strictErrors.forEach(([toParseError, at]) => this.raise(toParseError, { + at + })); this.state.strictErrors.clear(); } } @@ -1993,21 +2006,16 @@ } nextToken() { - const curContext = this.curContext(); - if (!curContext.preserveSpace) this.skipSpace(); + this.skipSpace(); this.state.start = this.state.pos; if (!this.isLookahead) this.state.startLoc = this.state.curPosition(); if (this.state.pos >= this.length) { - this.finishToken(126); + this.finishToken(135); return; } - if (curContext === types.template) { - this.readTmplToken(); - } else { - this.getTokenFromCode(this.codePointAtPos(this.state.pos)); - } + this.getTokenFromCode(this.codePointAtPos(this.state.pos)); } skipBlockComment() { @@ -2015,7 +2023,13 @@ if (!this.isLookahead) startLoc = this.state.curPosition(); const start = this.state.pos; const end = this.input.indexOf("*/", start + 2); - if (end === -1) throw this.raise(start, ErrorMessages.UnterminatedComment); + + if (end === -1) { + throw this.raise(Errors.UnterminatedComment, { + at: this.state.curPosition() + }); + } + this.state.pos = end + 2; lineBreakG.lastIndex = start + 2; @@ -2173,14 +2187,19 @@ finishToken(type, val) { this.state.end = this.state.pos; + this.state.endLoc = this.state.curPosition(); const prevType = this.state.type; this.state.type = type; this.state.value = val; if (!this.isLookahead) { - this.state.endLoc = this.state.curPosition(); this.updateContext(prevType); } + } + + replaceToken(type) { + this.state.type = type; + this.updateContext(); } readToken_numberSign() { @@ -2192,14 +2211,18 @@ const next = this.codePointAtPos(nextPos); if (next >= 48 && next <= 57) { - throw this.raise(this.state.pos, ErrorMessages.UnexpectedDigitAfterHash); + throw this.raise(Errors.UnexpectedDigitAfterHash, { + at: this.state.curPosition() + }); } if (next === 123 || next === 91 && this.hasPlugin("recordAndTuple")) { this.expectPlugin("recordAndTuple"); if (this.getPluginOption("recordAndTuple", "syntaxType") !== "hash") { - throw this.raise(this.state.pos, next === 123 ? ErrorMessages.RecordExpressionHashIncorrectStartSyntaxType : ErrorMessages.TupleExpressionHashIncorrectStartSyntaxType); + throw this.raise(next === 123 ? Errors.RecordExpressionHashIncorrectStartSyntaxType : Errors.TupleExpressionHashIncorrectStartSyntaxType, { + at: this.state.curPosition() + }); } this.state.pos += 2; @@ -2211,12 +2234,12 @@ } } else if (isIdentifierStart(next)) { ++this.state.pos; - this.finishToken(125, this.readWord1(next)); + this.finishToken(134, this.readWord1(next)); } else if (next === 92) { ++this.state.pos; - this.finishToken(125, this.readWord1()); + this.finishToken(134, this.readWord1()); } else { - this.finishOp(25, 1); + this.finishOp(27, 1); } } @@ -2241,9 +2264,9 @@ const next = this.input.charCodeAt(this.state.pos + 1); if (next === 61) { - this.finishOp(29, 2); + this.finishOp(31, 2); } else { - this.finishOp(47, 1); + this.finishOp(56, 1); } } @@ -2259,24 +2282,24 @@ } const value = this.input.slice(start + 2, this.state.pos); - this.finishToken(26, value); + this.finishToken(28, value); return true; } readToken_mult_modulo(code) { - let type = code === 42 ? 46 : 45; + let type = code === 42 ? 55 : 54; let width = 1; let next = this.input.charCodeAt(this.state.pos + 1); if (code === 42 && next === 42) { width++; next = this.input.charCodeAt(this.state.pos + 2); - type = 48; + type = 57; } if (next === 61 && !this.state.inType) { width++; - type = code === 37 ? 30 : 28; + type = code === 37 ? 33 : 30; } this.finishOp(type, width); @@ -2287,9 +2310,9 @@ if (next === code) { if (this.input.charCodeAt(this.state.pos + 2) === 61) { - this.finishOp(28, 3); + this.finishOp(30, 3); } else { - this.finishOp(code === 124 ? 36 : 37, 2); + this.finishOp(code === 124 ? 41 : 42, 2); } return; @@ -2297,13 +2320,15 @@ if (code === 124) { if (next === 62) { - this.finishOp(34, 2); + this.finishOp(39, 2); return; } if (this.hasPlugin("recordAndTuple") && next === 125) { if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { - throw this.raise(this.state.pos, ErrorMessages.RecordExpressionBarIncorrectEndSyntaxType); + throw this.raise(Errors.RecordExpressionBarIncorrectEndSyntaxType, { + at: this.state.curPosition() + }); } this.state.pos += 2; @@ -2313,7 +2338,9 @@ if (this.hasPlugin("recordAndTuple") && next === 93) { if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { - throw this.raise(this.state.pos, ErrorMessages.TupleExpressionBarIncorrectEndSyntaxType); + throw this.raise(Errors.TupleExpressionBarIncorrectEndSyntaxType, { + at: this.state.curPosition() + }); } this.state.pos += 2; @@ -2323,20 +2350,43 @@ } if (next === 61) { - this.finishOp(28, 2); + this.finishOp(30, 2); return; } - this.finishOp(code === 124 ? 38 : 40, 1); + this.finishOp(code === 124 ? 43 : 45, 1); } readToken_caret() { const next = this.input.charCodeAt(this.state.pos + 1); - if (next === 61) { - this.finishOp(28, 2); + if (next === 61 && !this.state.inType) { + this.finishOp(32, 2); + } else if (next === 94 && this.hasPlugin(["pipelineOperator", { + proposal: "hack", + topicToken: "^^" + }])) { + this.finishOp(37, 2); + const lookaheadCh = this.input.codePointAt(this.state.pos); + + if (lookaheadCh === 94) { + throw this.unexpected(); + } } else { - this.finishOp(39, 1); + this.finishOp(44, 1); + } + } + + readToken_atSign() { + const next = this.input.charCodeAt(this.state.pos + 1); + + if (next === 64 && this.hasPlugin(["pipelineOperator", { + proposal: "hack", + topicToken: "@@" + }])) { + this.finishOp(38, 2); + } else { + this.finishOp(26, 1); } } @@ -2344,45 +2394,72 @@ const next = this.input.charCodeAt(this.state.pos + 1); if (next === code) { - this.finishOp(31, 2); + this.finishOp(34, 2); return; } if (next === 61) { - this.finishOp(28, 2); + this.finishOp(30, 2); } else { - this.finishOp(44, 1); + this.finishOp(53, 1); } } - readToken_lt_gt(code) { - const next = this.input.charCodeAt(this.state.pos + 1); - let size = 1; + readToken_lt() { + const { + pos + } = this.state; + const next = this.input.charCodeAt(pos + 1); - if (next === code) { - size = code === 62 && this.input.charCodeAt(this.state.pos + 2) === 62 ? 3 : 2; - - if (this.input.charCodeAt(this.state.pos + size) === 61) { - this.finishOp(28, size + 1); + if (next === 60) { + if (this.input.charCodeAt(pos + 2) === 61) { + this.finishOp(30, 3); return; } - this.finishOp(43, size); + this.finishOp(51, 2); return; } if (next === 61) { - size = 2; + this.finishOp(49, 2); + return; } - this.finishOp(42, size); + this.finishOp(47, 1); + } + + readToken_gt() { + const { + pos + } = this.state; + const next = this.input.charCodeAt(pos + 1); + + if (next === 62) { + const size = this.input.charCodeAt(pos + 2) === 62 ? 3 : 2; + + if (this.input.charCodeAt(pos + size) === 61) { + this.finishOp(30, size + 1); + return; + } + + this.finishOp(52, size); + return; + } + + if (next === 61) { + this.finishOp(49, 2); + return; + } + + this.finishOp(48, 1); } readToken_eq_excl(code) { const next = this.input.charCodeAt(this.state.pos + 1); if (next === 61) { - this.finishOp(41, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2); + this.finishOp(46, this.input.charCodeAt(this.state.pos + 2) === 61 ? 3 : 2); return; } @@ -2392,7 +2469,7 @@ return; } - this.finishOp(code === 61 ? 27 : 32, 1); + this.finishOp(code === 61 ? 29 : 35, 1); } readToken_question() { @@ -2401,9 +2478,9 @@ if (next === 63) { if (next2 === 61) { - this.finishOp(28, 3); + this.finishOp(30, 3); } else { - this.finishOp(35, 2); + this.finishOp(40, 2); } } else if (next === 46 && !(next2 >= 48 && next2 <= 57)) { this.state.pos += 2; @@ -2443,7 +2520,9 @@ case 91: if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) { if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { - throw this.raise(this.state.pos, ErrorMessages.TupleExpressionBarIncorrectStartSyntaxType); + throw this.raise(Errors.TupleExpressionBarIncorrectStartSyntaxType, { + at: this.state.curPosition() + }); } this.state.pos += 2; @@ -2463,7 +2542,9 @@ case 123: if (this.hasPlugin("recordAndTuple") && this.input.charCodeAt(this.state.pos + 1) === 124) { if (this.getPluginOption("recordAndTuple", "syntaxType") !== "bar") { - throw this.raise(this.state.pos, ErrorMessages.RecordExpressionBarIncorrectStartSyntaxType); + throw this.raise(Errors.RecordExpressionBarIncorrectStartSyntaxType, { + at: this.state.curPosition() + }); } this.state.pos += 2; @@ -2495,8 +2576,7 @@ return; case 96: - ++this.state.pos; - this.finishToken(22); + this.readTemplateToken(); return; case 48: @@ -2560,8 +2640,11 @@ return; case 60: + this.readToken_lt(); + return; + case 62: - this.readToken_lt_gt(code); + this.readToken_gt(); return; case 61: @@ -2570,12 +2653,11 @@ return; case 126: - this.finishOp(33, 1); + this.finishOp(36, 1); return; case 64: - ++this.state.pos; - this.finishToken(24); + this.readToken_atSign(); return; case 35: @@ -2594,7 +2676,10 @@ } - throw this.raise(this.state.pos, ErrorMessages.InvalidOrUnexpectedToken, String.fromCodePoint(code)); + throw this.raise(Errors.InvalidOrUnexpectedToken, { + at: this.state.curPosition(), + unexpected: String.fromCodePoint(code) + }); } finishOp(type, size) { @@ -2604,6 +2689,7 @@ } readRegexp() { + const startLoc = this.state.startLoc; const start = this.state.start + 1; let escaped, inClass; let { @@ -2612,13 +2698,17 @@ for (;; ++pos) { if (pos >= this.length) { - throw this.raise(start, ErrorMessages.UnterminatedRegExp); + throw this.raise(Errors.UnterminatedRegExp, { + at: createPositionWithColumnOffset(startLoc, 1) + }); } const ch = this.input.charCodeAt(pos); if (isNewLine(ch)) { - throw this.raise(start, ErrorMessages.UnterminatedRegExp); + throw this.raise(Errors.UnterminatedRegExp, { + at: createPositionWithColumnOffset(startLoc, 1) + }); } if (escaped) { @@ -2640,16 +2730,38 @@ ++pos; let mods = ""; + const nextPos = () => createPositionWithColumnOffset(startLoc, pos + 2 - start); + while (pos < this.length) { const cp = this.codePointAtPos(pos); const char = String.fromCharCode(cp); if (VALID_REGEX_FLAGS.has(cp)) { + if (cp === 118) { + this.expectPlugin("regexpUnicodeSets", nextPos()); + + if (mods.includes("u")) { + this.raise(Errors.IncompatibleRegExpUVFlags, { + at: nextPos() + }); + } + } else if (cp === 117) { + if (mods.includes("v")) { + this.raise(Errors.IncompatibleRegExpUVFlags, { + at: nextPos() + }); + } + } + if (mods.includes(char)) { - this.raise(pos + 1, ErrorMessages.DuplicateRegExpFlags); + this.raise(Errors.DuplicateRegExpFlags, { + at: nextPos() + }); } } else if (isIdentifierChar(cp) || cp === 92) { - this.raise(pos + 1, ErrorMessages.MalformedRegExpFlags); + this.raise(Errors.MalformedRegExpFlags, { + at: nextPos() + }); } else { break; } @@ -2659,7 +2771,7 @@ } this.state.pos = pos; - this.finishToken(124, { + this.finishToken(133, { pattern: content, flags: mods }); @@ -2668,7 +2780,7 @@ readInt(radix, len, forceLen, allowNumSeparator = true) { const start = this.state.pos; const forbiddenSiblings = radix === 16 ? forbiddenNumericSeparatorSiblings.hex : forbiddenNumericSeparatorSiblings.decBinOct; - const allowedSiblings = radix === 16 ? allowedNumericSeparatorSiblings.hex : radix === 10 ? allowedNumericSeparatorSiblings.dec : radix === 8 ? allowedNumericSeparatorSiblings.oct : allowedNumericSeparatorSiblings.bin; + const isAllowedSibling = radix === 16 ? isAllowedNumericSeparatorSibling.hex : radix === 10 ? isAllowedNumericSeparatorSibling.dec : radix === 8 ? isAllowedNumericSeparatorSibling.oct : isAllowedNumericSeparatorSibling.bin; let invalid = false; let total = 0; @@ -2676,18 +2788,18 @@ const code = this.input.charCodeAt(this.state.pos); let val; - if (code === 95) { + if (code === 95 && allowNumSeparator !== "bail") { const prev = this.input.charCodeAt(this.state.pos - 1); const next = this.input.charCodeAt(this.state.pos + 1); - if (allowedSiblings.indexOf(next) === -1) { - this.raise(this.state.pos, ErrorMessages.UnexpectedNumericSeparator); - } else if (forbiddenSiblings.indexOf(prev) > -1 || forbiddenSiblings.indexOf(next) > -1 || Number.isNaN(next)) { - this.raise(this.state.pos, ErrorMessages.UnexpectedNumericSeparator); - } - if (!allowNumSeparator) { - this.raise(this.state.pos, ErrorMessages.NumericSeparatorInEscapeSequence); + this.raise(Errors.NumericSeparatorInEscapeSequence, { + at: this.state.curPosition() + }); + } else if (Number.isNaN(next) || !isAllowedSibling(next) || forbiddenSiblings.has(prev) || forbiddenSiblings.has(next)) { + this.raise(Errors.UnexpectedNumericSeparator, { + at: this.state.curPosition() + }); } ++this.state.pos; @@ -2707,7 +2819,10 @@ if (val >= radix) { if (this.options.errorRecovery && val <= 9) { val = 0; - this.raise(this.state.start + i + 2, ErrorMessages.InvalidDigit, radix); + this.raise(Errors.InvalidDigit, { + at: this.state.curPosition(), + radix + }); } else if (forceLen) { val = 0; invalid = true; @@ -2728,13 +2843,16 @@ } readRadixNumber(radix) { - const start = this.state.pos; + const startLoc = this.state.curPosition(); let isBigInt = false; this.state.pos += 2; const val = this.readInt(radix); if (val == null) { - this.raise(this.state.start + 2, ErrorMessages.InvalidDigit, radix); + this.raise(Errors.InvalidDigit, { + at: createPositionWithColumnOffset(startLoc, 2), + radix + }); } const next = this.input.charCodeAt(this.state.pos); @@ -2743,24 +2861,29 @@ ++this.state.pos; isBigInt = true; } else if (next === 109) { - throw this.raise(start, ErrorMessages.InvalidDecimal); + throw this.raise(Errors.InvalidDecimal, { + at: startLoc + }); } if (isIdentifierStart(this.codePointAtPos(this.state.pos))) { - throw this.raise(this.state.pos, ErrorMessages.NumberIdentifier); + throw this.raise(Errors.NumberIdentifier, { + at: this.state.curPosition() + }); } if (isBigInt) { - const str = this.input.slice(start, this.state.pos).replace(/[_n]/g, ""); - this.finishToken(122, str); + const str = this.input.slice(startLoc.index, this.state.pos).replace(/[_n]/g, ""); + this.finishToken(131, str); return; } - this.finishToken(121, val); + this.finishToken(130, val); } readNumber(startsWithDot) { const start = this.state.pos; + const startLoc = this.state.curPosition(); let isFloat = false; let isBigInt = false; let isDecimal = false; @@ -2768,20 +2891,26 @@ let isOctal = false; if (!startsWithDot && this.readInt(10) === null) { - this.raise(start, ErrorMessages.InvalidNumber); + this.raise(Errors.InvalidNumber, { + at: this.state.curPosition() + }); } const hasLeadingZero = this.state.pos - start >= 2 && this.input.charCodeAt(start) === 48; if (hasLeadingZero) { const integer = this.input.slice(start, this.state.pos); - this.recordStrictModeErrors(start, ErrorMessages.StrictOctalLiteral); + this.recordStrictModeErrors(Errors.StrictOctalLiteral, { + at: startLoc + }); if (!this.state.strict) { const underscorePos = integer.indexOf("_"); if (underscorePos > 0) { - this.raise(underscorePos + start, ErrorMessages.ZeroDigitNumericSeparator); + this.raise(Errors.ZeroDigitNumericSeparator, { + at: createPositionWithColumnOffset(startLoc, underscorePos) + }); } } @@ -2805,7 +2934,9 @@ } if (this.readInt(10) === null) { - this.raise(start, ErrorMessages.InvalidOrMissingExponent); + this.raise(Errors.InvalidOrMissingExponent, { + at: startLoc + }); } isFloat = true; @@ -2815,7 +2946,9 @@ if (next === 110) { if (isFloat || hasLeadingZero) { - this.raise(start, ErrorMessages.InvalidBigIntLiteral); + this.raise(Errors.InvalidBigIntLiteral, { + at: startLoc + }); } ++this.state.pos; @@ -2823,10 +2956,12 @@ } if (next === 109) { - this.expectPlugin("decimal", this.state.pos); + this.expectPlugin("decimal", this.state.curPosition()); if (hasExponent || hasLeadingZero) { - this.raise(start, ErrorMessages.InvalidDecimal); + this.raise(Errors.InvalidDecimal, { + at: startLoc + }); } ++this.state.pos; @@ -2834,23 +2969,25 @@ } if (isIdentifierStart(this.codePointAtPos(this.state.pos))) { - throw this.raise(this.state.pos, ErrorMessages.NumberIdentifier); + throw this.raise(Errors.NumberIdentifier, { + at: this.state.curPosition() + }); } const str = this.input.slice(start, this.state.pos).replace(/[_mn]/g, ""); if (isBigInt) { - this.finishToken(122, str); + this.finishToken(131, str); return; } if (isDecimal) { - this.finishToken(123, str); + this.finishToken(132, str); return; } const val = isOctal ? parseInt(str, 8) : parseFloat(str); - this.finishToken(121, val); + this.finishToken(130, val); } readCodePoint(throwOnInvalid) { @@ -2858,13 +2995,15 @@ let code; if (ch === 123) { - const codePos = ++this.state.pos; + ++this.state.pos; code = this.readHexChar(this.input.indexOf("}", this.state.pos) - this.state.pos, true, throwOnInvalid); ++this.state.pos; if (code !== null && code > 0x10ffff) { if (throwOnInvalid) { - this.raise(codePos, ErrorMessages.InvalidCodePoint); + this.raise(Errors.InvalidCodePoint, { + at: this.state.curPosition() + }); } else { return null; } @@ -2882,7 +3021,9 @@ for (;;) { if (this.state.pos >= this.length) { - throw this.raise(this.state.start, ErrorMessages.UnterminatedString); + throw this.raise(Errors.UnterminatedString, { + at: this.state.startLoc + }); } const ch = this.input.charCodeAt(this.state.pos); @@ -2897,43 +3038,53 @@ ++this.state.curLine; this.state.lineStart = this.state.pos; } else if (isNewLine(ch)) { - throw this.raise(this.state.start, ErrorMessages.UnterminatedString); + throw this.raise(Errors.UnterminatedString, { + at: this.state.startLoc + }); } else { ++this.state.pos; } } out += this.input.slice(chunkStart, this.state.pos++); - this.finishToken(120, out); + this.finishToken(129, out); } - readTmplToken() { + readTemplateContinuation() { + if (!this.match(8)) { + this.unexpected(null, 8); + } + + this.state.pos--; + this.readTemplateToken(); + } + + readTemplateToken() { let out = "", chunkStart = this.state.pos, containsInvalid = false; + ++this.state.pos; for (;;) { if (this.state.pos >= this.length) { - throw this.raise(this.state.start, ErrorMessages.UnterminatedTemplate); + throw this.raise(Errors.UnterminatedTemplate, { + at: createPositionWithColumnOffset(this.state.startLoc, 1) + }); } const ch = this.input.charCodeAt(this.state.pos); - if (ch === 96 || ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { - if (this.state.pos === this.state.start && this.match(20)) { - if (ch === 36) { - this.state.pos += 2; - this.finishToken(23); - return; - } else { - ++this.state.pos; - this.finishToken(22); - return; - } - } - + if (ch === 96) { + ++this.state.pos; out += this.input.slice(chunkStart, this.state.pos); - this.finishToken(20, containsInvalid ? null : out); + this.finishToken(24, containsInvalid ? null : out); + return; + } + + if (ch === 36 && this.input.charCodeAt(this.state.pos + 1) === 123) { + this.state.pos += 2; + out += this.input.slice(chunkStart, this.state.pos); + this.finishToken(25, containsInvalid ? null : out); return; } @@ -2976,11 +3127,17 @@ } } - recordStrictModeErrors(pos, message) { - if (this.state.strict && !this.state.strictErrors.has(pos)) { - this.raise(pos, message); + recordStrictModeErrors(toParseError, { + at + }) { + const index = at.index; + + if (this.state.strict && !this.state.strictErrors.has(index)) { + this.raise(toParseError, { + at + }); } else { - this.state.strictErrors.set(pos, message); + this.state.strictErrors.set(index, [toParseError, at]); } } @@ -3038,13 +3195,15 @@ if (inTemplate) { return null; } else { - this.recordStrictModeErrors(this.state.pos - 1, ErrorMessages.StrictNumericEscape); + this.recordStrictModeErrors(Errors.StrictNumericEscape, { + at: createPositionWithColumnOffset(this.state.curPosition(), -1) + }); } default: if (ch >= 48 && ch <= 55) { - const codePos = this.state.pos - 1; - const match = this.input.substr(this.state.pos - 1, 3).match(/^[0-7]+/); + const codePos = createPositionWithColumnOffset(this.state.curPosition(), -1); + const match = this.input.slice(this.state.pos - 1, this.state.pos + 2).match(/^[0-7]+/); let octalStr = match[0]; let octal = parseInt(octalStr, 8); @@ -3060,7 +3219,9 @@ if (inTemplate) { return null; } else { - this.recordStrictModeErrors(codePos, ErrorMessages.StrictNumericEscape); + this.recordStrictModeErrors(Errors.StrictNumericEscape, { + at: codePos + }); } } @@ -3072,14 +3233,16 @@ } readHexChar(len, forceLen, throwOnInvalid) { - const codePos = this.state.pos; + const codeLoc = this.state.curPosition(); const n = this.readInt(16, len, forceLen, false); if (n === null) { if (throwOnInvalid) { - this.raise(codePos, ErrorMessages.InvalidEscapeSequence); + this.raise(Errors.InvalidEscapeSequence, { + at: codeLoc + }); } else { - this.state.pos = codePos - 1; + this.state.pos = codeLoc.index - 1; } } @@ -3104,11 +3267,13 @@ } else if (ch === 92) { this.state.containsEsc = true; word += this.input.slice(chunkStart, this.state.pos); - const escStart = this.state.pos; + const escStart = this.state.curPosition(); const identifierCheck = this.state.pos === start ? isIdentifierStart : isIdentifierChar; if (this.input.charCodeAt(++this.state.pos) !== 117) { - this.raise(this.state.pos, ErrorMessages.MissingUnicodeEscape); + this.raise(Errors.MissingUnicodeEscape, { + at: this.state.curPosition() + }); chunkStart = this.state.pos - 1; continue; } @@ -3118,7 +3283,9 @@ if (esc !== null) { if (!identifierCheck(esc)) { - this.raise(escStart, ErrorMessages.EscapedCharNotAnIdentifier); + this.raise(Errors.EscapedCharNotAnIdentifier, { + at: escStart + }); } word += String.fromCodePoint(esc); @@ -3140,7 +3307,7 @@ if (type !== undefined) { this.finishToken(type, tokenLabelName(type)); } else { - this.finishToken(119, word); + this.finishToken(128, word); } } @@ -3150,35 +3317,305 @@ } = this.state; if (tokenIsKeyword(type) && this.state.containsEsc) { - this.raise(this.state.start, ErrorMessages.InvalidEscapedReservedWord, tokenLabelName(type)); + this.raise(Errors.InvalidEscapedReservedWord, { + at: this.state.startLoc, + reservedWord: tokenLabelName(type) + }); } } - updateContext(prevType) { + raise(toParseError, raiseProperties) { const { - context, - type - } = this.state; + at + } = raiseProperties, + details = _objectWithoutPropertiesLoose(raiseProperties, _excluded); - switch (type) { - case 8: - context.pop(); - break; + const loc = at instanceof Position ? at : at.loc.start; + const error = toParseError({ + loc, + details + }); + if (!this.options.errorRecovery) throw error; + if (!this.isLookahead) this.state.errors.push(error); + return error; + } - case 5: - case 7: - case 23: - context.push(types.brace); - break; + raiseOverwrite(toParseError, raiseProperties) { + const { + at + } = raiseProperties, + details = _objectWithoutPropertiesLoose(raiseProperties, _excluded2); - case 22: - if (context[context.length - 1] === types.template) { - context.pop(); - } else { - context.push(types.template); - } + const loc = at instanceof Position ? at : at.loc.start; + const pos = loc.index; + const errors = this.state.errors; - break; + for (let i = errors.length - 1; i >= 0; i--) { + const error = errors[i]; + + if (error.loc.index === pos) { + return errors[i] = toParseError({ + loc, + details + }); + } + + if (error.loc.index < pos) break; + } + + return this.raise(toParseError, raiseProperties); + } + + updateContext(prevType) {} + + unexpected(loc, type) { + throw this.raise(Errors.UnexpectedToken, { + expected: type ? tokenLabelName(type) : null, + at: loc != null ? loc : this.state.startLoc + }); + } + + expectPlugin(pluginName, loc) { + if (this.hasPlugin(pluginName)) { + return true; + } + + throw this.raise(Errors.MissingPlugin, { + at: loc != null ? loc : this.state.startLoc, + missingPlugin: [pluginName] + }); + } + + expectOnePlugin(pluginNames) { + if (!pluginNames.some(name => this.hasPlugin(name))) { + throw this.raise(Errors.MissingOneOfPlugins, { + at: this.state.startLoc, + missingPlugin: pluginNames + }); + } + } + +} + +class Scope { + constructor(flags) { + this.var = new Set(); + this.lexical = new Set(); + this.functions = new Set(); + this.flags = flags; + } + +} +class ScopeHandler { + constructor(parser, inModule) { + this.parser = void 0; + this.scopeStack = []; + this.inModule = void 0; + this.undefinedExports = new Map(); + this.parser = parser; + this.inModule = inModule; + } + + get inFunction() { + return (this.currentVarScopeFlags() & SCOPE_FUNCTION) > 0; + } + + get allowSuper() { + return (this.currentThisScopeFlags() & SCOPE_SUPER) > 0; + } + + get allowDirectSuper() { + return (this.currentThisScopeFlags() & SCOPE_DIRECT_SUPER) > 0; + } + + get inClass() { + return (this.currentThisScopeFlags() & SCOPE_CLASS) > 0; + } + + get inClassAndNotInNonArrowFunction() { + const flags = this.currentThisScopeFlags(); + return (flags & SCOPE_CLASS) > 0 && (flags & SCOPE_FUNCTION) === 0; + } + + get inStaticBlock() { + for (let i = this.scopeStack.length - 1;; i--) { + const { + flags + } = this.scopeStack[i]; + + if (flags & SCOPE_STATIC_BLOCK) { + return true; + } + + if (flags & (SCOPE_VAR | SCOPE_CLASS)) { + return false; + } + } + } + + get inNonArrowFunction() { + return (this.currentThisScopeFlags() & SCOPE_FUNCTION) > 0; + } + + get treatFunctionsAsVar() { + return this.treatFunctionsAsVarInScope(this.currentScope()); + } + + createScope(flags) { + return new Scope(flags); + } + + enter(flags) { + this.scopeStack.push(this.createScope(flags)); + } + + exit() { + this.scopeStack.pop(); + } + + treatFunctionsAsVarInScope(scope) { + return !!(scope.flags & (SCOPE_FUNCTION | SCOPE_STATIC_BLOCK) || !this.parser.inModule && scope.flags & SCOPE_PROGRAM); + } + + declareName(name, bindingType, loc) { + let scope = this.currentScope(); + + if (bindingType & BIND_SCOPE_LEXICAL || bindingType & BIND_SCOPE_FUNCTION) { + this.checkRedeclarationInScope(scope, name, bindingType, loc); + + if (bindingType & BIND_SCOPE_FUNCTION) { + scope.functions.add(name); + } else { + scope.lexical.add(name); + } + + if (bindingType & BIND_SCOPE_LEXICAL) { + this.maybeExportDefined(scope, name); + } + } else if (bindingType & BIND_SCOPE_VAR) { + for (let i = this.scopeStack.length - 1; i >= 0; --i) { + scope = this.scopeStack[i]; + this.checkRedeclarationInScope(scope, name, bindingType, loc); + scope.var.add(name); + this.maybeExportDefined(scope, name); + if (scope.flags & SCOPE_VAR) break; + } + } + + if (this.parser.inModule && scope.flags & SCOPE_PROGRAM) { + this.undefinedExports.delete(name); + } + } + + maybeExportDefined(scope, name) { + if (this.parser.inModule && scope.flags & SCOPE_PROGRAM) { + this.undefinedExports.delete(name); + } + } + + checkRedeclarationInScope(scope, name, bindingType, loc) { + if (this.isRedeclaredInScope(scope, name, bindingType)) { + this.parser.raise(Errors.VarRedeclaration, { + at: loc, + identifierName: name + }); + } + } + + isRedeclaredInScope(scope, name, bindingType) { + if (!(bindingType & BIND_KIND_VALUE)) return false; + + if (bindingType & BIND_SCOPE_LEXICAL) { + return scope.lexical.has(name) || scope.functions.has(name) || scope.var.has(name); + } + + if (bindingType & BIND_SCOPE_FUNCTION) { + return scope.lexical.has(name) || !this.treatFunctionsAsVarInScope(scope) && scope.var.has(name); + } + + return scope.lexical.has(name) && !(scope.flags & SCOPE_SIMPLE_CATCH && scope.lexical.values().next().value === name) || !this.treatFunctionsAsVarInScope(scope) && scope.functions.has(name); + } + + checkLocalExport(id) { + const { + name + } = id; + const topLevelScope = this.scopeStack[0]; + + if (!topLevelScope.lexical.has(name) && !topLevelScope.var.has(name) && !topLevelScope.functions.has(name)) { + this.undefinedExports.set(name, id.loc.start); + } + } + + currentScope() { + return this.scopeStack[this.scopeStack.length - 1]; + } + + currentVarScopeFlags() { + for (let i = this.scopeStack.length - 1;; i--) { + const { + flags + } = this.scopeStack[i]; + + if (flags & SCOPE_VAR) { + return flags; + } + } + } + + currentThisScopeFlags() { + for (let i = this.scopeStack.length - 1;; i--) { + const { + flags + } = this.scopeStack[i]; + + if (flags & (SCOPE_VAR | SCOPE_CLASS) && !(flags & SCOPE_ARROW)) { + return flags; + } + } + } + +} + +class FlowScope extends Scope { + constructor(...args) { + super(...args); + this.declareFunctions = new Set(); + } + +} + +class FlowScopeHandler extends ScopeHandler { + createScope(flags) { + return new FlowScope(flags); + } + + declareName(name, bindingType, loc) { + const scope = this.currentScope(); + + if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) { + this.checkRedeclarationInScope(scope, name, bindingType, loc); + this.maybeExportDefined(scope, name); + scope.declareFunctions.add(name); + return; + } + + super.declareName(...arguments); + } + + isRedeclaredInScope(scope, name, bindingType) { + if (super.isRedeclaredInScope(...arguments)) return true; + + if (bindingType & BIND_FLAGS_FLOW_DECLARE_FN) { + return !scope.declareFunctions.has(name) && (scope.lexical.has(name) || scope.functions.has(name)); + } + + return false; + } + + checkLocalExport(id) { + if (!this.scopeStack[0].declareFunctions.has(id.name)) { + super.checkLocalExport(id); } } @@ -3193,10 +3630,11 @@ } class ClassScopeHandler { - constructor(raise) { + constructor(parser) { + this.parser = void 0; this.stack = []; this.undefinedPrivateNames = new Map(); - this.raise = raise; + this.parser = parser; } current() { @@ -3211,23 +3649,30 @@ const oldClassScope = this.stack.pop(); const current = this.current(); - for (const [name, pos] of Array.from(oldClassScope.undefinedPrivateNames)) { + for (const [name, loc] of Array.from(oldClassScope.undefinedPrivateNames)) { if (current) { if (!current.undefinedPrivateNames.has(name)) { - current.undefinedPrivateNames.set(name, pos); + current.undefinedPrivateNames.set(name, loc); } } else { - this.raise(pos, ErrorMessages.InvalidPrivateFieldResolution, name); + this.parser.raise(Errors.InvalidPrivateFieldResolution, { + at: loc, + identifierName: name + }); } } } - declarePrivateName(name, elementType, pos) { - const classScope = this.current(); - let redefined = classScope.privateNames.has(name); + declarePrivateName(name, elementType, loc) { + const { + privateNames, + loneAccessors, + undefinedPrivateNames + } = this.current(); + let redefined = privateNames.has(name); if (elementType & CLASS_ELEMENT_KIND_ACCESSOR) { - const accessor = redefined && classScope.loneAccessors.get(name); + const accessor = redefined && loneAccessors.get(name); if (accessor) { const oldStatic = accessor & CLASS_ELEMENT_FLAG_STATIC; @@ -3235,21 +3680,24 @@ const oldKind = accessor & CLASS_ELEMENT_KIND_ACCESSOR; const newKind = elementType & CLASS_ELEMENT_KIND_ACCESSOR; redefined = oldKind === newKind || oldStatic !== newStatic; - if (!redefined) classScope.loneAccessors.delete(name); + if (!redefined) loneAccessors.delete(name); } else if (!redefined) { - classScope.loneAccessors.set(name, elementType); + loneAccessors.set(name, elementType); } } if (redefined) { - this.raise(pos, ErrorMessages.PrivateNameRedeclaration, name); + this.parser.raise(Errors.PrivateNameRedeclaration, { + at: loc, + identifierName: name + }); } - classScope.privateNames.add(name); - classScope.undefinedPrivateNames.delete(name); + privateNames.add(name); + undefinedPrivateNames.delete(name); } - usePrivateName(name, pos) { + usePrivateName(name, loc) { let classScope; for (classScope of this.stack) { @@ -3257,9 +3705,12 @@ } if (classScope) { - classScope.undefinedPrivateNames.set(name, pos); + classScope.undefinedPrivateNames.set(name, loc); } else { - this.raise(pos, ErrorMessages.InvalidPrivateFieldResolution, name); + this.parser.raise(Errors.InvalidPrivateFieldResolution, { + at: loc, + identifierName: name + }); } } @@ -3289,27 +3740,31 @@ class ArrowHeadParsingScope extends ExpressionScope { constructor(type) { super(type); - this.errors = new Map(); + this.declarationErrors = new Map(); } - recordDeclarationError(pos, template) { - this.errors.set(pos, template); + recordDeclarationError(ParsingErrorClass, { + at + }) { + const index = at.index; + this.declarationErrors.set(index, [ParsingErrorClass, at]); } - clearDeclarationError(pos) { - this.errors.delete(pos); + clearDeclarationError(index) { + this.declarationErrors.delete(index); } iterateErrors(iterator) { - this.errors.forEach(iterator); + this.declarationErrors.forEach(iterator); } } class ExpressionScopeHandler { - constructor(raise) { + constructor(parser) { + this.parser = void 0; this.stack = [new ExpressionScope()]; - this.raise = raise; + this.parser = parser; } enter(scope) { @@ -3320,7 +3775,12 @@ this.stack.pop(); } - recordParameterInitializerError(pos, template) { + recordParameterInitializerError(toParseError, { + at: node + }) { + const origin = { + at: node.loc.start + }; const { stack } = this; @@ -3329,7 +3789,7 @@ while (!scope.isCertainlyParameterDeclaration()) { if (scope.canBeArrowParameterDeclaration()) { - scope.recordDeclarationError(pos, template); + scope.recordDeclarationError(toParseError, origin); } else { return; } @@ -3337,25 +3797,32 @@ scope = stack[--i]; } - this.raise(pos, template); + this.parser.raise(toParseError, origin); } - recordParenthesizedIdentifierError(pos, template) { + recordArrowParemeterBindingError(error, { + at: node + }) { const { stack } = this; const scope = stack[stack.length - 1]; + const origin = { + at: node.loc.start + }; if (scope.isCertainlyParameterDeclaration()) { - this.raise(pos, template); + this.parser.raise(error, origin); } else if (scope.canBeArrowParameterDeclaration()) { - scope.recordDeclarationError(pos, template); + scope.recordDeclarationError(error, origin); } else { return; } } - recordAsyncArrowParametersError(pos, template) { + recordAsyncArrowParametersError({ + at + }) { const { stack } = this; @@ -3364,7 +3831,9 @@ while (scope.canBeArrowParameterDeclaration()) { if (scope.type === kMaybeAsyncArrowParameterDeclaration) { - scope.recordDeclarationError(pos, template); + scope.recordDeclarationError(Errors.AwaitBindingIdentifier, { + at + }); } scope = stack[--i]; @@ -3377,13 +3846,15 @@ } = this; const currentScope = stack[stack.length - 1]; if (!currentScope.canBeArrowParameterDeclaration()) return; - currentScope.iterateErrors((template, pos) => { - this.raise(pos, template); + currentScope.iterateErrors(([toParseError, loc]) => { + this.parser.raise(toParseError, { + at: loc + }); let i = stack.length - 2; let scope = stack[i]; while (scope.canBeArrowParameterDeclaration()) { - scope.clearDeclarationError(pos); + scope.clearDeclarationError(loc.index); scope = stack[--i]; } }); @@ -3447,21 +3918,17 @@ } class UtilParser extends Tokenizer { - addExtra(node, key, val) { + addExtra(node, key, value, enumerable = true) { if (!node) return; const extra = node.extra = node.extra || {}; - extra[key] = val; - } - isRelational(op) { - return this.match(42) && this.state.value === op; - } - - expectRelational(op) { - if (this.isRelational(op)) { - this.next(); + if (enumerable) { + extra[key] = value; } else { - this.unexpected(null, 42); + Object.defineProperty(extra, key, { + enumerable, + value + }); } } @@ -3494,16 +3961,24 @@ return false; } - expectContextual(token, template) { - if (!this.eatContextual(token)) this.unexpected(null, template); + expectContextual(token, toParseError) { + if (!this.eatContextual(token)) { + if (toParseError != null) { + throw this.raise(toParseError, { + at: this.state.startLoc + }); + } + + throw this.unexpected(null, token); + } } canInsertSemicolon() { - return this.match(126) || this.match(8) || this.hasPrecedingLineBreak(); + return this.match(135) || this.match(8) || this.hasPrecedingLineBreak(); } hasPrecedingLineBreak() { - return lineBreak.test(this.input.slice(this.state.lastTokEnd, this.state.start)); + return lineBreak.test(this.input.slice(this.state.lastTokEndLoc.index, this.state.start)); } hasFollowingLineBreak() { @@ -3517,55 +3992,13 @@ semicolon(allowAsi = true) { if (allowAsi ? this.isLineTerminator() : this.eat(13)) return; - this.raise(this.state.lastTokEnd, ErrorMessages.MissingSemicolon); + this.raise(Errors.MissingSemicolon, { + at: this.state.lastTokEndLoc + }); } - expect(type, pos) { - this.eat(type) || this.unexpected(pos, type); - } - - assertNoSpace(message = "Unexpected space.") { - if (this.state.start > this.state.lastTokEnd) { - this.raise(this.state.lastTokEnd, { - code: ErrorCodes.SyntaxError, - reasonCode: "UnexpectedSpace", - template: message - }); - } - } - - unexpected(pos, messageOrType = { - code: ErrorCodes.SyntaxError, - reasonCode: "UnexpectedToken", - template: "Unexpected token" - }) { - if (isTokenType(messageOrType)) { - messageOrType = { - code: ErrorCodes.SyntaxError, - reasonCode: "UnexpectedToken", - template: `Unexpected token, expected "${tokenLabelName(messageOrType)}"` - }; - } - - throw this.raise(pos != null ? pos : this.state.start, messageOrType); - } - - expectPlugin(name, pos) { - if (!this.hasPlugin(name)) { - throw this.raiseWithData(pos != null ? pos : this.state.start, { - missingPlugin: [name] - }, `This experimental syntax requires enabling the parser plugin: '${name}'`); - } - - return true; - } - - expectOnePlugin(names, pos) { - if (!names.some(n => this.hasPlugin(n))) { - throw this.raiseWithData(pos != null ? pos : this.state.start, { - missingPlugin: names - }, `This experimental syntax requires enabling one of the following parser plugin(s): '${names.join(", ")}'`); - } + expect(type, loc) { + this.eat(type) || this.unexpected(loc, type); } tryParse(fn, oldState = this.state.clone()) { @@ -3630,25 +4063,37 @@ checkExpressionErrors(refExpressionErrors, andThrow) { if (!refExpressionErrors) return false; const { - shorthandAssign, - doubleProto, - optionalParameters + shorthandAssignLoc, + doubleProtoLoc, + privateKeyLoc, + optionalParametersLoc } = refExpressionErrors; + const hasErrors = !!shorthandAssignLoc || !!doubleProtoLoc || !!optionalParametersLoc || !!privateKeyLoc; if (!andThrow) { - return shorthandAssign >= 0 || doubleProto >= 0 || optionalParameters >= 0; + return hasErrors; } - if (shorthandAssign >= 0) { - this.unexpected(shorthandAssign); + if (shorthandAssignLoc != null) { + this.raise(Errors.InvalidCoverInitializedName, { + at: shorthandAssignLoc + }); } - if (doubleProto >= 0) { - this.raise(doubleProto, ErrorMessages.DuplicateProto); + if (doubleProtoLoc != null) { + this.raise(Errors.DuplicateProto, { + at: doubleProtoLoc + }); } - if (optionalParameters >= 0) { - this.unexpected(optionalParameters); + if (privateKeyLoc != null) { + this.raise(Errors.UnexpectedPrivateField, { + at: privateKeyLoc + }); + } + + if (optionalParametersLoc != null) { + this.unexpected(optionalParametersLoc); } } @@ -3689,13 +4134,13 @@ this.inModule = inModule; const oldScope = this.scope; const ScopeHandler = this.getScopeHandler(); - this.scope = new ScopeHandler(this.raise.bind(this), this.inModule); + this.scope = new ScopeHandler(this, inModule); const oldProdParam = this.prodParam; this.prodParam = new ProductionParameterHandler(); const oldClassScope = this.classScope; - this.classScope = new ClassScopeHandler(this.raise.bind(this)); + this.classScope = new ClassScopeHandler(this); const oldExpressionScope = this.expressionScope; - this.expressionScope = new ExpressionScopeHandler(this.raise.bind(this)); + this.expressionScope = new ExpressionScopeHandler(this); return () => { this.state.labels = oldLabels; this.exportedIdentifiers = oldExportedIdentifiers; @@ -3718,12 +4163,23 @@ this.prodParam.enter(paramFlags); } + checkDestructuringPrivate(refExpressionErrors) { + const { + privateKeyLoc + } = refExpressionErrors; + + if (privateKeyLoc !== null) { + this.expectPlugin("destructuringPrivate", privateKeyLoc); + } + } + } class ExpressionErrors { constructor() { - this.shorthandAssign = -1; - this.doubleProto = -1; - this.optionalParameters = -1; + this.shorthandAssignLoc = null; + this.doubleProtoLoc = null; + this.privateKeyLoc = null; + this.optionalParametersLoc = null; } } @@ -3802,12 +4258,18 @@ } const cloned = Object.create(NodePrototype); - cloned.type = "StringLiteral"; + cloned.type = type; cloned.start = start; cloned.end = end; cloned.loc = loc; cloned.range = range; - cloned.extra = extra; + + if (node.raw !== undefined) { + cloned.raw = node.raw; + } else { + cloned.extra = extra; + } + cloned.value = node.value; return cloned; } @@ -3825,15 +4287,15 @@ } finishNode(node, type) { - return this.finishNodeAt(node, type, this.state.lastTokEnd, this.state.lastTokEndLoc); + return this.finishNodeAt(node, type, this.state.lastTokEndLoc); } - finishNodeAt(node, type, pos, loc) { + finishNodeAt(node, type, endLoc) { node.type = type; - node.end = pos; - node.loc.end = loc; - if (this.options.ranges) node.range[1] = pos; + node.end = endLoc.index; + node.loc.end = endLoc; + if (this.options.ranges) node.range[1] = endLoc.index; if (this.options.attachComment) this.processComment(node); return node; } @@ -3844,10 +4306,10 @@ if (this.options.ranges) node.range[0] = start; } - resetEndLocation(node, end = this.state.lastTokEnd, endLoc = this.state.lastTokEndLoc) { - node.end = end; + resetEndLocation(node, endLoc = this.state.lastTokEndLoc) { + node.end = endLoc.index; node.loc.end = endLoc; - if (this.options.ranges) node.range[1] = end; + if (this.options.ranges) node.range[1] = endLoc.index; } resetStartLocationFromNode(node, locationNode) { @@ -3857,55 +4319,96 @@ } const reservedTypes = new Set(["_", "any", "bool", "boolean", "empty", "extends", "false", "interface", "mixed", "null", "number", "static", "string", "true", "typeof", "void"]); -const FlowErrors = makeErrorTemplates({ - AmbiguousConditionalArrow: "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.", - AmbiguousDeclareModuleKind: "Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module.", - AssignReservedType: "Cannot overwrite reserved type %0.", - DeclareClassElement: "The `declare` modifier can only appear on class fields.", - DeclareClassFieldInitializer: "Initializers are not allowed in fields with the `declare` modifier.", - DuplicateDeclareModuleExports: "Duplicate `declare module.exports` statement.", - EnumBooleanMemberNotInitialized: "Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.", - EnumDuplicateMemberName: "Enum member names need to be unique, but the name `%0` has already been used before in enum `%1`.", - EnumInconsistentMemberValues: "Enum `%0` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.", - EnumInvalidExplicitType: "Enum type `%1` is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", - EnumInvalidExplicitTypeUnknownSupplied: "Supplied enum type is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", - EnumInvalidMemberInitializerPrimaryType: "Enum `%0` has type `%2`, so the initializer of `%1` needs to be a %2 literal.", - EnumInvalidMemberInitializerSymbolType: "Symbol enum members cannot be initialized. Use `%1,` in enum `%0`.", - EnumInvalidMemberInitializerUnknownType: "The enum member initializer for `%1` needs to be a literal (either a boolean, number, or string) in enum `%0`.", - EnumInvalidMemberName: "Enum member names cannot start with lowercase 'a' through 'z'. Instead of using `%0`, consider using `%1`, in enum `%2`.", - EnumNumberMemberNotInitialized: "Number enum members need to be initialized, e.g. `%1 = 1` in enum `%0`.", - EnumStringMemberInconsistentlyInitailized: "String enum members need to consistently either all use initializers, or use no initializers, in enum `%0`.", - GetterMayNotHaveThisParam: "A getter cannot have a `this` parameter.", - ImportTypeShorthandOnlyInPureImport: "The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements.", - InexactInsideExact: "Explicit inexact syntax cannot appear inside an explicit exact object type.", - InexactInsideNonObject: "Explicit inexact syntax cannot appear in class or interface definitions.", - InexactVariance: "Explicit inexact syntax cannot have variance.", - InvalidNonTypeImportInDeclareModule: "Imports within a `declare module` body must always be `import type` or `import typeof`.", - MissingTypeParamDefault: "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.", - NestedDeclareModule: "`declare module` cannot be used inside another `declare module`.", - NestedFlowComment: "Cannot have a flow comment inside another flow comment.", - PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.", - SetterMayNotHaveThisParam: "A setter cannot have a `this` parameter.", - SpreadVariance: "Spread properties cannot have variance.", - ThisParamAnnotationRequired: "A type annotation is required for the `this` parameter.", - ThisParamBannedInConstructor: "Constructors cannot have a `this` parameter; constructors don't bind `this` like other functions.", - ThisParamMayNotBeOptional: "The `this` parameter cannot be optional.", - ThisParamMustBeFirst: "The `this` parameter must be the first function parameter.", - ThisParamNoDefault: "The `this` parameter may not have a default value.", - TypeBeforeInitializer: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.", - TypeCastInPattern: "The type cast expression is expected to be wrapped with parenthesis.", - UnexpectedExplicitInexactInObject: "Explicit inexact syntax must appear at the end of an inexact object.", - UnexpectedReservedType: "Unexpected reserved type %0.", - UnexpectedReservedUnderscore: "`_` is only allowed as a type argument to call or new.", - UnexpectedSpaceBetweenModuloChecks: "Spaces between `%` and `checks` are not allowed here.", - UnexpectedSpreadType: "Spread operator cannot appear in class or interface definitions.", - UnexpectedSubtractionOperand: 'Unexpected token, expected "number" or "bigint".', - UnexpectedTokenAfterTypeParameter: "Expected an arrow function after this type parameter declaration.", - UnexpectedTypeParameterBeforeAsyncArrowFunction: "Type parameters must come after the async keyword, e.g. instead of `<T> async () => {}`, use `async <T>() => {}`.", - UnsupportedDeclareExportKind: "`declare export %0` is not supported. Use `%1` instead.", - UnsupportedStatementInDeclareModule: "Only declares and type imports are allowed inside declare module.", - UnterminatedFlowComment: "Unterminated flow-comment." -}, ErrorCodes.SyntaxError, "flow"); +const FlowErrors = ParseErrorEnum`flow`(_ => ({ + AmbiguousConditionalArrow: _("Ambiguous expression: wrap the arrow functions in parentheses to disambiguate."), + AmbiguousDeclareModuleKind: _("Found both `declare module.exports` and `declare export` in the same module. Modules can only have 1 since they are either an ES module or they are a CommonJS module."), + AssignReservedType: _(({ + reservedType + }) => `Cannot overwrite reserved type ${reservedType}.`), + DeclareClassElement: _("The `declare` modifier can only appear on class fields."), + DeclareClassFieldInitializer: _("Initializers are not allowed in fields with the `declare` modifier."), + DuplicateDeclareModuleExports: _("Duplicate `declare module.exports` statement."), + EnumBooleanMemberNotInitialized: _(({ + memberName, + enumName + }) => `Boolean enum members need to be initialized. Use either \`${memberName} = true,\` or \`${memberName} = false,\` in enum \`${enumName}\`.`), + EnumDuplicateMemberName: _(({ + memberName, + enumName + }) => `Enum member names need to be unique, but the name \`${memberName}\` has already been used before in enum \`${enumName}\`.`), + EnumInconsistentMemberValues: _(({ + enumName + }) => `Enum \`${enumName}\` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.`), + EnumInvalidExplicitType: _(({ + invalidEnumType, + enumName + }) => `Enum type \`${invalidEnumType}\` is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`), + EnumInvalidExplicitTypeUnknownSupplied: _(({ + enumName + }) => `Supplied enum type is not valid. Use one of \`boolean\`, \`number\`, \`string\`, or \`symbol\` in enum \`${enumName}\`.`), + EnumInvalidMemberInitializerPrimaryType: _(({ + enumName, + memberName, + explicitType + }) => `Enum \`${enumName}\` has type \`${explicitType}\`, so the initializer of \`${memberName}\` needs to be a ${explicitType} literal.`), + EnumInvalidMemberInitializerSymbolType: _(({ + enumName, + memberName + }) => `Symbol enum members cannot be initialized. Use \`${memberName},\` in enum \`${enumName}\`.`), + EnumInvalidMemberInitializerUnknownType: _(({ + enumName, + memberName + }) => `The enum member initializer for \`${memberName}\` needs to be a literal (either a boolean, number, or string) in enum \`${enumName}\`.`), + EnumInvalidMemberName: _(({ + enumName, + memberName, + suggestion + }) => `Enum member names cannot start with lowercase 'a' through 'z'. Instead of using \`${memberName}\`, consider using \`${suggestion}\`, in enum \`${enumName}\`.`), + EnumNumberMemberNotInitialized: _(({ + enumName, + memberName + }) => `Number enum members need to be initialized, e.g. \`${memberName} = 1\` in enum \`${enumName}\`.`), + EnumStringMemberInconsistentlyInitailized: _(({ + enumName + }) => `String enum members need to consistently either all use initializers, or use no initializers, in enum \`${enumName}\`.`), + GetterMayNotHaveThisParam: _("A getter cannot have a `this` parameter."), + ImportTypeShorthandOnlyInPureImport: _("The `type` and `typeof` keywords on named imports can only be used on regular `import` statements. It cannot be used with `import type` or `import typeof` statements."), + InexactInsideExact: _("Explicit inexact syntax cannot appear inside an explicit exact object type."), + InexactInsideNonObject: _("Explicit inexact syntax cannot appear in class or interface definitions."), + InexactVariance: _("Explicit inexact syntax cannot have variance."), + InvalidNonTypeImportInDeclareModule: _("Imports within a `declare module` body must always be `import type` or `import typeof`."), + MissingTypeParamDefault: _("Type parameter declaration needs a default, since a preceding type parameter declaration has a default."), + NestedDeclareModule: _("`declare module` cannot be used inside another `declare module`."), + NestedFlowComment: _("Cannot have a flow comment inside another flow comment."), + PatternIsOptional: _("A binding pattern parameter cannot be optional in an implementation signature.", { + reasonCode: "OptionalBindingPattern" + }), + SetterMayNotHaveThisParam: _("A setter cannot have a `this` parameter."), + SpreadVariance: _("Spread properties cannot have variance."), + ThisParamAnnotationRequired: _("A type annotation is required for the `this` parameter."), + ThisParamBannedInConstructor: _("Constructors cannot have a `this` parameter; constructors don't bind `this` like other functions."), + ThisParamMayNotBeOptional: _("The `this` parameter cannot be optional."), + ThisParamMustBeFirst: _("The `this` parameter must be the first function parameter."), + ThisParamNoDefault: _("The `this` parameter may not have a default value."), + TypeBeforeInitializer: _("Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`."), + TypeCastInPattern: _("The type cast expression is expected to be wrapped with parenthesis."), + UnexpectedExplicitInexactInObject: _("Explicit inexact syntax must appear at the end of an inexact object."), + UnexpectedReservedType: _(({ + reservedType + }) => `Unexpected reserved type ${reservedType}.`), + UnexpectedReservedUnderscore: _("`_` is only allowed as a type argument to call or new."), + UnexpectedSpaceBetweenModuloChecks: _("Spaces between `%` and `checks` are not allowed here."), + UnexpectedSpreadType: _("Spread operator cannot appear in class or interface definitions."), + UnexpectedSubtractionOperand: _('Unexpected token, expected "number" or "bigint".'), + UnexpectedTokenAfterTypeParameter: _("Expected an arrow function after this type parameter declaration."), + UnexpectedTypeParameterBeforeAsyncArrowFunction: _("Type parameters must come after the async keyword, e.g. instead of `<T> async () => {}`, use `async <T>() => {}`."), + UnsupportedDeclareExportKind: _(({ + unsupportedExportKind, + suggestion + }) => `\`declare export ${unsupportedExportKind}\` is not supported. Use \`${suggestion}\` instead.`), + UnsupportedStatementInDeclareModule: _("Only declares and type imports are allowed inside declare module."), + UnterminatedFlowComment: _("Unterminated flow-comment.") +})); function isEsModuleType(bodyElement) { return bodyElement.type === "DeclareExportAllDeclaration" || bodyElement.type === "DeclareExportDeclaration" && (!bodyElement.declaration || bodyElement.declaration.type !== "TypeAlias" && bodyElement.declaration.type !== "InterfaceDeclaration"); @@ -3916,7 +4419,7 @@ } function isMaybeDefaultImport(type) { - return tokenIsKeywordOrIdentifier(type) && type !== 88; + return tokenIsKeywordOrIdentifier(type) && type !== 97; } const exportSuggestions = { @@ -3957,7 +4460,7 @@ } finishToken(type, val) { - if (type !== 120 && type !== 13 && type !== 26) { + if (type !== 129 && type !== 13 && type !== 28) { if (this.flowPragma === undefined) { this.flowPragma = null; } @@ -3993,12 +4496,14 @@ flowParsePredicate() { const node = this.startNode(); - const moduloPos = this.state.start; + const moduloLoc = this.state.startLoc; this.next(); - this.expectContextual(98); + this.expectContextual(107); - if (this.state.lastTokStart > moduloPos + 1) { - this.raise(moduloPos, FlowErrors.UnexpectedSpaceBetweenModuloChecks); + if (this.state.lastTokStart > moduloLoc.index + 1) { + this.raise(FlowErrors.UnexpectedSpaceBetweenModuloChecks, { + at: moduloLoc + }); } if (this.eat(10)) { @@ -4017,14 +4522,14 @@ let type = null; let predicate = null; - if (this.match(45)) { + if (this.match(54)) { this.state.inType = oldInType; predicate = this.flowParsePredicate(); } else { type = this.flowParseType(); this.state.inType = oldInType; - if (this.match(45)) { + if (this.match(54)) { predicate = this.flowParsePredicate(); } } @@ -4044,7 +4549,7 @@ const typeNode = this.startNode(); const typeContainer = this.startNode(); - if (this.isRelational("<")) { + if (this.match(47)) { typeNode.typeParameters = this.flowParseTypeParameterDeclaration(); } else { typeNode.typeParameters = null; @@ -4061,34 +4566,36 @@ id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation"); this.resetEndLocation(id); this.semicolon(); - this.scope.declareName(node.id.name, BIND_FLOW_DECLARE_FN, node.id.start); + this.scope.declareName(node.id.name, BIND_FLOW_DECLARE_FN, node.id.loc.start); return this.finishNode(node, "DeclareFunction"); } flowParseDeclare(node, insideModule) { - if (this.match(71)) { + if (this.match(80)) { return this.flowParseDeclareClass(node); - } else if (this.match(59)) { + } else if (this.match(68)) { return this.flowParseDeclareFunction(node); - } else if (this.match(65)) { + } else if (this.match(74)) { return this.flowParseDeclareVariable(node); - } else if (this.eatContextual(114)) { + } else if (this.eatContextual(123)) { if (this.match(16)) { return this.flowParseDeclareModuleExports(node); } else { if (insideModule) { - this.raise(this.state.lastTokStart, FlowErrors.NestedDeclareModule); + this.raise(FlowErrors.NestedDeclareModule, { + at: this.state.lastTokStartLoc + }); } return this.flowParseDeclareModule(node); } - } else if (this.isContextual(117)) { + } else if (this.isContextual(126)) { return this.flowParseDeclareTypeAlias(node); - } else if (this.isContextual(118)) { + } else if (this.isContextual(127)) { return this.flowParseDeclareOpaqueType(node); - } else if (this.isContextual(116)) { + } else if (this.isContextual(125)) { return this.flowParseDeclareInterface(node); - } else if (this.match(73)) { + } else if (this.match(82)) { return this.flowParseDeclareExportDeclaration(node, insideModule); } else { throw this.unexpected(); @@ -4098,7 +4605,7 @@ flowParseDeclareVariable(node) { this.next(); node.id = this.flowParseTypeAnnotatableIdentifier(true); - this.scope.declareName(node.id.name, BIND_VAR, node.id.start); + this.scope.declareName(node.id.name, BIND_VAR, node.id.loc.start); this.semicolon(); return this.finishNode(node, "DeclareVariable"); } @@ -4106,7 +4613,7 @@ flowParseDeclareModule(node) { this.scope.enter(SCOPE_OTHER); - if (this.match(120)) { + if (this.match(129)) { node.id = this.parseExprAtom(); } else { node.id = this.parseIdentifier(); @@ -4119,16 +4626,18 @@ while (!this.match(8)) { let bodyNode = this.startNode(); - if (this.match(74)) { + if (this.match(83)) { this.next(); - if (!this.isContextual(117) && !this.match(78)) { - this.raise(this.state.lastTokStart, FlowErrors.InvalidNonTypeImportInDeclareModule); + if (!this.isContextual(126) && !this.match(87)) { + this.raise(FlowErrors.InvalidNonTypeImportInDeclareModule, { + at: this.state.lastTokStartLoc + }); } this.parseImport(bodyNode); } else { - this.expectContextual(112, FlowErrors.UnsupportedStatementInDeclareModule); + this.expectContextual(121, FlowErrors.UnsupportedStatementInDeclareModule); bodyNode = this.flowParseDeclare(bodyNode, true); } @@ -4143,17 +4652,23 @@ body.forEach(bodyElement => { if (isEsModuleType(bodyElement)) { if (kind === "CommonJS") { - this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind); + this.raise(FlowErrors.AmbiguousDeclareModuleKind, { + at: bodyElement + }); } kind = "ES"; } else if (bodyElement.type === "DeclareModuleExports") { if (hasModuleExport) { - this.raise(bodyElement.start, FlowErrors.DuplicateDeclareModuleExports); + this.raise(FlowErrors.DuplicateDeclareModuleExports, { + at: bodyElement + }); } if (kind === "ES") { - this.raise(bodyElement.start, FlowErrors.AmbiguousDeclareModuleKind); + this.raise(FlowErrors.AmbiguousDeclareModuleKind, { + at: bodyElement + }); } kind = "CommonJS"; @@ -4165,10 +4680,10 @@ } flowParseDeclareExportDeclaration(node, insideModule) { - this.expect(73); + this.expect(82); - if (this.eat(56)) { - if (this.match(59) || this.match(71)) { + if (this.eat(65)) { + if (this.match(68) || this.match(80)) { node.declaration = this.flowParseDeclare(this.startNode()); } else { node.declaration = this.flowParseType(); @@ -4178,17 +4693,20 @@ node.default = true; return this.finishNode(node, "DeclareExportDeclaration"); } else { - if (this.match(66) || this.isLet() || (this.isContextual(117) || this.isContextual(116)) && !insideModule) { + if (this.match(75) || this.isLet() || (this.isContextual(126) || this.isContextual(125)) && !insideModule) { const label = this.state.value; - const suggestion = exportSuggestions[label]; - throw this.raise(this.state.start, FlowErrors.UnsupportedDeclareExportKind, label, suggestion); + throw this.raise(FlowErrors.UnsupportedDeclareExportKind, { + at: this.state.startLoc, + unsupportedExportKind: label, + suggestion: exportSuggestions[label] + }); } - if (this.match(65) || this.match(59) || this.match(71) || this.isContextual(118)) { + if (this.match(74) || this.match(68) || this.match(80) || this.isContextual(127)) { node.declaration = this.flowParseDeclare(this.startNode()); node.default = false; return this.finishNode(node, "DeclareExportDeclaration"); - } else if (this.match(46) || this.match(5) || this.isContextual(116) || this.isContextual(117) || this.isContextual(118)) { + } else if (this.match(55) || this.match(5) || this.isContextual(125) || this.isContextual(126) || this.isContextual(127)) { node = this.parseExport(node); if (node.type === "ExportNamedDeclaration") { @@ -4207,7 +4725,7 @@ flowParseDeclareModuleExports(node) { this.next(); - this.expectContextual(99); + this.expectContextual(108); node.typeAnnotation = this.flowParseTypeAnnotation(); this.semicolon(); return this.finishNode(node, "DeclareModuleExports"); @@ -4235,9 +4753,9 @@ flowParseInterfaceish(node, isClass = false) { node.id = this.flowParseRestrictedIdentifier(!isClass, true); - this.scope.declareName(node.id.name, isClass ? BIND_FUNCTION : BIND_LEXICAL, node.id.start); + this.scope.declareName(node.id.name, isClass ? BIND_FUNCTION : BIND_LEXICAL, node.id.loc.start); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } else { node.typeParameters = null; @@ -4247,13 +4765,13 @@ node.implements = []; node.mixins = []; - if (this.eat(72)) { + if (this.eat(81)) { do { node.extends.push(this.flowParseInterfaceExtends()); } while (!isClass && this.eat(12)); } - if (this.isContextual(105)) { + if (this.isContextual(114)) { this.next(); do { @@ -4261,7 +4779,7 @@ } while (this.eat(12)); } - if (this.isContextual(101)) { + if (this.isContextual(110)) { this.next(); do { @@ -4282,7 +4800,7 @@ const node = this.startNode(); node.id = this.flowParseQualifiedTypeIdentifier(); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterInstantiation(); } else { node.typeParameters = null; @@ -4298,41 +4816,46 @@ checkNotUnderscore(word) { if (word === "_") { - this.raise(this.state.start, FlowErrors.UnexpectedReservedUnderscore); + this.raise(FlowErrors.UnexpectedReservedUnderscore, { + at: this.state.startLoc + }); } } checkReservedType(word, startLoc, declaration) { if (!reservedTypes.has(word)) return; - this.raise(startLoc, declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, word); + this.raise(declaration ? FlowErrors.AssignReservedType : FlowErrors.UnexpectedReservedType, { + at: startLoc, + reservedType: word + }); } flowParseRestrictedIdentifier(liberal, declaration) { - this.checkReservedType(this.state.value, this.state.start, declaration); + this.checkReservedType(this.state.value, this.state.startLoc, declaration); return this.parseIdentifier(liberal); } flowParseTypeAlias(node) { node.id = this.flowParseRestrictedIdentifier(false, true); - this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start); + this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.loc.start); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } else { node.typeParameters = null; } - node.right = this.flowParseTypeInitialiser(27); + node.right = this.flowParseTypeInitialiser(29); this.semicolon(); return this.finishNode(node, "TypeAlias"); } flowParseOpaqueType(node, declare) { - this.expectContextual(117); + this.expectContextual(126); node.id = this.flowParseRestrictedIdentifier(true, true); - this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.start); + this.scope.declareName(node.id.name, BIND_LEXICAL, node.id.loc.start); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } else { node.typeParameters = null; @@ -4347,7 +4870,7 @@ node.impltype = null; if (!declare) { - node.impltype = this.flowParseTypeInitialiser(27); + node.impltype = this.flowParseTypeInitialiser(29); } this.semicolon(); @@ -4355,7 +4878,7 @@ } flowParseTypeParameter(requireDefault = false) { - const nodeStart = this.state.start; + const nodeStartLoc = this.state.startLoc; const node = this.startNode(); const variance = this.flowParseVariance(); const ident = this.flowParseTypeAnnotatableIdentifier(); @@ -4363,12 +4886,14 @@ node.variance = variance; node.bound = ident.typeAnnotation; - if (this.match(27)) { - this.eat(27); + if (this.match(29)) { + this.eat(29); node.default = this.flowParseType(); } else { if (requireDefault) { - this.raise(nodeStart, FlowErrors.MissingTypeParamDefault); + this.raise(FlowErrors.MissingTypeParamDefault, { + at: nodeStartLoc + }); } } @@ -4381,7 +4906,7 @@ node.params = []; this.state.inType = true; - if (this.isRelational("<") || this.match(129)) { + if (this.match(47) || this.match(138)) { this.next(); } else { this.unexpected(); @@ -4397,12 +4922,12 @@ defaultRequired = true; } - if (!this.isRelational(">")) { + if (!this.match(48)) { this.expect(12); } - } while (!this.isRelational(">")); + } while (!this.match(48)); - this.expectRelational(">"); + this.expect(48); this.state.inType = oldInType; return this.finishNode(node, "TypeParameterDeclaration"); } @@ -4412,20 +4937,20 @@ const oldInType = this.state.inType; node.params = []; this.state.inType = true; - this.expectRelational("<"); + this.expect(47); const oldNoAnonFunctionType = this.state.noAnonFunctionType; this.state.noAnonFunctionType = false; - while (!this.isRelational(">")) { + while (!this.match(48)) { node.params.push(this.flowParseType()); - if (!this.isRelational(">")) { + if (!this.match(48)) { this.expect(12); } } this.state.noAnonFunctionType = oldNoAnonFunctionType; - this.expectRelational(">"); + this.expect(48); this.state.inType = oldInType; return this.finishNode(node, "TypeParameterInstantiation"); } @@ -4435,27 +4960,27 @@ const oldInType = this.state.inType; node.params = []; this.state.inType = true; - this.expectRelational("<"); + this.expect(47); - while (!this.isRelational(">")) { + while (!this.match(48)) { node.params.push(this.flowParseTypeOrImplicitInstantiation()); - if (!this.isRelational(">")) { + if (!this.match(48)) { this.expect(12); } } - this.expectRelational(">"); + this.expect(48); this.state.inType = oldInType; return this.finishNode(node, "TypeParameterInstantiation"); } flowParseInterfaceType() { const node = this.startNode(); - this.expectContextual(116); + this.expectContextual(125); node.extends = []; - if (this.eat(72)) { + if (this.eat(81)) { do { node.extends.push(this.flowParseInterfaceExtends()); } while (this.eat(12)); @@ -4472,7 +4997,7 @@ } flowParseObjectPropertyKey() { - return this.match(121) || this.match(120) ? this.parseExprAtom() : this.parseIdentifier(true); + return this.match(130) || this.match(129) ? this.parseExprAtom() : this.parseIdentifier(true); } flowParseObjectTypeIndexer(node, isStatic, variance) { @@ -4498,7 +5023,7 @@ this.expect(3); this.expect(3); - if (this.isRelational("<") || this.match(10)) { + if (this.match(47) || this.match(10)) { node.method = true; node.optional = false; node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); @@ -4521,13 +5046,13 @@ node.typeParameters = null; node.this = null; - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } this.expect(10); - if (this.match(69)) { + if (this.match(78)) { node.this = this.flowParseFunctionTypeParam(true); node.this.name = null; @@ -4592,21 +5117,21 @@ while (!this.match(endDelim)) { let isStatic = false; - let protoStart = null; - let inexactStart = null; + let protoStartLoc = null; + let inexactStartLoc = null; const node = this.startNode(); - if (allowProto && this.isContextual(106)) { + if (allowProto && this.isContextual(115)) { const lookahead = this.lookahead(); if (lookahead.type !== 14 && lookahead.type !== 17) { this.next(); - protoStart = this.state.start; + protoStartLoc = this.state.startLoc; allowStatic = false; } } - if (allowStatic && this.isContextual(95)) { + if (allowStatic && this.isContextual(104)) { const lookahead = this.lookahead(); if (lookahead.type !== 14 && lookahead.type !== 17) { @@ -4618,33 +5143,33 @@ const variance = this.flowParseVariance(); if (this.eat(0)) { - if (protoStart != null) { - this.unexpected(protoStart); + if (protoStartLoc != null) { + this.unexpected(protoStartLoc); } if (this.eat(0)) { if (variance) { - this.unexpected(variance.start); + this.unexpected(variance.loc.start); } nodeStart.internalSlots.push(this.flowParseObjectTypeInternalSlot(node, isStatic)); } else { nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic, variance)); } - } else if (this.match(10) || this.isRelational("<")) { - if (protoStart != null) { - this.unexpected(protoStart); + } else if (this.match(10) || this.match(47)) { + if (protoStartLoc != null) { + this.unexpected(protoStartLoc); } if (variance) { - this.unexpected(variance.start); + this.unexpected(variance.loc.start); } nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, isStatic)); } else { let kind = "init"; - if (this.isContextual(89) || this.isContextual(94)) { + if (this.isContextual(98) || this.isContextual(103)) { const lookahead = this.lookahead(); if (tokenIsLiteralPropertyName(lookahead.type)) { @@ -4653,11 +5178,11 @@ } } - const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact); + const propOrInexact = this.flowParseObjectTypeProperty(node, isStatic, protoStartLoc, variance, kind, allowSpread, allowInexact != null ? allowInexact : !exact); if (propOrInexact === null) { inexact = true; - inexactStart = this.state.lastTokStart; + inexactStartLoc = this.state.lastTokStartLoc; } else { nodeStart.properties.push(propOrInexact); } @@ -4665,8 +5190,10 @@ this.flowObjectTypeSemicolon(); - if (inexactStart && !this.match(8) && !this.match(9)) { - this.raise(inexactStart, FlowErrors.UnexpectedExplicitInexactInObject); + if (inexactStartLoc && !this.match(8) && !this.match(9)) { + this.raise(FlowErrors.UnexpectedExplicitInexactInObject, { + at: inexactStartLoc + }); } } @@ -4681,34 +5208,44 @@ return out; } - flowParseObjectTypeProperty(node, isStatic, protoStart, variance, kind, allowSpread, allowInexact) { + flowParseObjectTypeProperty(node, isStatic, protoStartLoc, variance, kind, allowSpread, allowInexact) { if (this.eat(21)) { const isInexactToken = this.match(12) || this.match(13) || this.match(8) || this.match(9); if (isInexactToken) { if (!allowSpread) { - this.raise(this.state.lastTokStart, FlowErrors.InexactInsideNonObject); + this.raise(FlowErrors.InexactInsideNonObject, { + at: this.state.lastTokStartLoc + }); } else if (!allowInexact) { - this.raise(this.state.lastTokStart, FlowErrors.InexactInsideExact); + this.raise(FlowErrors.InexactInsideExact, { + at: this.state.lastTokStartLoc + }); } if (variance) { - this.raise(variance.start, FlowErrors.InexactVariance); + this.raise(FlowErrors.InexactVariance, { + at: variance + }); } return null; } if (!allowSpread) { - this.raise(this.state.lastTokStart, FlowErrors.UnexpectedSpreadType); + this.raise(FlowErrors.UnexpectedSpreadType, { + at: this.state.lastTokStartLoc + }); } - if (protoStart != null) { - this.unexpected(protoStart); + if (protoStartLoc != null) { + this.unexpected(protoStartLoc); } if (variance) { - this.raise(variance.start, FlowErrors.SpreadVariance); + this.raise(FlowErrors.SpreadVariance, { + at: variance + }); } node.argument = this.flowParseType(); @@ -4716,19 +5253,19 @@ } else { node.key = this.flowParseObjectPropertyKey(); node.static = isStatic; - node.proto = protoStart != null; + node.proto = protoStartLoc != null; node.kind = kind; let optional = false; - if (this.isRelational("<") || this.match(10)) { + if (this.match(47) || this.match(10)) { node.method = true; - if (protoStart != null) { - this.unexpected(protoStart); + if (protoStartLoc != null) { + this.unexpected(protoStartLoc); } if (variance) { - this.unexpected(variance.start); + this.unexpected(variance.loc.start); } node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(node.start, node.loc.start)); @@ -4738,7 +5275,9 @@ } if (!allowSpread && node.key.name === "constructor" && node.value.this) { - this.raise(node.value.this.start, FlowErrors.ThisParamBannedInConstructor); + this.raise(FlowErrors.ThisParamBannedInConstructor, { + at: node.value.this + }); } } else { if (kind !== "init") this.unexpected(); @@ -4759,23 +5298,24 @@ flowCheckGetterSetterParams(property) { const paramCount = property.kind === "get" ? 0 : 1; - const start = property.start; const length = property.value.params.length + (property.value.rest ? 1 : 0); if (property.value.this) { - this.raise(property.value.this.start, property.kind === "get" ? FlowErrors.GetterMayNotHaveThisParam : FlowErrors.SetterMayNotHaveThisParam); + this.raise(property.kind === "get" ? FlowErrors.GetterMayNotHaveThisParam : FlowErrors.SetterMayNotHaveThisParam, { + at: property.value.this + }); } if (length !== paramCount) { - if (property.kind === "get") { - this.raise(start, ErrorMessages.BadGetterArity); - } else { - this.raise(start, ErrorMessages.BadSetterArity); - } + this.raise(property.kind === "get" ? Errors.BadGetterArity : Errors.BadSetterArity, { + at: property + }); } if (property.kind === "set" && property.value.rest) { - this.raise(start, ErrorMessages.BadSetterRestParameter); + this.raise(Errors.BadSetterRestParameter, { + at: property + }); } } @@ -4805,7 +5345,7 @@ node.typeParameters = null; node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterInstantiation(); } @@ -4814,7 +5354,7 @@ flowParseTypeofType() { const node = this.startNode(); - this.expect(78); + this.expect(87); node.argument = this.flowParsePrimaryType(); return this.finishNode(node, "TypeofTypeAnnotation"); } @@ -4840,11 +5380,13 @@ let typeAnnotation = null; const node = this.startNode(); const lh = this.lookahead(); - const isThis = this.state.type === 69; + const isThis = this.state.type === 78; if (lh.type === 14 || lh.type === 17) { if (isThis && !first) { - this.raise(node.start, FlowErrors.ThisParamMustBeFirst); + this.raise(FlowErrors.ThisParamMustBeFirst, { + at: node + }); } name = this.parseIdentifier(isThis); @@ -4853,7 +5395,9 @@ optional = true; if (isThis) { - this.raise(node.start, FlowErrors.ThisParamMayNotBeOptional); + this.raise(FlowErrors.ThisParamMayNotBeOptional, { + at: node + }); } } @@ -4880,7 +5424,7 @@ let rest = null; let _this = null; - if (this.match(69)) { + if (this.match(78)) { _this = this.flowParseFunctionTypeParam(true); _this.name = null; @@ -4972,27 +5516,23 @@ this.state.noAnonFunctionType = oldNoAnonFunctionType; return type; - case 42: - if (this.state.value === "<") { - node.typeParameters = this.flowParseTypeParameterDeclaration(); - this.expect(10); - tmp = this.flowParseFunctionTypeParams(); - node.params = tmp.params; - node.rest = tmp.rest; - node.this = tmp._this; - this.expect(11); - this.expect(19); - node.returnType = this.flowParseType(); - return this.finishNode(node, "FunctionTypeAnnotation"); - } - - break; + case 47: + node.typeParameters = this.flowParseTypeParameterDeclaration(); + this.expect(10); + tmp = this.flowParseFunctionTypeParams(); + node.params = tmp.params; + node.rest = tmp.rest; + node.this = tmp._this; + this.expect(11); + this.expect(19); + node.returnType = this.flowParseType(); + return this.finishNode(node, "FunctionTypeAnnotation"); case 10: this.next(); if (!this.match(11) && !this.match(21)) { - if (tokenIsIdentifier(this.state.type) || this.match(69)) { + if (tokenIsIdentifier(this.state.type) || this.match(78)) { const token = this.lookahead().type; isGroupedType = token !== 17 && token !== 14; } else { @@ -5028,55 +5568,57 @@ node.typeParameters = null; return this.finishNode(node, "FunctionTypeAnnotation"); - case 120: + case 129: return this.parseLiteral(this.state.value, "StringLiteralTypeAnnotation"); - case 76: - case 77: - node.value = this.match(76); + case 85: + case 86: + node.value = this.match(85); this.next(); return this.finishNode(node, "BooleanLiteralTypeAnnotation"); - case 44: + case 53: if (this.state.value === "-") { this.next(); - if (this.match(121)) { + if (this.match(130)) { return this.parseLiteralAtNode(-this.state.value, "NumberLiteralTypeAnnotation", node); } - if (this.match(122)) { + if (this.match(131)) { return this.parseLiteralAtNode(-this.state.value, "BigIntLiteralTypeAnnotation", node); } - throw this.raise(this.state.start, FlowErrors.UnexpectedSubtractionOperand); + throw this.raise(FlowErrors.UnexpectedSubtractionOperand, { + at: this.state.startLoc + }); } throw this.unexpected(); - case 121: + case 130: return this.parseLiteral(this.state.value, "NumberLiteralTypeAnnotation"); - case 122: + case 131: return this.parseLiteral(this.state.value, "BigIntLiteralTypeAnnotation"); - case 79: + case 88: this.next(); return this.finishNode(node, "VoidTypeAnnotation"); - case 75: + case 84: this.next(); return this.finishNode(node, "NullLiteralTypeAnnotation"); - case 69: + case 78: this.next(); return this.finishNode(node, "ThisTypeAnnotation"); - case 46: + case 55: this.next(); return this.finishNode(node, "ExistsTypeAnnotation"); - case 78: + case 87: return this.flowParseTypeofType(); default: @@ -5085,7 +5627,7 @@ this.next(); return super.createIdentifier(node, label); } else if (tokenIsIdentifier(this.state.type)) { - if (this.isContextual(116)) { + if (this.isContextual(125)) { return this.flowParseInterfaceType(); } @@ -5159,11 +5701,11 @@ flowParseIntersectionType() { const node = this.startNode(); - this.eat(40); + this.eat(45); const type = this.flowParseAnonFunctionWithoutParens(); node.types = [type]; - while (this.eat(40)) { + while (this.eat(45)) { node.types.push(this.flowParseAnonFunctionWithoutParens()); } @@ -5172,11 +5714,11 @@ flowParseUnionType() { const node = this.startNode(); - this.eat(38); + this.eat(43); const type = this.flowParseIntersectionType(); node.types = [type]; - while (this.eat(38)) { + while (this.eat(43)) { node.types.push(this.flowParseIntersectionType()); } @@ -5192,7 +5734,7 @@ } flowParseTypeOrImplicitInstantiation() { - if (this.state.type === 119 && this.state.value === "_") { + if (this.state.type === 128 && this.state.value === "_") { const startPos = this.state.start; const startLoc = this.state.startLoc; const node = this.parseIdentifier(); @@ -5221,14 +5763,14 @@ typeCastToParameter(node) { node.expression.typeAnnotation = node.typeAnnotation; - this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); + this.resetEndLocation(node.expression, node.typeAnnotation.loc.end); return node.expression; } flowParseVariance() { let variance = null; - if (this.match(44)) { + if (this.match(53)) { variance = this.startNode(); if (this.state.value === "+") { @@ -5263,7 +5805,7 @@ } parseStatement(context, topLevel) { - if (this.state.strict && this.isContextual(116)) { + if (this.state.strict && this.isContextual(125)) { const lookahead = this.lookahead(); if (tokenIsKeywordOrIdentifier(lookahead.type)) { @@ -5271,7 +5813,7 @@ this.next(); return this.flowParseInterface(node); } - } else if (this.shouldParseEnums() && this.isContextual(113)) { + } else if (this.shouldParseEnums() && this.isContextual(122)) { const node = this.startNode(); this.next(); return this.flowParseEnumDeclaration(node); @@ -5289,7 +5831,7 @@ parseExpressionStatement(node, expr) { if (expr.type === "Identifier") { if (expr.name === "declare") { - if (this.match(71) || tokenIsIdentifier(this.state.type) || this.match(59) || this.match(65) || this.match(73)) { + if (this.match(80) || tokenIsIdentifier(this.state.type) || this.match(68) || this.match(74) || this.match(82)) { return this.flowParseDeclare(node); } } else if (tokenIsIdentifier(this.state.type)) { @@ -5311,7 +5853,7 @@ type } = this.state; - if (tokenIsFlowInterfaceOrTypeOrOpaque(type) || this.shouldParseEnums() && type === 113) { + if (tokenIsFlowInterfaceOrTypeOrOpaque(type) || this.shouldParseEnums() && type === 122) { return !this.state.containsEsc; } @@ -5323,7 +5865,7 @@ type } = this.state; - if (tokenIsFlowInterfaceOrTypeOrOpaque(type) || this.shouldParseEnums() && type === 113) { + if (tokenIsFlowInterfaceOrTypeOrOpaque(type) || this.shouldParseEnums() && type === 122) { return this.state.containsEsc; } @@ -5331,7 +5873,7 @@ } parseExportDefaultExpression() { - if (this.shouldParseEnums() && this.isContextual(113)) { + if (this.shouldParseEnums() && this.isContextual(122)) { const node = this.startNode(); this.next(); return this.flowParseEnumDeclaration(node); @@ -5381,7 +5923,9 @@ } if (failed && valid.length > 1) { - this.raise(state.start, FlowErrors.AmbiguousConditionalArrow); + this.raise(FlowErrors.AmbiguousConditionalArrow, { + at: state.startLoc + }); } if (failed && valid.length === 1) { @@ -5447,7 +5991,7 @@ finishArrowValidation(node) { var _node$extra; - this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingComma, false); + this.toAssignableList(node.params, (_node$extra = node.extra) == null ? void 0 : _node$extra.trailingCommaLoc, false); this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW); super.checkParams(node, false, true); this.scope.exit(); @@ -5504,29 +6048,29 @@ } parseExportDeclaration(node) { - if (this.isContextual(117)) { + if (this.isContextual(126)) { node.exportKind = "type"; const declarationNode = this.startNode(); this.next(); if (this.match(5)) { - node.specifiers = this.parseExportSpecifiers(); + node.specifiers = this.parseExportSpecifiers(true); this.parseExportFrom(node); return null; } else { return this.flowParseTypeAlias(declarationNode); } - } else if (this.isContextual(118)) { + } else if (this.isContextual(127)) { node.exportKind = "type"; const declarationNode = this.startNode(); this.next(); return this.flowParseOpaqueType(declarationNode, false); - } else if (this.isContextual(116)) { + } else if (this.isContextual(125)) { node.exportKind = "type"; const declarationNode = this.startNode(); this.next(); return this.flowParseInterface(declarationNode); - } else if (this.shouldParseEnums() && this.isContextual(113)) { + } else if (this.shouldParseEnums() && this.isContextual(122)) { node.exportKind = "value"; const declarationNode = this.startNode(); this.next(); @@ -5539,7 +6083,7 @@ eatExportStar(node) { if (super.eatExportStar(...arguments)) return true; - if (this.isContextual(117) && this.lookahead().type === 46) { + if (this.isContextual(126) && this.lookahead().type === 55) { node.exportKind = "type"; this.next(); this.next(); @@ -5550,11 +6094,13 @@ } maybeParseExportNamespaceSpecifier(node) { - const pos = this.state.start; + const { + startLoc + } = this.state; const hasNamespace = super.maybeParseExportNamespaceSpecifier(node); if (hasNamespace && node.exportKind === "type") { - this.unexpected(pos); + this.unexpected(startLoc); } return hasNamespace; @@ -5563,15 +6109,17 @@ parseClassId(node, isStatement, optionalId) { super.parseClassId(node, isStatement, optionalId); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } } parseClassMember(classBody, member, state) { - const pos = this.state.start; + const { + startLoc + } = this.state; - if (this.isContextual(112)) { + if (this.isContextual(121)) { if (this.parseClassMemberFromModifier(classBody, member)) { return; } @@ -5583,9 +6131,13 @@ if (member.declare) { if (member.type !== "ClassProperty" && member.type !== "ClassPrivateProperty" && member.type !== "PropertyDefinition") { - this.raise(pos, FlowErrors.DeclareClassElement); + this.raise(FlowErrors.DeclareClassElement, { + at: startLoc + }); } else if (member.value) { - this.raise(member.value.start, FlowErrors.DeclareClassFieldInitializer); + this.raise(FlowErrors.DeclareClassFieldInitializer, { + at: member.value + }); } } } @@ -5599,10 +6151,13 @@ const fullWord = "@@" + word; if (!this.isIterator(word) || !this.state.inType) { - this.raise(this.state.pos, ErrorMessages.InvalidIdentifier, fullWord); + this.raise(Errors.InvalidIdentifier, { + at: this.state.curPosition(), + identifierName: fullWord + }); } - this.finishToken(119, fullWord); + this.finishToken(128, fullWord); } getTokenFromCode(code) { @@ -5611,14 +6166,14 @@ if (code === 123 && next === 124) { return this.finishOp(6, 2); } else if (this.state.inType && (code === 62 || code === 60)) { - return this.finishOp(42, 1); + return this.finishOp(code === 62 ? 48 : 47, 1); } else if (this.state.inType && code === 63) { if (next === 46) { return this.finishOp(18, 2); } return this.finishOp(17, 1); - } else if (isIteratorStart(code, next)) { + } else if (isIteratorStart(code, next, this.input.charCodeAt(this.state.pos + 2))) { this.state.pos += 2; return this.readIterator(); } else { @@ -5635,14 +6190,14 @@ } toAssignable(node, isLHS = false) { - if (node.type === "TypeCastExpression") { - return super.toAssignable(this.typeCastToParameter(node), isLHS); - } else { - return super.toAssignable(node, isLHS); + if (!isLHS && node.type === "AssignmentExpression" && node.left.type === "TypeCastExpression") { + node.left = this.typeCastToParameter(node.left); } + + super.toAssignable(...arguments); } - toAssignableList(exprList, trailingCommaPos, isLHS) { + toAssignableList(exprList, trailingCommaLoc, isLHS) { for (let i = 0; i < exprList.length; i++) { const expr = exprList[i]; @@ -5651,7 +6206,7 @@ } } - return super.toAssignableList(exprList, trailingCommaPos, isLHS); + super.toAssignableList(exprList, trailingCommaLoc, isLHS); } toReferencedList(exprList, isParenthesizedExpr) { @@ -5661,7 +6216,9 @@ const expr = exprList[i]; if (expr && expr.type === "TypeCastExpression" && !((_expr$extra = expr.extra) != null && _expr$extra.parenthesized) && (exprList.length > 1 || !isParenthesizedExpr)) { - this.raise(expr.typeAnnotation.start, FlowErrors.TypeCastInPattern); + this.raise(FlowErrors.TypeCastInPattern, { + at: expr.typeAnnotation + }); } } @@ -5678,10 +6235,8 @@ return node; } - checkLVal(expr, ...args) { - if (expr.type !== "TypeCastExpression") { - return super.checkLVal(expr, ...args); - } + isValidLVal(type, ...rest) { + return type === "TypeCastExpression" || super.isValidLVal(type, ...rest); } parseClassProperty(node) { @@ -5701,7 +6256,7 @@ } isClassMethod() { - return this.isRelational("<") || super.isClassMethod(); + return this.match(47) || super.isClassMethod(); } isClassProperty() { @@ -5714,12 +6269,12 @@ pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { if (method.variance) { - this.unexpected(method.variance.start); + this.unexpected(method.variance.loc.start); } delete method.variance; - if (this.isRelational("<")) { + if (this.match(47)) { method.typeParameters = this.flowParseTypeParameterDeclaration(); } @@ -5729,25 +6284,29 @@ const params = method.params; if (params.length > 0 && this.isThisParam(params[0])) { - this.raise(method.start, FlowErrors.ThisParamBannedInConstructor); + this.raise(FlowErrors.ThisParamBannedInConstructor, { + at: method + }); } } else if (method.type === "MethodDefinition" && isConstructor && method.value.params) { const params = method.value.params; if (params.length > 0 && this.isThisParam(params[0])) { - this.raise(method.start, FlowErrors.ThisParamBannedInConstructor); + this.raise(FlowErrors.ThisParamBannedInConstructor, { + at: method + }); } } } pushClassPrivateMethod(classBody, method, isGenerator, isAsync) { if (method.variance) { - this.unexpected(method.variance.start); + this.unexpected(method.variance.loc.start); } delete method.variance; - if (this.isRelational("<")) { + if (this.match(47)) { method.typeParameters = this.flowParseTypeParameterDeclaration(); } @@ -5757,11 +6316,11 @@ parseClassSuper(node) { super.parseClassSuper(node); - if (node.superClass && this.isRelational("<")) { + if (node.superClass && this.match(47)) { node.superTypeParameters = this.flowParseTypeParameterInstantiation(); } - if (this.isContextual(101)) { + if (this.isContextual(110)) { this.next(); const implemented = node.implements = []; @@ -5769,7 +6328,7 @@ const node = this.startNode(); node.id = this.flowParseRestrictedIdentifier(true); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.flowParseTypeParameterInstantiation(); } else { node.typeParameters = null; @@ -5788,29 +6347,30 @@ const param = params[0]; if (this.isThisParam(param) && method.kind === "get") { - this.raise(param.start, FlowErrors.GetterMayNotHaveThisParam); + this.raise(FlowErrors.GetterMayNotHaveThisParam, { + at: param + }); } else if (this.isThisParam(param)) { - this.raise(param.start, FlowErrors.SetterMayNotHaveThisParam); + this.raise(FlowErrors.SetterMayNotHaveThisParam, { + at: param + }); } } } - parsePropertyName(node, isPrivateNameAllowed) { - const variance = this.flowParseVariance(); - const key = super.parsePropertyName(node, isPrivateNameAllowed); - node.variance = variance; - return key; + parsePropertyNamePrefixOperator(node) { + node.variance = this.flowParseVariance(); } parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors) { if (prop.variance) { - this.unexpected(prop.variance.start); + this.unexpected(prop.variance.loc.start); } delete prop.variance; let typeParameters; - if (this.isRelational("<") && !isAccessor) { + if (this.match(47) && !isAccessor) { typeParameters = this.flowParseTypeParameterDeclaration(); if (!this.match(10)) this.unexpected(); } @@ -5825,11 +6385,15 @@ parseAssignableListItemTypes(param) { if (this.eat(17)) { if (param.type !== "Identifier") { - this.raise(param.start, FlowErrors.PatternIsOptional); + this.raise(FlowErrors.PatternIsOptional, { + at: param + }); } if (this.isThisParam(param)) { - this.raise(param.start, FlowErrors.ThisParamMayNotBeOptional); + this.raise(FlowErrors.ThisParamMayNotBeOptional, { + at: param + }); } param.optional = true; @@ -5838,11 +6402,15 @@ if (this.match(14)) { param.typeAnnotation = this.flowParseTypeAnnotation(); } else if (this.isThisParam(param)) { - this.raise(param.start, FlowErrors.ThisParamAnnotationRequired); + this.raise(FlowErrors.ThisParamAnnotationRequired, { + at: param + }); } - if (this.match(27) && this.isThisParam(param)) { - this.raise(param.start, FlowErrors.ThisParamNoDefault); + if (this.match(29) && this.isThisParam(param)) { + this.raise(FlowErrors.ThisParamNoDefault, { + at: param + }); } this.resetEndLocation(param); @@ -5853,7 +6421,9 @@ const node = super.parseMaybeDefault(startPos, startLoc, left); if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { - this.raise(node.typeAnnotation.start, FlowErrors.TypeBeforeInitializer); + this.raise(FlowErrors.TypeBeforeInitializer, { + at: node.typeAnnotation + }); } return node; @@ -5867,19 +6437,18 @@ return isMaybeDefaultImport(this.state.type); } - parseImportSpecifierLocal(node, specifier, type, contextDescription) { + parseImportSpecifierLocal(node, specifier, type) { specifier.local = hasTypeImportKind(node) ? this.flowParseRestrictedIdentifier(true, true) : this.parseIdentifier(); - this.checkLVal(specifier.local, contextDescription, BIND_LEXICAL); - node.specifiers.push(this.finishNode(specifier, type)); + node.specifiers.push(this.finishImportSpecifier(specifier, type)); } maybeParseDefaultImportSpecifier(node) { node.importKind = "value"; let kind = null; - if (this.match(78)) { + if (this.match(87)) { kind = "typeof"; - } else if (this.isContextual(117)) { + } else if (this.isContextual(126)) { kind = "type"; } @@ -5889,11 +6458,11 @@ type } = lh; - if (kind === "type" && type === 46) { - this.unexpected(lh.start); + if (kind === "type" && type === 55) { + this.unexpected(null, lh.type); } - if (isMaybeDefaultImport(type) || type === 5 || type === 46) { + if (isMaybeDefaultImport(type) || type === 5 || type === 55) { this.next(); node.importKind = kind; } @@ -5902,10 +6471,8 @@ return super.maybeParseDefaultImportSpecifier(node); } - parseImportSpecifier(node) { - const specifier = this.startNode(); - const firstIdentIsString = this.match(120); - const firstIdent = this.parseModuleExportName(); + parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly) { + const firstIdent = specifier.imported; let specifierTypeKind = null; if (firstIdent.type === "Identifier") { @@ -5918,7 +6485,7 @@ let isBinding = false; - if (this.isContextual(84) && !this.isLookaheadContextual("as")) { + if (this.isContextual(93) && !this.isLookaheadContextual("as")) { const as_ident = this.parseIdentifier(true); if (specifierTypeKind !== null && !tokenIsKeywordOrIdentifier(this.state.type)) { @@ -5935,15 +6502,18 @@ specifier.imported = this.parseIdentifier(true); specifier.importKind = specifierTypeKind; } else { - if (firstIdentIsString) { - throw this.raise(specifier.start, ErrorMessages.ImportBindingIsString, firstIdent.value); + if (importedIsString) { + throw this.raise(Errors.ImportBindingIsString, { + at: specifier, + importName: firstIdent.value + }); } specifier.imported = firstIdent; specifier.importKind = null; } - if (this.eatContextual(84)) { + if (this.eatContextual(93)) { specifier.local = this.parseIdentifier(); } else { isBinding = true; @@ -5951,28 +6521,28 @@ } } - const nodeIsTypeImport = hasTypeImportKind(node); const specifierIsTypeImport = hasTypeImportKind(specifier); - if (nodeIsTypeImport && specifierIsTypeImport) { - this.raise(specifier.start, FlowErrors.ImportTypeShorthandOnlyInPureImport); + if (isInTypeOnlyImport && specifierIsTypeImport) { + this.raise(FlowErrors.ImportTypeShorthandOnlyInPureImport, { + at: specifier + }); } - if (nodeIsTypeImport || specifierIsTypeImport) { - this.checkReservedType(specifier.local.name, specifier.local.start, true); + if (isInTypeOnlyImport || specifierIsTypeImport) { + this.checkReservedType(specifier.local.name, specifier.local.loc.start, true); } - if (isBinding && !nodeIsTypeImport && !specifierIsTypeImport) { - this.checkReservedWord(specifier.local.name, specifier.start, true, true); + if (isBinding && !isInTypeOnlyImport && !specifierIsTypeImport) { + this.checkReservedWord(specifier.local.name, specifier.loc.start, true, true); } - this.checkLVal(specifier.local, "import specifier", BIND_LEXICAL); - node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + return this.finishImportSpecifier(specifier, "ImportSpecifier"); } parseBindingAtom() { switch (this.state.type) { - case 69: + case 78: return this.parseIdentifier(true); default: @@ -5983,7 +6553,7 @@ parseFunctionParams(node, allowModifiers) { const kind = node.kind; - if (kind !== "get" && kind !== "set" && this.isRelational("<")) { + if (kind !== "get" && kind !== "set" && this.match(47)) { node.typeParameters = this.flowParseTypeParameterDeclaration(); } @@ -6020,23 +6590,21 @@ let state = null; let jsx; - if (this.hasPlugin("jsx") && (this.match(129) || this.isRelational("<"))) { + if (this.hasPlugin("jsx") && (this.match(138) || this.match(47))) { state = this.state.clone(); jsx = this.tryParse(() => super.parseMaybeAssign(refExpressionErrors, afterLeftParse), state); if (!jsx.error) return jsx.node; const { context } = this.state; - const curContext = context[context.length - 1]; + const currentContext = context[context.length - 1]; - if (curContext === types.j_oTag) { - context.length -= 2; - } else if (curContext === types.j_expr) { - context.length -= 1; + if (currentContext === types.j_oTag || currentContext === types.j_expr) { + context.pop(); } } - if ((_jsx = jsx) != null && _jsx.error || this.isRelational("<")) { + if ((_jsx = jsx) != null && _jsx.error || this.match(47)) { var _jsx2, _jsx3; state = state || this.state.clone(); @@ -6062,7 +6630,9 @@ if (arrow.node && this.maybeUnwrapTypeCastExpression(arrow.node).type === "ArrowFunctionExpression") { if (!arrow.error && !arrow.aborted) { if (arrow.node.async) { - this.raise(typeParameters.start, FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction); + this.raise(FlowErrors.UnexpectedTypeParameterBeforeAsyncArrowFunction, { + at: typeParameters + }); } return arrow.node; @@ -6083,7 +6653,9 @@ if ((_jsx3 = jsx) != null && _jsx3.thrown) throw jsx.error; if (arrow.thrown) throw arrow.error; - throw this.raise(typeParameters.start, FlowErrors.UnexpectedTokenAfterTypeParameter); + throw this.raise(FlowErrors.UnexpectedTokenAfterTypeParameter, { + at: typeParameters + }); } return super.parseMaybeAssign(refExpressionErrors, afterLeftParse); @@ -6128,7 +6700,9 @@ for (let i = 0; i < node.params.length; i++) { if (this.isThisParam(node.params[i]) && i > 0) { - this.raise(node.params[i].start, FlowErrors.ThisParamMustBeFirst); + this.raise(FlowErrors.ThisParamMustBeFirst, { + at: node.params[i] + }); } } @@ -6146,7 +6720,7 @@ node.callee = base; node.arguments = this.parseCallExpressionArguments(11, false); base = this.finishNode(node, "CallExpression"); - } else if (base.type === "Identifier" && base.name === "async" && this.isRelational("<")) { + } else if (base.type === "Identifier" && base.name === "async" && this.match(47)) { const state = this.state.clone(); const arrow = this.tryParse(abort => this.parseAsyncArrowWithTypeParameters(startPos, startLoc) || abort(), state); if (!arrow.error && !arrow.aborted) return arrow.node; @@ -6186,7 +6760,7 @@ node.arguments = this.parseCallExpressionArguments(11, false); node.optional = true; return this.finishCallExpression(node, true); - } else if (!noCalls && this.shouldParseTypes() && this.isRelational("<")) { + } else if (!noCalls && this.shouldParseTypes() && this.match(47)) { const node = this.startNodeAt(startPos, startLoc); node.callee = base; const result = this.tryParse(() => { @@ -6209,7 +6783,7 @@ parseNewArguments(node) { let targs = null; - if (this.shouldParseTypes() && this.isRelational("<")) { + if (this.shouldParseTypes() && this.match(47)) { targs = this.tryParse(() => this.flowParseTypeParameterInstantiationCallOrNew()).node; } @@ -6252,7 +6826,9 @@ const fileNode = super.parseTopLevel(file, program); if (this.state.hasFlowComment) { - this.raise(this.state.pos, FlowErrors.UnterminatedFlowComment); + this.raise(FlowErrors.UnterminatedFlowComment, { + at: this.state.curPosition() + }); } return fileNode; @@ -6261,7 +6837,9 @@ skipBlockComment() { if (this.hasPlugin("flowComments") && this.skipFlowComment()) { if (this.state.hasFlowComment) { - this.unexpected(null, FlowErrors.NestedFlowComment); + throw this.raise(FlowErrors.NestedFlowComment, { + at: this.state.startLoc + }); } this.hasFlowCommentCompletion(); @@ -6271,13 +6849,15 @@ } if (this.state.hasFlowComment) { - const end = this.input.indexOf("*-/", this.state.pos += 2); + const end = this.input.indexOf("*-/", this.state.pos + 2); if (end === -1) { - throw this.raise(this.state.pos - 2, ErrorMessages.UnterminatedComment); + throw this.raise(Errors.UnterminatedComment, { + at: this.state.curPosition() + }); } - this.state.pos = end + 3; + this.state.pos = end + 2 + 3; return; } @@ -6316,158 +6896,124 @@ const end = this.input.indexOf("*/", this.state.pos); if (end === -1) { - throw this.raise(this.state.pos, ErrorMessages.UnterminatedComment); + throw this.raise(Errors.UnterminatedComment, { + at: this.state.curPosition() + }); } } - flowEnumErrorBooleanMemberNotInitialized(pos, { + flowEnumErrorBooleanMemberNotInitialized(loc, { enumName, memberName }) { - this.raise(pos, FlowErrors.EnumBooleanMemberNotInitialized, memberName, enumName); + this.raise(FlowErrors.EnumBooleanMemberNotInitialized, { + at: loc, + memberName, + enumName + }); } - flowEnumErrorInvalidMemberName(pos, { + flowEnumErrorInvalidMemberInitializer(loc, enumContext) { + return this.raise(!enumContext.explicitType ? FlowErrors.EnumInvalidMemberInitializerUnknownType : enumContext.explicitType === "symbol" ? FlowErrors.EnumInvalidMemberInitializerSymbolType : FlowErrors.EnumInvalidMemberInitializerPrimaryType, Object.assign({ + at: loc + }, enumContext)); + } + + flowEnumErrorNumberMemberNotInitialized(loc, { enumName, memberName }) { - const suggestion = memberName[0].toUpperCase() + memberName.slice(1); - this.raise(pos, FlowErrors.EnumInvalidMemberName, memberName, suggestion, enumName); + this.raise(FlowErrors.EnumNumberMemberNotInitialized, { + at: loc, + enumName, + memberName + }); } - flowEnumErrorDuplicateMemberName(pos, { - enumName, - memberName - }) { - this.raise(pos, FlowErrors.EnumDuplicateMemberName, memberName, enumName); - } - - flowEnumErrorInconsistentMemberValues(pos, { + flowEnumErrorStringMemberInconsistentlyInitailized(node, { enumName }) { - this.raise(pos, FlowErrors.EnumInconsistentMemberValues, enumName); - } - - flowEnumErrorInvalidExplicitType(pos, { - enumName, - suppliedType - }) { - return this.raise(pos, suppliedType === null ? FlowErrors.EnumInvalidExplicitTypeUnknownSupplied : FlowErrors.EnumInvalidExplicitType, enumName, suppliedType); - } - - flowEnumErrorInvalidMemberInitializer(pos, { - enumName, - explicitType, - memberName - }) { - let message = null; - - switch (explicitType) { - case "boolean": - case "number": - case "string": - message = FlowErrors.EnumInvalidMemberInitializerPrimaryType; - break; - - case "symbol": - message = FlowErrors.EnumInvalidMemberInitializerSymbolType; - break; - - default: - message = FlowErrors.EnumInvalidMemberInitializerUnknownType; - } - - return this.raise(pos, message, enumName, memberName, explicitType); - } - - flowEnumErrorNumberMemberNotInitialized(pos, { - enumName, - memberName - }) { - this.raise(pos, FlowErrors.EnumNumberMemberNotInitialized, enumName, memberName); - } - - flowEnumErrorStringMemberInconsistentlyInitailized(pos, { - enumName - }) { - this.raise(pos, FlowErrors.EnumStringMemberInconsistentlyInitailized, enumName); + this.raise(FlowErrors.EnumStringMemberInconsistentlyInitailized, { + at: node, + enumName + }); } flowEnumMemberInit() { - const startPos = this.state.start; + const startLoc = this.state.startLoc; const endOfInit = () => this.match(12) || this.match(8); switch (this.state.type) { - case 121: + case 130: { const literal = this.parseNumericLiteral(this.state.value); if (endOfInit()) { return { type: "number", - pos: literal.start, + loc: literal.loc.start, value: literal }; } return { type: "invalid", - pos: startPos + loc: startLoc }; } - case 120: + case 129: { const literal = this.parseStringLiteral(this.state.value); if (endOfInit()) { return { type: "string", - pos: literal.start, + loc: literal.loc.start, value: literal }; } return { type: "invalid", - pos: startPos + loc: startLoc }; } - case 76: - case 77: + case 85: + case 86: { - const literal = this.parseBooleanLiteral(this.match(76)); + const literal = this.parseBooleanLiteral(this.match(85)); if (endOfInit()) { return { type: "boolean", - pos: literal.start, + loc: literal.loc.start, value: literal }; } return { type: "invalid", - pos: startPos + loc: startLoc }; } default: return { type: "invalid", - pos: startPos + loc: startLoc }; } } flowEnumMemberRaw() { - const pos = this.state.start; + const loc = this.state.startLoc; const id = this.parseIdentifier(true); - const init = this.eat(27) ? this.flowEnumMemberInit() : { + const init = this.eat(29) ? this.flowEnumMemberInit() : { type: "none", - pos + loc }; return { id, @@ -6475,7 +7021,7 @@ }; } - flowEnumCheckExplicitTypeMismatch(pos, context, expectedType) { + flowEnumCheckExplicitTypeMismatch(loc, context, expectedType) { const { explicitType } = context; @@ -6485,7 +7031,7 @@ } if (explicitType !== expectedType) { - this.flowEnumErrorInvalidMemberInitializer(pos, context); + this.flowEnumErrorInvalidMemberInitializer(loc, context); } } @@ -6520,16 +7066,19 @@ } if (/^[a-z]/.test(memberName)) { - this.flowEnumErrorInvalidMemberName(id.start, { - enumName, - memberName + this.raise(FlowErrors.EnumInvalidMemberName, { + at: id, + memberName, + suggestion: memberName[0].toUpperCase() + memberName.slice(1), + enumName }); } if (seenNames.has(memberName)) { - this.flowEnumErrorDuplicateMemberName(id.start, { - enumName, - memberName + this.raise(FlowErrors.EnumDuplicateMemberName, { + at: id, + memberName, + enumName }); } @@ -6544,7 +7093,7 @@ switch (init.type) { case "boolean": { - this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "boolean"); + this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "boolean"); memberNode.init = init.value; members.booleanMembers.push(this.finishNode(memberNode, "EnumBooleanMember")); break; @@ -6552,7 +7101,7 @@ case "number": { - this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "number"); + this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "number"); memberNode.init = init.value; members.numberMembers.push(this.finishNode(memberNode, "EnumNumberMember")); break; @@ -6560,7 +7109,7 @@ case "string": { - this.flowEnumCheckExplicitTypeMismatch(init.pos, context, "string"); + this.flowEnumCheckExplicitTypeMismatch(init.loc, context, "string"); memberNode.init = init.value; members.stringMembers.push(this.finishNode(memberNode, "EnumStringMember")); break; @@ -6568,18 +7117,18 @@ case "invalid": { - throw this.flowEnumErrorInvalidMemberInitializer(init.pos, context); + throw this.flowEnumErrorInvalidMemberInitializer(init.loc, context); } case "none": { switch (explicitType) { case "boolean": - this.flowEnumErrorBooleanMemberNotInitialized(init.pos, context); + this.flowEnumErrorBooleanMemberNotInitialized(init.loc, context); break; case "number": - this.flowEnumErrorNumberMemberNotInitialized(init.pos, context); + this.flowEnumErrorNumberMemberNotInitialized(init.loc, context); break; default: @@ -6608,7 +7157,7 @@ return initializedMembers; } else if (defaultedMembers.length > initializedMembers.length) { for (const member of initializedMembers) { - this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, { + this.flowEnumErrorStringMemberInconsistentlyInitailized(member, { enumName }); } @@ -6616,7 +7165,7 @@ return defaultedMembers; } else { for (const member of defaultedMembers) { - this.flowEnumErrorStringMemberInconsistentlyInitailized(member.start, { + this.flowEnumErrorStringMemberInconsistentlyInitailized(member, { enumName }); } @@ -6628,36 +7177,34 @@ flowEnumParseExplicitType({ enumName }) { - if (this.eatContextual(92)) { - if (!tokenIsIdentifier(this.state.type)) { - throw this.flowEnumErrorInvalidExplicitType(this.state.start, { - enumName, - suppliedType: null - }); - } + if (!this.eatContextual(101)) return null; - const { - value - } = this.state; - this.next(); - - if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") { - this.flowEnumErrorInvalidExplicitType(this.state.start, { - enumName, - suppliedType: value - }); - } - - return value; + if (!tokenIsIdentifier(this.state.type)) { + throw this.raise(FlowErrors.EnumInvalidExplicitTypeUnknownSupplied, { + at: this.state.startLoc, + enumName + }); } - return null; + const { + value + } = this.state; + this.next(); + + if (value !== "boolean" && value !== "number" && value !== "string" && value !== "symbol") { + this.raise(FlowErrors.EnumInvalidExplicitType, { + at: this.state.startLoc, + enumName, + invalidEnumType: value + }); + } + + return value; } - flowEnumBody(node, { - enumName, - nameLoc - }) { + flowEnumBody(node, id) { + const enumName = id.name; + const nameLoc = id.loc.start; const explicitType = this.flowEnumParseExplicitType({ enumName }); @@ -6721,7 +7268,7 @@ return this.finishNode(node, "EnumStringBody"); } else if (!numsLen && !strsLen && boolsLen >= defaultedLen) { for (const member of members.defaultedMembers) { - this.flowEnumErrorBooleanMemberNotInitialized(member.start, { + this.flowEnumErrorBooleanMemberNotInitialized(member.loc.start, { enumName, memberName: member.id.name }); @@ -6732,7 +7279,7 @@ return this.finishNode(node, "EnumBooleanBody"); } else if (!boolsLen && !strsLen && numsLen >= defaultedLen) { for (const member of members.defaultedMembers) { - this.flowEnumErrorNumberMemberNotInitialized(member.start, { + this.flowEnumErrorNumberMemberNotInitialized(member.loc.start, { enumName, memberName: member.id.name }); @@ -6742,7 +7289,8 @@ this.expect(8); return this.finishNode(node, "EnumNumberBody"); } else { - this.flowEnumErrorInconsistentMemberValues(nameLoc, { + this.raise(FlowErrors.EnumInconsistentMemberValues, { + at: nameLoc, enumName }); return empty(); @@ -6754,10 +7302,7 @@ flowParseEnumDeclaration(node) { const id = this.parseIdentifier(); node.id = id; - node.body = this.flowEnumBody(this.startNode(), { - enumName: id.name, - nameLoc: id.start - }); + node.body = this.flowEnumBody(this.startNode(), id); return this.finishNode(node, "EnumDeclaration"); } @@ -6779,6 +7324,7 @@ }); const entities = { + __proto__: null, quot: "\u0022", amp: "&", apos: "\u0027", @@ -7034,20 +7580,21 @@ diams: "\u2666" }; -const HEX_NUMBER = /^[\da-fA-F]+$/; -const DECIMAL_NUMBER = /^\d+$/; -const JsxErrors = makeErrorTemplates({ - AttributeIsEmpty: "JSX attributes must only be assigned a non-empty expression.", - MissingClosingTagElement: "Expected corresponding JSX closing tag for <%0>.", - MissingClosingTagFragment: "Expected corresponding JSX closing tag for <>.", - UnexpectedSequenceExpression: "Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?", - UnsupportedJsxValue: "JSX value should be either an expression or a quoted JSX text.", - UnterminatedJsxContent: "Unterminated JSX contents.", - UnwrappedAdjacentJSXElements: "Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?" -}, ErrorCodes.SyntaxError, "jsx"); -types.j_oTag = new TokContext("<tag"); -types.j_cTag = new TokContext("</tag"); -types.j_expr = new TokContext("<tag>...</tag>", true); +const JsxErrors = ParseErrorEnum`jsx`(_ => ({ + AttributeIsEmpty: _("JSX attributes must only be assigned a non-empty expression."), + MissingClosingTagElement: _(({ + openingTagName + }) => `Expected corresponding JSX closing tag for <${openingTagName}>.`), + MissingClosingTagFragment: _("Expected corresponding JSX closing tag for <>."), + UnexpectedSequenceExpression: _("Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?"), + UnexpectedToken: _(({ + unexpected, + HTMLEntity + }) => `Unexpected token \`${unexpected}\`. Did you mean \`${HTMLEntity}\` or \`{'${unexpected}'}\`?`), + UnsupportedJsxValue: _("JSX value should be either an expression or a quoted JSX text."), + UnterminatedJsxContent: _("Unterminated JSX contents."), + UnwrappedAdjacentJSXElements: _("Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?") +})); function isFragment(object) { return object ? object.type === "JSXOpeningFragment" || object.type === "JSXClosingFragment" : false; @@ -7076,7 +7623,9 @@ for (;;) { if (this.state.pos >= this.length) { - throw this.raise(this.state.start, JsxErrors.UnterminatedJsxContent); + throw this.raise(JsxErrors.UnterminatedJsxContent, { + at: this.state.startLoc + }); } const ch = this.input.charCodeAt(this.state.pos); @@ -7085,16 +7634,16 @@ case 60: case 123: if (this.state.pos === this.state.start) { - if (ch === 60 && this.state.exprAllowed) { + if (ch === 60 && this.state.canStartJSXElement) { ++this.state.pos; - return this.finishToken(129); + return this.finishToken(138); } return super.getTokenFromCode(ch); } out += this.input.slice(chunkStart, this.state.pos); - return this.finishToken(128, out); + return this.finishToken(137, out); case 38: out += this.input.slice(chunkStart, this.state.pos); @@ -7141,7 +7690,9 @@ for (;;) { if (this.state.pos >= this.length) { - throw this.raise(this.state.start, ErrorMessages.UnterminatedString); + throw this.raise(Errors.UnterminatedString, { + at: this.state.startLoc + }); } const ch = this.input.charCodeAt(this.state.pos); @@ -7161,50 +7712,48 @@ } out += this.input.slice(chunkStart, this.state.pos++); - return this.finishToken(120, out); + return this.finishToken(129, out); } jsxReadEntity() { - let str = ""; - let count = 0; - let entity; - let ch = this.input[this.state.pos]; const startPos = ++this.state.pos; - while (this.state.pos < this.length && count++ < 10) { - ch = this.input[this.state.pos++]; + if (this.codePointAtPos(this.state.pos) === 35) { + ++this.state.pos; + let radix = 10; - if (ch === ";") { - if (str[0] === "#") { - if (str[1] === "x") { - str = str.substr(2); - - if (HEX_NUMBER.test(str)) { - entity = String.fromCodePoint(parseInt(str, 16)); - } - } else { - str = str.substr(1); - - if (DECIMAL_NUMBER.test(str)) { - entity = String.fromCodePoint(parseInt(str, 10)); - } - } - } else { - entity = entities[str]; - } - - break; + if (this.codePointAtPos(this.state.pos) === 120) { + radix = 16; + ++this.state.pos; } - str += ch; + const codePoint = this.readInt(radix, undefined, false, "bail"); + + if (codePoint !== null && this.codePointAtPos(this.state.pos) === 59) { + ++this.state.pos; + return String.fromCodePoint(codePoint); + } + } else { + let count = 0; + let semi = false; + + while (count++ < 10 && this.state.pos < this.length && !(semi = this.codePointAtPos(this.state.pos) == 59)) { + ++this.state.pos; + } + + if (semi) { + const desc = this.input.slice(startPos, this.state.pos); + const entity = entities[desc]; + ++this.state.pos; + + if (entity) { + return entity; + } + } } - if (!entity) { - this.state.pos = startPos; - return "&"; - } - - return entity; + this.state.pos = startPos; + return "&"; } jsxReadWord() { @@ -7215,13 +7764,13 @@ ch = this.input.charCodeAt(++this.state.pos); } while (isIdentifierChar(ch) || ch === 45); - return this.finishToken(127, this.input.slice(start, this.state.pos)); + return this.finishToken(136, this.input.slice(start, this.state.pos)); } jsxParseIdentifier() { const node = this.startNode(); - if (this.match(127)) { + if (this.match(136)) { node.name = this.state.value; } else if (tokenIsKeyword(this.state.type)) { node.name = tokenLabelName(this.state.type); @@ -7269,37 +7818,43 @@ switch (this.state.type) { case 5: node = this.startNode(); + this.setContext(types.brace); this.next(); - node = this.jsxParseExpressionContainer(node); + node = this.jsxParseExpressionContainer(node, types.j_oTag); if (node.expression.type === "JSXEmptyExpression") { - this.raise(node.start, JsxErrors.AttributeIsEmpty); + this.raise(JsxErrors.AttributeIsEmpty, { + at: node + }); } return node; + case 138: case 129: - case 120: return this.parseExprAtom(); default: - throw this.raise(this.state.start, JsxErrors.UnsupportedJsxValue); + throw this.raise(JsxErrors.UnsupportedJsxValue, { + at: this.state.startLoc + }); } } jsxParseEmptyExpression() { - const node = this.startNodeAt(this.state.lastTokEnd, this.state.lastTokEndLoc); - return this.finishNodeAt(node, "JSXEmptyExpression", this.state.start, this.state.startLoc); + const node = this.startNodeAt(this.state.lastTokEndLoc.index, this.state.lastTokEndLoc); + return this.finishNodeAt(node, "JSXEmptyExpression", this.state.startLoc); } jsxParseSpreadChild(node) { this.next(); node.expression = this.parseExpression(); + this.setContext(types.j_oTag); this.expect(8); return this.finishNode(node, "JSXSpreadChild"); } - jsxParseExpressionContainer(node) { + jsxParseExpressionContainer(node, previousContext) { if (this.match(8)) { node.expression = this.jsxParseEmptyExpression(); } else { @@ -7307,6 +7862,7 @@ node.expression = expression; } + this.setContext(previousContext); this.expect(8); return this.finishNode(node, "JSXExpressionContainer"); } @@ -7314,23 +7870,26 @@ jsxParseAttribute() { const node = this.startNode(); - if (this.eat(5)) { + if (this.match(5)) { + this.setContext(types.brace); + this.next(); this.expect(21); node.argument = this.parseMaybeAssignAllowIn(); + this.setContext(types.j_oTag); this.expect(8); return this.finishNode(node, "JSXSpreadAttribute"); } node.name = this.jsxParseNamespacedName(); - node.value = this.eat(27) ? this.jsxParseAttributeValue() : null; + node.value = this.eat(29) ? this.jsxParseAttributeValue() : null; return this.finishNode(node, "JSXAttribute"); } jsxParseOpeningElementAt(startPos, startLoc) { const node = this.startNodeAt(startPos, startLoc); - if (this.match(130)) { - this.expect(130); + if (this.match(139)) { + this.expect(139); return this.finishNode(node, "JSXOpeningFragment"); } @@ -7341,26 +7900,26 @@ jsxParseOpeningElementAfterName(node) { const attributes = []; - while (!this.match(47) && !this.match(130)) { + while (!this.match(56) && !this.match(139)) { attributes.push(this.jsxParseAttribute()); } node.attributes = attributes; - node.selfClosing = this.eat(47); - this.expect(130); + node.selfClosing = this.eat(56); + this.expect(139); return this.finishNode(node, "JSXOpeningElement"); } jsxParseClosingElementAt(startPos, startLoc) { const node = this.startNodeAt(startPos, startLoc); - if (this.match(130)) { - this.expect(130); + if (this.match(139)) { + this.expect(139); return this.finishNode(node, "JSXClosingFragment"); } node.name = this.jsxParseElementName(); - this.expect(130); + this.expect(139); return this.finishNode(node, "JSXClosingElement"); } @@ -7373,12 +7932,12 @@ if (!openingElement.selfClosing) { contents: for (;;) { switch (this.state.type) { - case 129: + case 138: startPos = this.state.start; startLoc = this.state.startLoc; this.next(); - if (this.eat(47)) { + if (this.eat(56)) { closingElement = this.jsxParseClosingElementAt(startPos, startLoc); break contents; } @@ -7386,19 +7945,20 @@ children.push(this.jsxParseElementAt(startPos, startLoc)); break; - case 128: + case 137: children.push(this.parseExprAtom()); break; case 5: { const node = this.startNode(); + this.setContext(types.brace); this.next(); if (this.match(21)) { children.push(this.jsxParseSpreadChild(node)); } else { - children.push(this.jsxParseExpressionContainer(node)); + children.push(this.jsxParseExpressionContainer(node, types.j_expr)); } break; @@ -7409,13 +7969,21 @@ } } - if (isFragment(openingElement) && !isFragment(closingElement)) { - this.raise(closingElement.start, JsxErrors.MissingClosingTagFragment); + if (isFragment(openingElement) && !isFragment(closingElement) && closingElement !== null) { + this.raise(JsxErrors.MissingClosingTagFragment, { + at: closingElement + }); } else if (!isFragment(openingElement) && isFragment(closingElement)) { - this.raise(closingElement.start, JsxErrors.MissingClosingTagElement, getQualifiedJSXName(openingElement.name)); + this.raise(JsxErrors.MissingClosingTagElement, { + at: closingElement, + openingTagName: getQualifiedJSXName(openingElement.name) + }); } else if (!isFragment(openingElement) && !isFragment(closingElement)) { if (getQualifiedJSXName(closingElement.name) !== getQualifiedJSXName(openingElement.name)) { - this.raise(closingElement.start, JsxErrors.MissingClosingTagElement, getQualifiedJSXName(openingElement.name)); + this.raise(JsxErrors.MissingClosingTagElement, { + at: closingElement, + openingTagName: getQualifiedJSXName(openingElement.name) + }); } } } @@ -7430,8 +7998,10 @@ node.children = children; - if (this.isRelational("<")) { - throw this.raise(this.state.start, JsxErrors.UnwrappedAdjacentJSXElements); + if (this.match(47)) { + throw this.raise(JsxErrors.UnwrappedAdjacentJSXElements, { + at: this.state.startLoc + }); } return isFragment(openingElement) ? this.finishNode(node, "JSXFragment") : this.finishNode(node, "JSXElement"); @@ -7444,27 +8014,32 @@ return this.jsxParseElementAt(startPos, startLoc); } + setContext(newContext) { + const { + context + } = this.state; + context[context.length - 1] = newContext; + } + parseExprAtom(refExpressionErrors) { - if (this.match(128)) { + if (this.match(137)) { return this.parseLiteral(this.state.value, "JSXText"); - } else if (this.match(129)) { + } else if (this.match(138)) { return this.jsxParseElement(); - } else if (this.isRelational("<") && this.input.charCodeAt(this.state.pos) !== 33) { - this.finishToken(129); + } else if (this.match(47) && this.input.charCodeAt(this.state.pos) !== 33) { + this.replaceToken(138); return this.jsxParseElement(); } else { return super.parseExprAtom(refExpressionErrors); } } - createLookaheadState(state) { - const lookaheadState = super.createLookaheadState(state); - lookaheadState.inPropertyName = state.inPropertyName; - return lookaheadState; + skipSpace() { + const curContext = this.curContext(); + if (!curContext.preserveSpace) super.skipSpace(); } getTokenFromCode(code) { - if (this.state.inPropertyName) return super.getTokenFromCode(code); const context = this.curContext(); if (context === types.j_expr) { @@ -7478,7 +8053,7 @@ if (code === 62) { ++this.state.pos; - return this.finishToken(130); + return this.finishToken(139); } if ((code === 34 || code === 39) && context === types.j_oTag) { @@ -7486,39 +8061,37 @@ } } - if (code === 60 && this.state.exprAllowed && this.input.charCodeAt(this.state.pos + 1) !== 33) { + if (code === 60 && this.state.canStartJSXElement && this.input.charCodeAt(this.state.pos + 1) !== 33) { ++this.state.pos; - return this.finishToken(129); + return this.finishToken(138); } return super.getTokenFromCode(code); } updateContext(prevType) { - super.updateContext(prevType); const { context, type } = this.state; - if (type === 47 && prevType === 129) { + if (type === 56 && prevType === 138) { context.splice(-2, 2, types.j_cTag); - this.state.exprAllowed = false; - } else if (type === 129) { - context.push(types.j_expr, types.j_oTag); - } else if (type === 130) { - const out = context.pop(); + this.state.canStartJSXElement = false; + } else if (type === 138) { + context.push(types.j_oTag); + } else if (type === 139) { + const out = context[context.length - 1]; - if (out === types.j_oTag && prevType === 47 || out === types.j_cTag) { + if (out === types.j_oTag && prevType === 56 || out === types.j_cTag) { context.pop(); - this.state.exprAllowed = context[context.length - 1] === types.j_expr; + this.state.canStartJSXElement = context[context.length - 1] === types.j_expr; } else { - this.state.exprAllowed = true; + this.setContext(types.j_expr); + this.state.canStartJSXElement = true; } - } else if (tokenIsKeyword(type) && (prevType === 16 || prevType === 18)) { - this.state.exprAllowed = false; } else { - this.state.exprAllowed = tokenComesBeforeExpression(type); + this.state.canStartJSXElement = tokenComesBeforeExpression(type); } } @@ -7541,7 +8114,7 @@ return new TypeScriptScope(flags); } - declareName(name, bindingType, pos) { + declareName(name, bindingType, loc) { const scope = this.currentScope(); if (bindingType & BIND_FLAGS_TS_EXPORT_ONLY) { @@ -7554,7 +8127,7 @@ if (bindingType & BIND_KIND_TYPE) { if (!(bindingType & BIND_KIND_VALUE)) { - this.checkRedeclarationInScope(scope, name, bindingType, pos); + this.checkRedeclarationInScope(scope, name, bindingType, loc); this.maybeExportDefined(scope, name); } @@ -7605,6 +8178,8 @@ } +const getOwn$1 = (object, key) => Object.hasOwnProperty.call(object, key) && object[key]; + function nonNull(x) { if (x == null) { throw new Error(`Unexpected ${x} value.`); @@ -7619,57 +8194,93 @@ } } -const TSErrors = makeErrorTemplates({ - AbstractMethodHasImplementation: "Method '%0' cannot have an implementation because it is marked abstract.", - AbstractPropertyHasInitializer: "Property '%0' cannot have an initializer because it is marked abstract.", - AccesorCannotDeclareThisParameter: "'get' and 'set' accessors cannot declare 'this' parameters.", - AccesorCannotHaveTypeParameters: "An accessor cannot have type parameters.", - ClassMethodHasDeclare: "Class methods cannot have the 'declare' modifier.", - ClassMethodHasReadonly: "Class methods cannot have the 'readonly' modifier.", - ConstructorHasTypeParameters: "Type parameters cannot appear on a constructor declaration.", - DeclareAccessor: "'declare' is not allowed in %0ters.", - DeclareClassFieldHasInitializer: "Initializers are not allowed in ambient contexts.", - DeclareFunctionHasImplementation: "An implementation cannot be declared in ambient contexts.", - DuplicateAccessibilityModifier: "Accessibility modifier already seen.", - DuplicateModifier: "Duplicate modifier: '%0'.", - EmptyHeritageClauseType: "'%0' list cannot be empty.", - EmptyTypeArguments: "Type argument list cannot be empty.", - EmptyTypeParameters: "Type parameter list cannot be empty.", - ExpectedAmbientAfterExportDeclare: "'export declare' must be followed by an ambient declaration.", - ImportAliasHasImportType: "An import alias can not use 'import type'.", - IncompatibleModifiers: "'%0' modifier cannot be used with '%1' modifier.", - IndexSignatureHasAbstract: "Index signatures cannot have the 'abstract' modifier.", - IndexSignatureHasAccessibility: "Index signatures cannot have an accessibility modifier ('%0').", - IndexSignatureHasDeclare: "Index signatures cannot have the 'declare' modifier.", - IndexSignatureHasOverride: "'override' modifier cannot appear on an index signature.", - IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier.", - InvalidModifierOnTypeMember: "'%0' modifier cannot appear on a type member.", - InvalidModifiersOrder: "'%0' modifier must precede '%1' modifier.", - InvalidTupleMemberLabel: "Tuple members must be labeled with a simple identifier.", - MissingInterfaceName: "'interface' declarations must be followed by an identifier.", - MixedLabeledAndUnlabeledElements: "Tuple members must all have names or all not have names.", - NonAbstractClassHasAbstractMethod: "Abstract methods can only appear within an abstract class.", - NonClassMethodPropertyHasAbstractModifer: "'abstract' modifier can only appear on a class, method, or property declaration.", - OptionalTypeBeforeRequired: "A required element cannot follow an optional element.", - OverrideNotInSubClass: "This member cannot have an 'override' modifier because its containing class does not extend another class.", - PatternIsOptional: "A binding pattern parameter cannot be optional in an implementation signature.", - PrivateElementHasAbstract: "Private elements cannot have the 'abstract' modifier.", - PrivateElementHasAccessibility: "Private elements cannot have an accessibility modifier ('%0').", - ReadonlyForMethodSignature: "'readonly' modifier can only appear on a property declaration or index signature.", - SetAccesorCannotHaveOptionalParameter: "A 'set' accessor cannot have an optional parameter.", - SetAccesorCannotHaveRestParameter: "A 'set' accessor cannot have rest parameter.", - SetAccesorCannotHaveReturnType: "A 'set' accessor cannot have a return type annotation.", - StaticBlockCannotHaveModifier: "Static class blocks cannot have any modifier.", - TypeAnnotationAfterAssign: "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`.", - TypeImportCannotSpecifyDefaultAndNamed: "A type-only import can specify a default import or named bindings, but not both.", - UnexpectedParameterModifier: "A parameter property is only allowed in a constructor implementation.", - UnexpectedReadonly: "'readonly' type modifier is only permitted on array and tuple literal types.", - UnexpectedTypeAnnotation: "Did not expect a type annotation here.", - UnexpectedTypeCastInParameter: "Unexpected type cast in parameter position.", - UnsupportedImportTypeArgument: "Argument in a type import must be a string literal.", - UnsupportedParameterPropertyKind: "A parameter property may not be declared using a binding pattern.", - UnsupportedSignatureParameterKind: "Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got %0." -}, ErrorCodes.SyntaxError, "typescript"); +const TSErrors = ParseErrorEnum`typescript`(_ => ({ + AbstractMethodHasImplementation: _(({ + methodName + }) => `Method '${methodName}' cannot have an implementation because it is marked abstract.`), + AbstractPropertyHasInitializer: _(({ + propertyName + }) => `Property '${propertyName}' cannot have an initializer because it is marked abstract.`), + AccesorCannotDeclareThisParameter: _("'get' and 'set' accessors cannot declare 'this' parameters."), + AccesorCannotHaveTypeParameters: _("An accessor cannot have type parameters."), + CannotFindName: _(({ + name + }) => `Cannot find name '${name}'.`), + ClassMethodHasDeclare: _("Class methods cannot have the 'declare' modifier."), + ClassMethodHasReadonly: _("Class methods cannot have the 'readonly' modifier."), + ConstInitiailizerMustBeStringOrNumericLiteralOrLiteralEnumReference: _("A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference."), + ConstructorHasTypeParameters: _("Type parameters cannot appear on a constructor declaration."), + DeclareAccessor: _(({ + kind + }) => `'declare' is not allowed in ${kind}ters.`), + DeclareClassFieldHasInitializer: _("Initializers are not allowed in ambient contexts."), + DeclareFunctionHasImplementation: _("An implementation cannot be declared in ambient contexts."), + DuplicateAccessibilityModifier: _(({ + modifier + }) => `Accessibility modifier already seen.`), + DuplicateModifier: _(({ + modifier + }) => `Duplicate modifier: '${modifier}'.`), + EmptyHeritageClauseType: _(({ + token + }) => `'${token}' list cannot be empty.`), + EmptyTypeArguments: _("Type argument list cannot be empty."), + EmptyTypeParameters: _("Type parameter list cannot be empty."), + ExpectedAmbientAfterExportDeclare: _("'export declare' must be followed by an ambient declaration."), + ImportAliasHasImportType: _("An import alias can not use 'import type'."), + IncompatibleModifiers: _(({ + modifiers + }) => `'${modifiers[0]}' modifier cannot be used with '${modifiers[1]}' modifier.`), + IndexSignatureHasAbstract: _("Index signatures cannot have the 'abstract' modifier."), + IndexSignatureHasAccessibility: _(({ + modifier + }) => `Index signatures cannot have an accessibility modifier ('${modifier}').`), + IndexSignatureHasDeclare: _("Index signatures cannot have the 'declare' modifier."), + IndexSignatureHasOverride: _("'override' modifier cannot appear on an index signature."), + IndexSignatureHasStatic: _("Index signatures cannot have the 'static' modifier."), + InitializerNotAllowedInAmbientContext: _("Initializers are not allowed in ambient contexts."), + InvalidModifierOnTypeMember: _(({ + modifier + }) => `'${modifier}' modifier cannot appear on a type member.`), + InvalidModifiersOrder: _(({ + orderedModifiers + }) => `'${orderedModifiers[0]}' modifier must precede '${orderedModifiers[1]}' modifier.`), + InvalidTupleMemberLabel: _("Tuple members must be labeled with a simple identifier."), + MissingInterfaceName: _("'interface' declarations must be followed by an identifier."), + MixedLabeledAndUnlabeledElements: _("Tuple members must all have names or all not have names."), + NonAbstractClassHasAbstractMethod: _("Abstract methods can only appear within an abstract class."), + NonClassMethodPropertyHasAbstractModifer: _("'abstract' modifier can only appear on a class, method, or property declaration."), + OptionalTypeBeforeRequired: _("A required element cannot follow an optional element."), + OverrideNotInSubClass: _("This member cannot have an 'override' modifier because its containing class does not extend another class."), + PatternIsOptional: _("A binding pattern parameter cannot be optional in an implementation signature."), + PrivateElementHasAbstract: _("Private elements cannot have the 'abstract' modifier."), + PrivateElementHasAccessibility: _(({ + modifier + }) => `Private elements cannot have an accessibility modifier ('${modifier}').`), + ReadonlyForMethodSignature: _("'readonly' modifier can only appear on a property declaration or index signature."), + ReservedArrowTypeParam: _("This syntax is reserved in files with the .mts or .cts extension. Add a trailing comma, as in `<T,>() => ...`."), + ReservedTypeAssertion: _("This syntax is reserved in files with the .mts or .cts extension. Use an `as` expression instead."), + SetAccesorCannotHaveOptionalParameter: _("A 'set' accessor cannot have an optional parameter."), + SetAccesorCannotHaveRestParameter: _("A 'set' accessor cannot have rest parameter."), + SetAccesorCannotHaveReturnType: _("A 'set' accessor cannot have a return type annotation."), + SingleTypeParameterWithoutTrailingComma: _(({ + typeParameterName + }) => `Single type parameter ${typeParameterName} should have a trailing comma. Example usage: <${typeParameterName},>.`), + StaticBlockCannotHaveModifier: _("Static class blocks cannot have any modifier."), + TypeAnnotationAfterAssign: _("Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`."), + TypeImportCannotSpecifyDefaultAndNamed: _("A type-only import can specify a default import or named bindings, but not both."), + TypeModifierIsUsedInTypeExports: _("The 'type' modifier cannot be used on a named export when 'export type' is used on its export statement."), + TypeModifierIsUsedInTypeImports: _("The 'type' modifier cannot be used on a named import when 'import type' is used on its import statement."), + UnexpectedParameterModifier: _("A parameter property is only allowed in a constructor implementation."), + UnexpectedReadonly: _("'readonly' type modifier is only permitted on array and tuple literal types."), + UnexpectedTypeAnnotation: _("Did not expect a type annotation here."), + UnexpectedTypeCastInParameter: _("Unexpected type cast in parameter position."), + UnsupportedImportTypeArgument: _("Argument in a type import must be a string literal."), + UnsupportedParameterPropertyKind: _("A parameter property may not be declared using a binding pattern."), + UnsupportedSignatureParameterKind: _(({ + type + }) => `Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got ${type}.`) +})); function keywordTypeFromName(value) { switch (value) { @@ -7722,7 +8333,7 @@ } tsTokenCanFollowModifier() { - return (this.match(0) || this.match(5) || this.match(46) || this.match(21) || this.match(125) || this.isLiteralPropertyName()) && !this.hasPrecedingLineBreak(); + return (this.match(0) || this.match(5) || this.match(55) || this.match(21) || this.match(134) || this.isLiteralPropertyName()) && !this.hasPrecedingLineBreak(); } tsNextTokenCanFollowModifier() { @@ -7750,50 +8361,72 @@ return undefined; } - tsParseModifiers(modified, allowedModifiers, disallowedModifiers, errorTemplate, stopOnStartOfClassStaticBlock) { - const enforceOrder = (pos, modifier, before, after) => { + tsParseModifiers({ + modified, + allowedModifiers, + disallowedModifiers, + stopOnStartOfClassStaticBlock + }) { + const enforceOrder = (loc, modifier, before, after) => { if (modifier === before && modified[after]) { - this.raise(pos, TSErrors.InvalidModifiersOrder, before, after); + this.raise(TSErrors.InvalidModifiersOrder, { + at: loc, + orderedModifiers: [before, after] + }); } }; - const incompatible = (pos, modifier, mod1, mod2) => { + const incompatible = (loc, modifier, mod1, mod2) => { if (modified[mod1] && modifier === mod2 || modified[mod2] && modifier === mod1) { - this.raise(pos, TSErrors.IncompatibleModifiers, mod1, mod2); + this.raise(TSErrors.IncompatibleModifiers, { + at: loc, + modifiers: [mod1, mod2] + }); } }; for (;;) { - const startPos = this.state.start; + const { + startLoc + } = this.state; const modifier = this.tsParseModifier(allowedModifiers.concat(disallowedModifiers != null ? disallowedModifiers : []), stopOnStartOfClassStaticBlock); if (!modifier) break; if (tsIsAccessModifier(modifier)) { if (modified.accessibility) { - this.raise(startPos, TSErrors.DuplicateAccessibilityModifier); + this.raise(TSErrors.DuplicateAccessibilityModifier, { + at: startLoc, + modifier + }); } else { - enforceOrder(startPos, modifier, modifier, "override"); - enforceOrder(startPos, modifier, modifier, "static"); - enforceOrder(startPos, modifier, modifier, "readonly"); + enforceOrder(startLoc, modifier, modifier, "override"); + enforceOrder(startLoc, modifier, modifier, "static"); + enforceOrder(startLoc, modifier, modifier, "readonly"); modified.accessibility = modifier; } } else { if (Object.hasOwnProperty.call(modified, modifier)) { - this.raise(startPos, TSErrors.DuplicateModifier, modifier); + this.raise(TSErrors.DuplicateModifier, { + at: startLoc, + modifier + }); } else { - enforceOrder(startPos, modifier, "static", "readonly"); - enforceOrder(startPos, modifier, "static", "override"); - enforceOrder(startPos, modifier, "override", "readonly"); - enforceOrder(startPos, modifier, "abstract", "override"); - incompatible(startPos, modifier, "declare", "override"); - incompatible(startPos, modifier, "static", "abstract"); + enforceOrder(startLoc, modifier, "static", "readonly"); + enforceOrder(startLoc, modifier, "static", "override"); + enforceOrder(startLoc, modifier, "override", "readonly"); + enforceOrder(startLoc, modifier, "abstract", "override"); + incompatible(startLoc, modifier, "declare", "override"); + incompatible(startLoc, modifier, "static", "abstract"); } modified[modifier] = true; } if (disallowedModifiers != null && disallowedModifiers.includes(modifier)) { - this.raise(startPos, errorTemplate, modifier); + this.raise(TSErrors.InvalidModifierOnTypeMember, { + at: startLoc, + modifier + }); } } } @@ -7811,7 +8444,7 @@ return this.match(3); case "TypeParametersOrArguments": - return this.isRelational(">"); + return this.match(48); } throw new Error("Unreachable"); @@ -7827,18 +8460,20 @@ return result; } - tsParseDelimitedList(kind, parseElement) { - return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true)); + tsParseDelimitedList(kind, parseElement, refTrailingCommaPos) { + return nonNull(this.tsParseDelimitedListWorker(kind, parseElement, true, refTrailingCommaPos)); } - tsParseDelimitedListWorker(kind, parseElement, expectSuccess) { + tsParseDelimitedListWorker(kind, parseElement, expectSuccess, refTrailingCommaPos) { const result = []; + let trailingCommaPos = -1; for (;;) { if (this.tsIsListTerminator(kind)) { break; } + trailingCommaPos = -1; const element = parseElement(); if (element == null) { @@ -7848,6 +8483,7 @@ result.push(element); if (this.eat(12)) { + trailingCommaPos = this.state.lastTokStart; continue; } @@ -7862,24 +8498,28 @@ return undefined; } + if (refTrailingCommaPos) { + refTrailingCommaPos.value = trailingCommaPos; + } + return result; } - tsParseBracketedList(kind, parseElement, bracket, skipFirstToken) { + tsParseBracketedList(kind, parseElement, bracket, skipFirstToken, refTrailingCommaPos) { if (!skipFirstToken) { if (bracket) { this.expect(0); } else { - this.expectRelational("<"); + this.expect(47); } } - const result = this.tsParseDelimitedList(kind, parseElement); + const result = this.tsParseDelimitedList(kind, parseElement, refTrailingCommaPos); if (bracket) { this.expect(3); } else { - this.expectRelational(">"); + this.expect(48); } return result; @@ -7887,29 +8527,31 @@ tsParseImportType() { const node = this.startNode(); - this.expect(74); + this.expect(83); this.expect(10); - if (!this.match(120)) { - this.raise(this.state.start, TSErrors.UnsupportedImportTypeArgument); + if (!this.match(129)) { + this.raise(TSErrors.UnsupportedImportTypeArgument, { + at: this.state.startLoc + }); } node.argument = this.parseExprAtom(); this.expect(11); if (this.eat(16)) { - node.qualifier = this.tsParseEntityName(true); + node.qualifier = this.tsParseEntityName(); } - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.tsParseTypeArguments(); } return this.finishNode(node, "TSImportType"); } - tsParseEntityName(allowReservedWords) { - let entity = this.parseIdentifier(); + tsParseEntityName(allowReservedWords = true) { + let entity = this.parseIdentifier(allowReservedWords); while (this.eat(16)) { const node = this.startNodeAtNode(entity); @@ -7923,9 +8565,9 @@ tsParseTypeReference() { const node = this.startNode(); - node.typeName = this.tsParseEntityName(false); + node.typeName = this.tsParseEntityName(); - if (!this.hasPrecedingLineBreak() && this.isRelational("<")) { + if (!this.hasPrecedingLineBreak() && this.match(47)) { node.typeParameters = this.tsParseTypeArguments(); } @@ -7949,12 +8591,12 @@ tsParseTypeQuery() { const node = this.startNode(); - this.expect(78); + this.expect(87); - if (this.match(74)) { + if (this.match(83)) { node.exprName = this.tsParseImportType(); } else { - node.exprName = this.tsParseEntityName(true); + node.exprName = this.tsParseEntityName(); } return this.finishNode(node, "TSTypeQuery"); @@ -7963,13 +8605,13 @@ tsParseTypeParameter() { const node = this.startNode(); node.name = this.tsParseTypeParameterName(); - node.constraint = this.tsEatThenParseType(72); - node.default = this.tsEatThenParseType(27); + node.constraint = this.tsEatThenParseType(81); + node.default = this.tsEatThenParseType(29); return this.finishNode(node, "TSTypeParameter"); } tsTryParseTypeParameters() { - if (this.isRelational("<")) { + if (this.match(47)) { return this.tsParseTypeParameters(); } } @@ -7977,47 +8619,67 @@ tsParseTypeParameters() { const node = this.startNode(); - if (this.isRelational("<") || this.match(129)) { + if (this.match(47) || this.match(138)) { this.next(); } else { this.unexpected(); } - node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this), false, true); + const refTrailingCommaPos = { + value: -1 + }; + node.params = this.tsParseBracketedList("TypeParametersOrArguments", this.tsParseTypeParameter.bind(this), false, true, refTrailingCommaPos); if (node.params.length === 0) { - this.raise(node.start, TSErrors.EmptyTypeParameters); + this.raise(TSErrors.EmptyTypeParameters, { + at: node + }); + } + + if (refTrailingCommaPos.value !== -1) { + this.addExtra(node, "trailingComma", refTrailingCommaPos.value); } return this.finishNode(node, "TSTypeParameterDeclaration"); } tsTryNextParseConstantContext() { - if (this.lookahead().type === 66) { - this.next(); - return this.tsParseTypeReference(); + if (this.lookahead().type !== 75) return null; + this.next(); + const typeReference = this.tsParseTypeReference(); + + if (typeReference.typeParameters) { + this.raise(TSErrors.CannotFindName, { + at: typeReference.typeName, + name: "const" + }); } - return null; + return typeReference; } tsFillSignature(returnToken, signature) { const returnTokenRequired = returnToken === 19; + const paramsKey = "parameters"; + const returnTypeKey = "typeAnnotation"; signature.typeParameters = this.tsTryParseTypeParameters(); this.expect(10); - signature.parameters = this.tsParseBindingListForSignature(); + signature[paramsKey] = this.tsParseBindingListForSignature(); if (returnTokenRequired) { - signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); + signature[returnTypeKey] = this.tsParseTypeOrTypePredicateAnnotation(returnToken); } else if (this.match(returnToken)) { - signature.typeAnnotation = this.tsParseTypeOrTypePredicateAnnotation(returnToken); + signature[returnTypeKey] = this.tsParseTypeOrTypePredicateAnnotation(returnToken); } } tsParseBindingListForSignature() { return this.parseBindingList(11, 41).map(pattern => { if (pattern.type !== "Identifier" && pattern.type !== "RestElement" && pattern.type !== "ObjectPattern" && pattern.type !== "ArrayPattern") { - this.raise(pattern.start, TSErrors.UnsupportedSignatureParameterKind, pattern.type); + this.raise(TSErrors.UnsupportedSignatureParameterKind, { + at: pattern, + type: pattern.type + }); } return pattern; @@ -8068,49 +8730,69 @@ if (this.eat(17)) node.optional = true; const nodeAny = node; - if (this.match(10) || this.isRelational("<")) { + if (this.match(10) || this.match(47)) { if (readonly) { - this.raise(node.start, TSErrors.ReadonlyForMethodSignature); + this.raise(TSErrors.ReadonlyForMethodSignature, { + at: node + }); } const method = nodeAny; - if (method.kind && this.isRelational("<")) { - this.raise(this.state.pos, TSErrors.AccesorCannotHaveTypeParameters); + if (method.kind && this.match(47)) { + this.raise(TSErrors.AccesorCannotHaveTypeParameters, { + at: this.state.curPosition() + }); } this.tsFillSignature(14, method); this.tsParseTypeMemberSemicolon(); + const paramsKey = "parameters"; + const returnTypeKey = "typeAnnotation"; if (method.kind === "get") { - if (method.parameters.length > 0) { - this.raise(this.state.pos, ErrorMessages.BadGetterArity); + if (method[paramsKey].length > 0) { + this.raise(Errors.BadGetterArity, { + at: this.state.curPosition() + }); - if (this.isThisParam(method.parameters[0])) { - this.raise(this.state.pos, TSErrors.AccesorCannotDeclareThisParameter); + if (this.isThisParam(method[paramsKey][0])) { + this.raise(TSErrors.AccesorCannotDeclareThisParameter, { + at: this.state.curPosition() + }); } } } else if (method.kind === "set") { - if (method.parameters.length !== 1) { - this.raise(this.state.pos, ErrorMessages.BadSetterArity); + if (method[paramsKey].length !== 1) { + this.raise(Errors.BadSetterArity, { + at: this.state.curPosition() + }); } else { - const firstParameter = method.parameters[0]; + const firstParameter = method[paramsKey][0]; if (this.isThisParam(firstParameter)) { - this.raise(this.state.pos, TSErrors.AccesorCannotDeclareThisParameter); + this.raise(TSErrors.AccesorCannotDeclareThisParameter, { + at: this.state.curPosition() + }); } if (firstParameter.type === "Identifier" && firstParameter.optional) { - this.raise(this.state.pos, TSErrors.SetAccesorCannotHaveOptionalParameter); + this.raise(TSErrors.SetAccesorCannotHaveOptionalParameter, { + at: this.state.curPosition() + }); } if (firstParameter.type === "RestElement") { - this.raise(this.state.pos, TSErrors.SetAccesorCannotHaveRestParameter); + this.raise(TSErrors.SetAccesorCannotHaveRestParameter, { + at: this.state.curPosition() + }); } } - if (method.typeAnnotation) { - this.raise(method.typeAnnotation.start, TSErrors.SetAccesorCannotHaveReturnType); + if (method[returnTypeKey]) { + this.raise(TSErrors.SetAccesorCannotHaveReturnType, { + at: method[returnTypeKey] + }); } } else { method.kind = "method"; @@ -8130,15 +8812,15 @@ tsParseTypeMember() { const node = this.startNode(); - if (this.match(10) || this.isRelational("<")) { + if (this.match(10) || this.match(47)) { return this.tsParseSignatureMember("TSCallSignatureDeclaration", node); } - if (this.match(68)) { + if (this.match(77)) { const id = this.startNode(); this.next(); - if (this.match(10) || this.isRelational("<")) { + if (this.match(10) || this.match(47)) { return this.tsParseSignatureMember("TSConstructSignatureDeclaration", node); } else { node.key = this.createIdentifier(id, "new"); @@ -8146,18 +8828,22 @@ } } - this.tsParseModifiers(node, ["readonly"], ["declare", "abstract", "private", "protected", "public", "static", "override"], TSErrors.InvalidModifierOnTypeMember); + this.tsParseModifiers({ + modified: node, + allowedModifiers: ["readonly"], + disallowedModifiers: ["declare", "abstract", "private", "protected", "public", "static", "override"] + }); const idx = this.tsTryParseIndexSignature(node); if (idx) { return idx; } - this.parsePropertyName(node, false); + this.parsePropertyName(node); if (!node.computed && node.key.type === "Identifier" && (node.key.name === "get" || node.key.name === "set") && this.tsTokenCanFollowModifier()) { node.kind = node.key.name; - this.parsePropertyName(node, false); + this.parsePropertyName(node); } return this.tsParsePropertyOrMethodSignature(node, !!node.readonly); @@ -8179,11 +8865,11 @@ tsIsStartOfMappedType() { this.next(); - if (this.eat(44)) { - return this.isContextual(109); + if (this.eat(53)) { + return this.isContextual(118); } - if (this.isContextual(109)) { + if (this.isContextual(118)) { this.next(); } @@ -8198,13 +8884,13 @@ } this.next(); - return this.match(49); + return this.match(58); } tsParseMappedTypeParameter() { const node = this.startNode(); node.name = this.tsParseTypeParameterName(); - node.constraint = this.tsExpectThenParseType(49); + node.constraint = this.tsExpectThenParseType(58); return this.finishNode(node, "TSTypeParameter"); } @@ -8212,20 +8898,20 @@ const node = this.startNode(); this.expect(5); - if (this.match(44)) { + if (this.match(53)) { node.readonly = this.state.value; this.next(); - this.expectContextual(109); - } else if (this.eatContextual(109)) { + this.expectContextual(118); + } else if (this.eatContextual(118)) { node.readonly = true; } this.expect(0); node.typeParameter = this.tsParseMappedTypeParameter(); - node.nameType = this.eatContextual(84) ? this.tsParseType() : null; + node.nameType = this.eatContextual(93) ? this.tsParseType() : null; this.expect(3); - if (this.match(44)) { + if (this.match(53)) { node.optional = this.state.value; this.next(); this.expect(17); @@ -8252,7 +8938,9 @@ } = elementNode; if (seenOptionalElement && type !== "TSRestType" && type !== "TSOptionalType" && !(type === "TSNamedTupleMember" && elementNode.optional)) { - this.raise(elementNode.start, TSErrors.OptionalTypeBeforeRequired); + this.raise(TSErrors.OptionalTypeBeforeRequired, { + at: elementNode + }); } seenOptionalElement = seenOptionalElement || type === "TSNamedTupleMember" && elementNode.optional || type === "TSOptionalType"; @@ -8266,7 +8954,9 @@ labeledElements = (_labeledElements = labeledElements) != null ? _labeledElements : isLabeled; if (labeledElements !== isLabeled) { - this.raise(elementNode.start, TSErrors.MixedLabeledAndUnlabeledElements); + this.raise(TSErrors.MixedLabeledAndUnlabeledElements, { + at: elementNode + }); } }); return this.finishNode(node, "TSTupleType"); @@ -8289,7 +8979,9 @@ if (type.type === "TSTypeReference" && !type.typeParameters && type.typeName.type === "Identifier") { labeledNode.label = type.typeName; } else { - this.raise(type.start, TSErrors.InvalidTupleMemberLabel); + this.raise(TSErrors.InvalidTupleMemberLabel, { + at: type + }); labeledNode.label = type; } @@ -8336,11 +9028,11 @@ node.literal = (() => { switch (this.state.type) { - case 121: - case 122: - case 120: - case 76: - case 77: + case 130: + case 131: + case 129: + case 85: + case 86: return this.parseExprAtom(); default: @@ -8365,7 +9057,7 @@ tsParseThisTypeOrThisTypePredicate() { const thisKeyword = this.tsParseThisTypeNode(); - if (this.isContextual(104) && !this.hasPrecedingLineBreak()) { + if (this.isContextual(113) && !this.hasPrecedingLineBreak()) { return this.tsParseThisTypePredicate(thisKeyword); } else { return thisKeyword; @@ -8374,19 +9066,19 @@ tsParseNonArrayType() { switch (this.state.type) { - case 120: - case 121: - case 122: - case 76: - case 77: + case 129: + case 130: + case 131: + case 85: + case 86: return this.tsParseLiteralTypeNode(); - case 44: + case 53: if (this.state.value === "-") { const node = this.startNode(); const nextToken = this.lookahead(); - if (nextToken.type !== 121 && nextToken.type !== 122) { + if (nextToken.type !== 130 && nextToken.type !== 131) { throw this.unexpected(); } @@ -8396,13 +9088,13 @@ break; - case 69: + case 78: return this.tsParseThisTypeOrThisTypePredicate(); - case 78: + case 87: return this.tsParseTypeQuery(); - case 74: + case 83: return this.tsParseImportType(); case 5: @@ -8414,7 +9106,8 @@ case 10: return this.tsParseParenthesizedType(); - case 22: + case 25: + case 24: return this.tsParseTemplateLiteralType(); default: @@ -8423,8 +9116,8 @@ type } = this.state; - if (tokenIsIdentifier(type) || type === 79 || type === 75) { - const nodeType = type === 79 ? "TSVoidKeyword" : type === 75 ? "TSNullKeyword" : keywordTypeFromName(this.state.value); + if (tokenIsIdentifier(type) || type === 88 || type === 84) { + const nodeType = type === 88 ? "TSVoidKeyword" : type === 84 ? "TSNullKeyword" : keywordTypeFromName(this.state.value); if (nodeType !== undefined && this.lookaheadCharCode() !== 46) { const node = this.startNode(); @@ -8482,13 +9175,15 @@ return; default: - this.raise(node.start, TSErrors.UnexpectedReadonly); + this.raise(TSErrors.UnexpectedReadonly, { + at: node + }); } } tsParseInferType() { const node = this.startNode(); - this.expectContextual(103); + this.expectContextual(112); const typeParameter = this.startNode(); typeParameter.name = this.tsParseTypeParameterName(); node.typeParameter = this.finishNode(typeParameter, "TSTypeParameter"); @@ -8497,7 +9192,7 @@ tsParseTypeOperatorOrHigher() { const isTypeOperator = tokenIsTSTypeOperator(this.state.type) && !this.state.containsEsc; - return isTypeOperator ? this.tsParseTypeOperator() : this.isContextual(103) ? this.tsParseInferType() : this.tsParseArrayTypeOrHigher(); + return isTypeOperator ? this.tsParseTypeOperator() : this.isContextual(112) ? this.tsParseInferType() : this.tsParseArrayTypeOrHigher(); } tsParseUnionOrIntersectionType(kind, parseConstituentType, operator) { @@ -8518,15 +9213,15 @@ } tsParseIntersectionTypeOrHigher() { - return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), 40); + return this.tsParseUnionOrIntersectionType("TSIntersectionType", this.tsParseTypeOperatorOrHigher.bind(this), 45); } tsParseUnionTypeOrHigher() { - return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), 38); + return this.tsParseUnionOrIntersectionType("TSUnionType", this.tsParseIntersectionTypeOrHigher.bind(this), 43); } tsIsStartOfFunctionType() { - if (this.isRelational("<")) { + if (this.match(47)) { return true; } @@ -8534,43 +9229,38 @@ } tsSkipParameterStart() { - if (tokenIsIdentifier(this.state.type) || this.match(69)) { + if (tokenIsIdentifier(this.state.type) || this.match(78)) { this.next(); return true; } if (this.match(5)) { - let braceStackCounter = 1; - this.next(); + const { + errors + } = this.state; + const previousErrorCount = errors.length; - while (braceStackCounter > 0) { - if (this.match(5)) { - ++braceStackCounter; - } else if (this.match(8)) { - --braceStackCounter; - } - - this.next(); + try { + this.parseObjectLike(8, true); + return errors.length === previousErrorCount; + } catch (_unused) { + return false; } - - return true; } if (this.match(0)) { - let braceStackCounter = 1; this.next(); + const { + errors + } = this.state; + const previousErrorCount = errors.length; - while (braceStackCounter > 0) { - if (this.match(0)) { - ++braceStackCounter; - } else if (this.match(3)) { - --braceStackCounter; - } - - this.next(); + try { + this.parseBindingList(3, 93, true); + return errors.length === previousErrorCount; + } catch (_unused2) { + return false; } - - return true; } return false; @@ -8584,7 +9274,7 @@ } if (this.tsSkipParameterStart()) { - if (this.match(14) || this.match(12) || this.match(17) || this.match(27)) { + if (this.match(14) || this.match(12) || this.match(17) || this.match(29)) { return true; } @@ -8607,7 +9297,7 @@ const node = this.startNode(); const asserts = !!this.tsTryParse(this.tsParseTypePredicateAsserts.bind(this)); - if (asserts && this.match(69)) { + if (asserts && this.match(78)) { let thisTypePredicate = this.tsParseThisTypeOrThisTypePredicate(); if (thisTypePredicate.type === "TSThisType") { @@ -8662,26 +9352,29 @@ tsParseTypePredicatePrefix() { const id = this.parseIdentifier(); - if (this.isContextual(104) && !this.hasPrecedingLineBreak()) { + if (this.isContextual(113) && !this.hasPrecedingLineBreak()) { this.next(); return id; } } tsParseTypePredicateAsserts() { - if (this.state.type !== 97) { + if (this.state.type !== 106) { return false; } const containsEsc = this.state.containsEsc; this.next(); - if (!tokenIsIdentifier(this.state.type) && !this.match(69)) { + if (!tokenIsIdentifier(this.state.type) && !this.match(78)) { return false; } if (containsEsc) { - this.raise(this.state.lastTokStart, ErrorMessages.InvalidEscapedReservedWord, "asserts"); + this.raise(Errors.InvalidEscapedReservedWord, { + at: this.state.lastTokStartLoc, + reservedWord: "asserts" + }); } return true; @@ -8699,7 +9392,7 @@ assert(this.state.inType); const type = this.tsParseNonConditionalType(); - if (this.hasPrecedingLineBreak() || !this.eat(72)) { + if (this.hasPrecedingLineBreak() || !this.eat(81)) { return type; } @@ -8714,7 +9407,7 @@ } isAbstractConstructorSignature() { - return this.isContextual(111) && this.lookahead().type === 68; + return this.isContextual(120) && this.lookahead().type === 77; } tsParseNonConditionalType() { @@ -8722,7 +9415,7 @@ return this.tsParseFunctionOrConstructorType("TSFunctionType"); } - if (this.match(68)) { + if (this.match(77)) { return this.tsParseFunctionOrConstructorType("TSConstructorType"); } else if (this.isAbstractConstructorSignature()) { return this.tsParseFunctionOrConstructorType("TSConstructorType", true); @@ -8732,22 +9425,31 @@ } tsParseTypeAssertion() { + if (this.getPluginOption("typescript", "disallowAmbiguousJSXLike")) { + this.raise(TSErrors.ReservedTypeAssertion, { + at: this.state.startLoc + }); + } + const node = this.startNode(); const _const = this.tsTryNextParseConstantContext(); node.typeAnnotation = _const || this.tsNextThenParseType(); - this.expectRelational(">"); + this.expect(48); node.expression = this.parseMaybeUnary(); return this.finishNode(node, "TSTypeAssertion"); } - tsParseHeritageClause(descriptor) { - const originalStart = this.state.start; + tsParseHeritageClause(token) { + const originalStartLoc = this.state.startLoc; const delimitedList = this.tsParseDelimitedList("HeritageClauseElement", this.tsParseExpressionWithTypeArguments.bind(this)); if (!delimitedList.length) { - this.raise(originalStart, TSErrors.EmptyHeritageClauseType, descriptor); + this.raise(TSErrors.EmptyHeritageClauseType, { + at: originalStartLoc, + token + }); } return delimitedList; @@ -8755,27 +9457,33 @@ tsParseExpressionWithTypeArguments() { const node = this.startNode(); - node.expression = this.tsParseEntityName(false); + node.expression = this.tsParseEntityName(); - if (this.isRelational("<")) { + if (this.match(47)) { node.typeParameters = this.tsParseTypeArguments(); } return this.finishNode(node, "TSExpressionWithTypeArguments"); } - tsParseInterfaceDeclaration(node) { + tsParseInterfaceDeclaration(node, properties = {}) { + if (this.hasFollowingLineBreak()) return null; + this.expectContextual(125); + if (properties.declare) node.declare = true; + if (tokenIsIdentifier(this.state.type)) { node.id = this.parseIdentifier(); - this.checkLVal(node.id, "typescript interface declaration", BIND_TS_INTERFACE); + this.checkIdentifier(node.id, BIND_TS_INTERFACE); } else { node.id = null; - this.raise(this.state.start, TSErrors.MissingInterfaceName); + this.raise(TSErrors.MissingInterfaceName, { + at: this.state.startLoc + }); } node.typeParameters = this.tsTryParseTypeParameters(); - if (this.eat(72)) { + if (this.eat(81)) { node.extends = this.tsParseHeritageClause("extends"); } @@ -8787,12 +9495,12 @@ tsParseTypeAliasDeclaration(node) { node.id = this.parseIdentifier(); - this.checkLVal(node.id, "typescript type alias", BIND_TS_TYPE); - node.typeParameters = this.tsTryParseTypeParameters(); + this.checkIdentifier(node.id, BIND_TS_TYPE); node.typeAnnotation = this.tsInType(() => { - this.expect(27); + node.typeParameters = this.tsTryParseTypeParameters(); + this.expect(29); - if (this.isContextual(102) && this.lookahead().type !== 16) { + if (this.isContextual(111) && this.lookahead().type !== 16) { const node = this.startNode(); this.next(); return this.finishNode(node, "TSIntrinsicKeyword"); @@ -8847,19 +9555,21 @@ tsParseEnumMember() { const node = this.startNode(); - node.id = this.match(120) ? this.parseExprAtom() : this.parseIdentifier(true); + node.id = this.match(129) ? this.parseExprAtom() : this.parseIdentifier(true); - if (this.eat(27)) { + if (this.eat(29)) { node.initializer = this.parseMaybeAssignAllowIn(); } return this.finishNode(node, "TSEnumMember"); } - tsParseEnumDeclaration(node, isConst) { - if (isConst) node.const = true; + tsParseEnumDeclaration(node, properties = {}) { + if (properties.const) node.const = true; + if (properties.declare) node.declare = true; + this.expectContextual(122); node.id = this.parseIdentifier(); - this.checkLVal(node.id, "typescript enum declaration", isConst ? BIND_TS_CONST_ENUM : BIND_TS_ENUM); + this.checkIdentifier(node.id, node.const ? BIND_TS_CONST_ENUM : BIND_TS_ENUM); this.expect(5); node.members = this.tsParseDelimitedList("EnumMembers", this.tsParseEnumMember.bind(this)); this.expect(8); @@ -8879,7 +9589,7 @@ node.id = this.parseIdentifier(); if (!nested) { - this.checkLVal(node.id, "module or namespace declaration", BIND_TS_NAMESPACE); + this.checkIdentifier(node.id, BIND_TS_NAMESPACE); } if (this.eat(16)) { @@ -8898,10 +9608,10 @@ } tsParseAmbientExternalModuleDeclaration(node) { - if (this.isContextual(100)) { + if (this.isContextual(109)) { node.global = true; node.id = this.parseIdentifier(); - } else if (this.match(120)) { + } else if (this.match(129)) { node.id = this.parseExprAtom(); } else { this.unexpected(); @@ -8923,12 +9633,14 @@ tsParseImportEqualsDeclaration(node, isExport) { node.isExport = isExport || false; node.id = this.parseIdentifier(); - this.checkLVal(node.id, "import equals declaration", BIND_LEXICAL); - this.expect(27); + this.checkIdentifier(node.id, BIND_LEXICAL); + this.expect(29); const moduleReference = this.tsParseModuleReference(); if (node.importKind === "type" && moduleReference.type !== "TSExternalModuleReference") { - this.raise(moduleReference.start, TSErrors.ImportAliasHasImportType); + this.raise(TSErrors.ImportAliasHasImportType, { + at: moduleReference + }); } node.moduleReference = moduleReference; @@ -8937,7 +9649,7 @@ } tsIsExternalModuleReference() { - return this.isContextual(107) && this.lookaheadCharCode() === 40; + return this.isContextual(116) && this.lookaheadCharCode() === 40; } tsParseModuleReference() { @@ -8946,10 +9658,10 @@ tsParseExternalModuleReference() { const node = this.startNode(); - this.expectContextual(107); + this.expectContextual(116); this.expect(10); - if (!this.match(120)) { + if (!this.match(129)) { throw this.unexpected(); } @@ -8992,41 +9704,54 @@ let starttype = this.state.type; let kind; - if (this.isContextual(90)) { - starttype = 65; + if (this.isContextual(99)) { + starttype = 74; kind = "let"; } return this.tsInAmbientContext(() => { - switch (starttype) { - case 59: + if (starttype === 68) { + nany.declare = true; + return this.parseFunctionStatement(nany, false, true); + } + + if (starttype === 80) { + nany.declare = true; + return this.parseClass(nany, true, false); + } + + if (starttype === 122) { + return this.tsParseEnumDeclaration(nany, { + declare: true + }); + } + + if (starttype === 109) { + return this.tsParseAmbientExternalModuleDeclaration(nany); + } + + if (starttype === 75 || starttype === 74) { + if (!this.match(75) || !this.isLookaheadContextual("enum")) { nany.declare = true; - return this.parseFunctionStatement(nany, false, true); + return this.parseVarStatement(nany, kind || this.state.value, true); + } - case 71: - nany.declare = true; - return this.parseClass(nany, true, false); + this.expect(75); + return this.tsParseEnumDeclaration(nany, { + const: true, + declare: true + }); + } - case 66: - if (this.match(66) && this.isLookaheadContextual("enum")) { - this.expect(66); - this.expectContextual(113); - return this.tsParseEnumDeclaration(nany, true); - } + if (starttype === 125) { + const result = this.tsParseInterfaceDeclaration(nany, { + declare: true + }); + if (result) return result; + } - case 65: - kind = kind || this.state.value; - return this.parseVarStatement(nany, kind); - - case 100: - return this.tsParseAmbientExternalModuleDeclaration(nany); - - default: - { - if (tokenIsIdentifier(starttype)) { - return this.tsParseDeclaration(nany, this.state.value, true); - } - } + if (tokenIsIdentifier(starttype)) { + return this.tsParseDeclaration(nany, this.state.value, true); } }); } @@ -9072,30 +9797,15 @@ tsParseDeclaration(node, value, next) { switch (value) { case "abstract": - if (this.tsCheckLineTerminator(next) && (this.match(71) || tokenIsIdentifier(this.state.type))) { + if (this.tsCheckLineTerminator(next) && (this.match(80) || tokenIsIdentifier(this.state.type))) { return this.tsParseAbstractDeclaration(node); - } - - break; - - case "enum": - if (next || tokenIsIdentifier(this.state.type)) { - if (next) this.next(); - return this.tsParseEnumDeclaration(node, false); - } - - break; - - case "interface": - if (this.tsCheckLineTerminator(next) && tokenIsIdentifier(this.state.type)) { - return this.tsParseInterfaceDeclaration(node); } break; case "module": if (this.tsCheckLineTerminator(next)) { - if (this.match(120)) { + if (this.match(129)) { return this.tsParseAmbientExternalModuleDeclaration(node); } else if (tokenIsIdentifier(this.state.type)) { return this.tsParseModuleOrNamespaceDeclaration(node); @@ -9131,7 +9841,7 @@ } tsTryParseGenericAsyncArrowFunction(startPos, startLoc) { - if (!this.isRelational("<")) { + if (!this.match(47)) { return undefined; } @@ -9154,18 +9864,28 @@ return this.parseArrowExpression(res, null, true); } + tsParseTypeArgumentsInExpression() { + if (this.reScan_lt() !== 47) { + return undefined; + } + + return this.tsParseTypeArguments(); + } + tsParseTypeArguments() { const node = this.startNode(); node.params = this.tsInType(() => this.tsInNoContext(() => { - this.expectRelational("<"); + this.expect(47); return this.tsParseDelimitedList("TypeParametersOrArguments", this.tsParseType.bind(this)); })); if (node.params.length === 0) { - this.raise(node.start, TSErrors.EmptyTypeArguments); + this.raise(TSErrors.EmptyTypeArguments, { + at: node + }); } - this.expectRelational(">"); + this.expect(48); return this.finishNode(node, "TSTypeParameterInstantiation"); } @@ -9187,13 +9907,18 @@ if (allowModifiers !== undefined) { const modified = {}; - this.tsParseModifiers(modified, ["public", "private", "protected", "override", "readonly"]); + this.tsParseModifiers({ + modified, + allowedModifiers: ["public", "private", "protected", "override", "readonly"] + }); accessibility = modified.accessibility; override = modified.override; readonly = modified.readonly; if (allowModifiers === false && (accessibility || readonly || override)) { - this.raise(startPos, TSErrors.UnexpectedParameterModifier); + this.raise(TSErrors.UnexpectedParameterModifier, { + at: startLoc + }); } } @@ -9213,7 +9938,9 @@ if (override) pp.override = override; if (elt.type !== "Identifier" && elt.type !== "AssignmentPattern") { - this.raise(pp.start, TSErrors.UnsupportedParameterPropertyKind); + this.raise(TSErrors.UnsupportedParameterPropertyKind, { + at: pp + }); } pp.parameter = elt; @@ -9227,12 +9954,16 @@ return elt; } + isSimpleParameter(node) { + return node.type === "TSParameterProperty" && super.isSimpleParameter(node.parameter) || super.isSimpleParameter(node); + } + parseFunctionBodyAndFinish(node, type, isMethod = false) { if (this.match(14)) { node.returnType = this.tsParseTypeOrTypePredicateAnnotation(14); } - const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" ? "TSDeclareMethod" : undefined; + const bodilessType = type === "FunctionDeclaration" ? "TSDeclareFunction" : type === "ClassMethod" || type === "ClassPrivateMethod" ? "TSDeclareMethod" : undefined; if (bodilessType && !this.match(5) && this.isLineTerminator()) { this.finishNode(node, bodilessType); @@ -9240,7 +9971,9 @@ } if (bodilessType === "TSDeclareFunction" && this.state.isAmbientContext) { - this.raise(node.start, TSErrors.DeclareFunctionHasImplementation); + this.raise(TSErrors.DeclareFunctionHasImplementation, { + at: node + }); if (node.declare) { super.parseFunctionBodyAndFinish(node, bodilessType, isMethod); @@ -9253,7 +9986,7 @@ registerFunctionStatementId(node) { if (!node.body && node.id) { - this.checkLVal(node.id, "function name", BIND_TS_AMBIENT); + this.checkIdentifier(node.id, BIND_TS_AMBIENT); } else { super.registerFunctionStatementId(...arguments); } @@ -9262,7 +9995,9 @@ tsCheckForInvalidTypeCasts(items) { items.forEach(node => { if ((node == null ? void 0 : node.type) === "TSTypeCastExpression") { - this.raise(node.typeAnnotation.start, TSErrors.UnexpectedTypeAnnotation); + this.raise(TSErrors.UnexpectedTypeAnnotation, { + at: node.typeAnnotation + }); } }); } @@ -9283,8 +10018,8 @@ } parseSubscript(base, startPos, startLoc, noCalls, state) { - if (!this.hasPrecedingLineBreak() && this.match(32)) { - this.state.exprAllowed = false; + if (!this.hasPrecedingLineBreak() && this.match(35)) { + this.state.canStartJSXElement = false; this.next(); const nonNullExpression = this.startNodeAt(startPos, startLoc); nonNullExpression.expression = base; @@ -9303,8 +10038,8 @@ this.next(); } - if (this.isRelational("<")) { - let missingParenErrorPos; + if (this.match(47) || this.match(51)) { + let missingParenErrorLoc; const result = this.tsTryParseAndCatch(() => { if (!noCalls && this.atPossibleAsyncArrow(base)) { const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(startPos, startLoc); @@ -9316,11 +10051,11 @@ const node = this.startNodeAt(startPos, startLoc); node.callee = base; - const typeArguments = this.tsParseTypeArguments(); + const typeArguments = this.tsParseTypeArgumentsInExpression(); if (typeArguments) { if (isOptionalCall && !this.match(10)) { - missingParenErrorPos = this.state.pos; + missingParenErrorLoc = this.state.curPosition(); this.unexpected(); } @@ -9334,7 +10069,7 @@ } return this.finishCallExpression(node, state.optionalChainMember); - } else if (this.match(22)) { + } else if (tokenIsTemplate(this.state.type)) { const result = this.parseTaggedTemplateExpression(base, startPos, startLoc, state); result.typeParameters = typeArguments; return result; @@ -9344,8 +10079,8 @@ this.unexpected(); }); - if (missingParenErrorPos) { - this.unexpected(missingParenErrorPos, 10); + if (missingParenErrorLoc) { + this.unexpected(missingParenErrorLoc, 10); } if (result) return result; @@ -9355,9 +10090,9 @@ } parseNewArguments(node) { - if (this.isRelational("<")) { + if (this.match(47) || this.match(51)) { const typeParameters = this.tsTryParseAndCatch(() => { - const args = this.tsParseTypeArguments(); + const args = this.tsParseTypeArgumentsInExpression(); if (!this.match(10)) this.unexpected(); return args; }); @@ -9371,7 +10106,7 @@ } parseExprOp(left, leftStartPos, leftStartLoc, minPrec) { - if (tokenOperatorPrecedence(49) > minPrec && !this.hasPrecedingLineBreak() && this.isContextual(84)) { + if (tokenOperatorPrecedence(58) > minPrec && !this.hasPrecedingLineBreak() && this.isContextual(93)) { const node = this.startNodeAt(leftStartPos, leftStartLoc); node.expression = left; @@ -9391,23 +10126,27 @@ return super.parseExprOp(left, leftStartPos, leftStartLoc, minPrec); } - checkReservedWord(word, startLoc, checkKeywords, isBinding) {} + checkReservedWord(word, startLoc, checkKeywords, isBinding) { + if (!this.state.isAmbientContext) { + super.checkReservedWord(word, startLoc, checkKeywords, isBinding); + } + } checkDuplicateExports() {} parseImport(node) { node.importKind = "value"; - if (tokenIsIdentifier(this.state.type) || this.match(46) || this.match(5)) { + if (tokenIsIdentifier(this.state.type) || this.match(55) || this.match(5)) { let ahead = this.lookahead(); - if (this.isContextual(117) && ahead.type !== 12 && ahead.type !== 88 && ahead.type !== 27) { + if (this.isContextual(126) && ahead.type !== 12 && ahead.type !== 97 && ahead.type !== 29) { node.importKind = "type"; this.next(); ahead = this.lookahead(); } - if (tokenIsIdentifier(this.state.type) && ahead.type === 27) { + if (tokenIsIdentifier(this.state.type) && ahead.type === 29) { return this.tsParseImportEqualsDeclaration(node); } } @@ -9415,17 +10154,19 @@ const importNode = super.parseImport(node); if (importNode.importKind === "type" && importNode.specifiers.length > 1 && importNode.specifiers[0].type === "ImportDefaultSpecifier") { - this.raise(importNode.start, TSErrors.TypeImportCannotSpecifyDefaultAndNamed); + this.raise(TSErrors.TypeImportCannotSpecifyDefaultAndNamed, { + at: importNode + }); } return importNode; } parseExport(node) { - if (this.match(74)) { + if (this.match(83)) { this.next(); - if (this.isContextual(117) && this.lookaheadCharCode() !== 61) { + if (this.isContextual(126) && this.lookaheadCharCode() !== 61) { node.importKind = "type"; this.next(); } else { @@ -9433,19 +10174,19 @@ } return this.tsParseImportEqualsDeclaration(node, true); - } else if (this.eat(27)) { + } else if (this.eat(29)) { const assign = node; assign.expression = this.parseExpression(); this.semicolon(); return this.finishNode(assign, "TSExportAssignment"); - } else if (this.eatContextual(84)) { + } else if (this.eatContextual(93)) { const decl = node; - this.expectContextual(115); + this.expectContextual(124); decl.id = this.parseIdentifier(); this.semicolon(); return this.finishNode(decl, "TSNamespaceExportDeclaration"); } else { - if (this.isContextual(117) && this.lookahead().type === 5) { + if (this.isContextual(126) && this.lookahead().type === 5) { this.next(); node.exportKind = "type"; } else { @@ -9457,7 +10198,7 @@ } isAbstractClass() { - return this.isContextual(111) && this.lookahead().type === 71; + return this.isContextual(120) && this.lookahead().type === 80; } parseExportDefaultExpression() { @@ -9469,26 +10210,57 @@ return cls; } - if (this.match(116)) { - const interfaceNode = this.startNode(); - this.next(); - const result = this.tsParseInterfaceDeclaration(interfaceNode); + if (this.match(125)) { + const result = this.tsParseInterfaceDeclaration(this.startNode()); if (result) return result; } return super.parseExportDefaultExpression(); } - parseStatementContent(context, topLevel) { - if (this.state.type === 66) { - const ahead = this.lookahead(); + parseVarStatement(node, kind, allowMissingInitializer = false) { + const { + isAmbientContext + } = this.state; + const declaration = super.parseVarStatement(node, kind, allowMissingInitializer || isAmbientContext); + if (!isAmbientContext) return declaration; - if (ahead.type === 113) { - const node = this.startNode(); - this.next(); - this.expectContextual(113); - return this.tsParseEnumDeclaration(node, true); + for (const { + id, + init + } of declaration.declarations) { + if (!init) continue; + + if (kind !== "const" || !!id.typeAnnotation) { + this.raise(TSErrors.InitializerNotAllowedInAmbientContext, { + at: init + }); + } else if (init.type !== "StringLiteral" && init.type !== "BooleanLiteral" && init.type !== "NumericLiteral" && init.type !== "BigIntLiteral" && (init.type !== "TemplateLiteral" || init.expressions.length > 0) && !isPossiblyLiteralEnum(init)) { + this.raise(TSErrors.ConstInitiailizerMustBeStringOrNumericLiteralOrLiteralEnumReference, { + at: init + }); } + } + + return declaration; + } + + parseStatementContent(context, topLevel) { + if (this.match(75) && this.isLookaheadContextual("enum")) { + const node = this.startNode(); + this.expect(75); + return this.tsParseEnumDeclaration(node, { + const: true + }); + } + + if (this.isContextual(122)) { + return this.tsParseEnumDeclaration(this.startNode()); + } + + if (this.isContextual(125)) { + const result = this.tsParseInterfaceDeclaration(this.startNode()); + if (result) return result; } return super.parseStatementContent(context, topLevel); @@ -9509,12 +10281,16 @@ } tsIsStartOfStaticBlocks() { - return this.isContextual(95) && this.lookaheadCharCode() === 123; + return this.isContextual(104) && this.lookaheadCharCode() === 123; } parseClassMember(classBody, member, state) { const modifiers = ["declare", "private", "public", "protected", "override", "abstract", "readonly", "static"]; - this.tsParseModifiers(member, modifiers, undefined, undefined, true); + this.tsParseModifiers({ + modified: member, + allowedModifiers: modifiers, + stopOnStartOfClassStaticBlock: true + }); const callParseClassMemberWithIsStatic = () => { if (this.tsIsStartOfStaticBlocks()) { @@ -9522,7 +10298,9 @@ this.next(); if (this.tsHasSomeModifiers(member, modifiers)) { - this.raise(this.state.pos, TSErrors.StaticBlockCannotHaveModifier); + this.raise(TSErrors.StaticBlockCannotHaveModifier, { + at: this.state.curPosition() + }); } this.parseClassStaticBlock(classBody, member); @@ -9545,31 +10323,44 @@ classBody.body.push(idx); if (member.abstract) { - this.raise(member.start, TSErrors.IndexSignatureHasAbstract); + this.raise(TSErrors.IndexSignatureHasAbstract, { + at: member + }); } if (member.accessibility) { - this.raise(member.start, TSErrors.IndexSignatureHasAccessibility, member.accessibility); + this.raise(TSErrors.IndexSignatureHasAccessibility, { + at: member, + modifier: member.accessibility + }); } if (member.declare) { - this.raise(member.start, TSErrors.IndexSignatureHasDeclare); + this.raise(TSErrors.IndexSignatureHasDeclare, { + at: member + }); } if (member.override) { - this.raise(member.start, TSErrors.IndexSignatureHasOverride); + this.raise(TSErrors.IndexSignatureHasOverride, { + at: member + }); } return; } if (!this.state.inAbstractClass && member.abstract) { - this.raise(member.start, TSErrors.NonAbstractClassHasAbstractMethod); + this.raise(TSErrors.NonAbstractClassHasAbstractMethod, { + at: member + }); } if (member.override) { if (!state.hadSuperClass) { - this.raise(member.start, TSErrors.OverrideNotInSubClass); + this.raise(TSErrors.OverrideNotInSubClass, { + at: member + }); } } @@ -9581,11 +10372,15 @@ if (optional) methodOrProp.optional = true; if (methodOrProp.readonly && this.match(10)) { - this.raise(methodOrProp.start, TSErrors.ClassMethodHasReadonly); + this.raise(TSErrors.ClassMethodHasReadonly, { + at: methodOrProp + }); } if (methodOrProp.declare && this.match(10)) { - this.raise(methodOrProp.start, TSErrors.ClassMethodHasDeclare); + this.raise(TSErrors.ClassMethodHasDeclare, { + at: methodOrProp + }); } } @@ -9637,29 +10432,29 @@ } parseExportDeclaration(node) { + if (!this.state.isAmbientContext && this.isContextual(121)) { + return this.tsInAmbientContext(() => this.parseExportDeclaration(node)); + } + const startPos = this.state.start; const startLoc = this.state.startLoc; - const isDeclare = this.eatContextual(112); + const isDeclare = this.eatContextual(121); - if (isDeclare && (this.isContextual(112) || !this.shouldParseExportDeclaration())) { - throw this.raise(this.state.start, TSErrors.ExpectedAmbientAfterExportDeclare); + if (isDeclare && (this.isContextual(121) || !this.shouldParseExportDeclaration())) { + throw this.raise(TSErrors.ExpectedAmbientAfterExportDeclare, { + at: this.state.startLoc + }); } - let declaration; + const isIdentifier = tokenIsIdentifier(this.state.type); + const declaration = isIdentifier && this.tsTryParseExportDeclaration() || super.parseExportDeclaration(node); + if (!declaration) return null; - if (tokenIsIdentifier(this.state.type)) { - declaration = this.tsTryParseExportDeclaration(); - } - - if (!declaration) { - declaration = super.parseExportDeclaration(node); - } - - if (declaration && (declaration.type === "TSInterfaceDeclaration" || declaration.type === "TSTypeAliasDeclaration" || isDeclare)) { + if (declaration.type === "TSInterfaceDeclaration" || declaration.type === "TSTypeAliasDeclaration" || isDeclare) { node.exportKind = "type"; } - if (declaration && isDeclare) { + if (isDeclare) { this.resetStartLocation(declaration, startPos, startLoc); declaration.declare = true; } @@ -9668,7 +10463,7 @@ } parseClassId(node, isStatement, optionalId) { - if ((!isStatement || optionalId) && this.isContextual(101)) { + if ((!isStatement || optionalId) && this.isContextual(110)) { return; } @@ -9678,7 +10473,7 @@ } parseClassPropertyAnnotation(node) { - if (!node.optional && this.eat(32)) { + if (!node.optional && this.eat(35)) { node.definite = true; } @@ -9689,15 +10484,20 @@ parseClassProperty(node) { this.parseClassPropertyAnnotation(node); - if (this.state.isAmbientContext && this.match(27)) { - this.raise(this.state.start, TSErrors.DeclareClassFieldHasInitializer); + if (this.state.isAmbientContext && this.match(29)) { + this.raise(TSErrors.DeclareClassFieldHasInitializer, { + at: this.state.startLoc + }); } - if (node.abstract && this.match(27)) { + if (node.abstract && this.match(29)) { const { key } = node; - this.raise(this.state.start, TSErrors.AbstractPropertyHasInitializer, key.type === "Identifier" && !node.computed ? key.name : `[${this.input.slice(key.start, key.end)}]`); + this.raise(TSErrors.AbstractPropertyHasInitializer, { + at: this.state.startLoc, + propertyName: key.type === "Identifier" && !node.computed ? key.name : `[${this.input.slice(key.start, key.end)}]` + }); } return super.parseClassProperty(node); @@ -9705,11 +10505,16 @@ parseClassPrivateProperty(node) { if (node.abstract) { - this.raise(node.start, TSErrors.PrivateElementHasAbstract); + this.raise(TSErrors.PrivateElementHasAbstract, { + at: node + }); } if (node.accessibility) { - this.raise(node.start, TSErrors.PrivateElementHasAccessibility, node.accessibility); + this.raise(TSErrors.PrivateElementHasAccessibility, { + at: node, + modifier: node.accessibility + }); } this.parseClassPropertyAnnotation(node); @@ -9720,11 +10525,21 @@ const typeParameters = this.tsTryParseTypeParameters(); if (typeParameters && isConstructor) { - this.raise(typeParameters.start, TSErrors.ConstructorHasTypeParameters); + this.raise(TSErrors.ConstructorHasTypeParameters, { + at: typeParameters + }); } - if (method.declare && (method.kind === "get" || method.kind === "set")) { - this.raise(method.start, TSErrors.DeclareAccessor, method.kind); + const { + declare = false, + kind + } = method; + + if (declare && (kind === "get" || kind === "set")) { + this.raise(TSErrors.DeclareAccessor, { + at: method, + kind + }); } if (typeParameters) method.typeParameters = typeParameters; @@ -9737,14 +10552,20 @@ super.pushClassPrivateMethod(classBody, method, isGenerator, isAsync); } + declareClassPrivateMethodInScope(node, kind) { + if (node.type === "TSDeclareMethod") return; + if (node.type === "MethodDefinition" && !node.value.body) return; + super.declareClassPrivateMethodInScope(node, kind); + } + parseClassSuper(node) { super.parseClassSuper(node); - if (node.superClass && this.isRelational("<")) { - node.superTypeParameters = this.tsParseTypeArguments(); + if (node.superClass && (this.match(47) || this.match(51))) { + node.superTypeParameters = this.tsParseTypeArgumentsInExpression(); } - if (this.eatContextual(101)) { + if (this.eatContextual(110)) { node.implements = this.tsParseHeritageClause("implements"); } } @@ -9764,7 +10585,7 @@ parseVarId(decl, kind) { super.parseVarId(decl, kind); - if (decl.id.type === "Identifier" && this.eat(32)) { + if (decl.id.type === "Identifier" && !this.hasPrecedingLineBreak() && this.eat(35)) { decl.definite = true; } @@ -9791,29 +10612,28 @@ let jsx; let typeCast; - if (this.hasPlugin("jsx") && (this.match(129) || this.isRelational("<"))) { + if (this.hasPlugin("jsx") && (this.match(138) || this.match(47))) { state = this.state.clone(); jsx = this.tryParse(() => super.parseMaybeAssign(...args), state); if (!jsx.error) return jsx.node; const { context } = this.state; + const currentContext = context[context.length - 1]; - if (context[context.length - 1] === types.j_oTag) { - context.length -= 2; - } else if (context[context.length - 1] === types.j_expr) { - context.length -= 1; + if (currentContext === types.j_oTag || currentContext === types.j_expr) { + context.pop(); } } - if (!((_jsx = jsx) != null && _jsx.error) && !this.isRelational("<")) { + if (!((_jsx = jsx) != null && _jsx.error) && !this.match(47)) { return super.parseMaybeAssign(...args); } let typeParameters; state = state || this.state.clone(); const arrow = this.tryParse(abort => { - var _expr$extra, _typeParameters; + var _expr$extra, _typeParameters, _expr$typeParameters$; typeParameters = this.tsParseTypeParameters(); const expr = super.parseMaybeAssign(...args); @@ -9827,9 +10647,20 @@ } expr.typeParameters = typeParameters; + + if (this.hasPlugin("jsx") && expr.typeParameters.params.length === 1 && !((_expr$typeParameters$ = expr.typeParameters.extra) != null && _expr$typeParameters$.trailingComma)) { + const parameter = expr.typeParameters.params[0]; + + if (!parameter.constraint) ; + } + return expr; }, state); - if (!arrow.error && !arrow.aborted) return arrow.node; + + if (!arrow.error && !arrow.aborted) { + if (typeParameters) this.reportReservedArrowTypeParam(typeParameters); + return arrow.node; + } if (!jsx) { assert(!this.hasPlugin("jsx")); @@ -9844,6 +10675,7 @@ if (arrow.node) { this.state = arrow.failState; + if (typeParameters) this.reportReservedArrowTypeParam(typeParameters); return arrow.node; } @@ -9858,8 +10690,18 @@ throw ((_jsx4 = jsx) == null ? void 0 : _jsx4.error) || arrow.error || ((_typeCast3 = typeCast) == null ? void 0 : _typeCast3.error); } + reportReservedArrowTypeParam(node) { + var _node$extra; + + if (node.params.length === 1 && !((_node$extra = node.extra) != null && _node$extra.trailingComma) && this.getPluginOption("typescript", "disallowAmbiguousJSXLike")) { + this.raise(TSErrors.ReservedArrowTypeParam, { + at: node + }); + } + } + parseMaybeUnary(refExpressionErrors) { - if (!this.hasPlugin("jsx") && this.isRelational("<")) { + if (!this.hasPlugin("jsx") && this.match(47)) { return this.tsParseTypeAssertion(); } else { return super.parseMaybeUnary(refExpressionErrors); @@ -9887,7 +10729,9 @@ parseAssignableListItemTypes(param) { if (this.eat(17)) { if (param.type !== "Identifier" && !this.state.isAmbientContext && !this.state.inType) { - this.raise(param.start, TSErrors.PatternIsOptional); + this.raise(TSErrors.PatternIsOptional, { + at: param + }); } param.optional = true; @@ -9914,23 +10758,33 @@ toAssignable(node, isLHS = false) { switch (node.type) { - case "TSTypeCastExpression": - return super.toAssignable(this.typeCastToParameter(node), isLHS); - - case "TSParameterProperty": - return super.toAssignable(node, isLHS); - case "ParenthesizedExpression": - return this.toAssignableParenthesizedExpression(node, isLHS); + this.toAssignableParenthesizedExpression(node, isLHS); + break; case "TSAsExpression": case "TSNonNullExpression": case "TSTypeAssertion": - node.expression = this.toAssignable(node.expression, isLHS); - return node; + if (isLHS) { + this.expressionScope.recordArrowParemeterBindingError(TSErrors.UnexpectedTypeCastInParameter, { + at: node + }); + } else { + this.raise(TSErrors.UnexpectedTypeCastInParameter, { + at: node + }); + } + + this.toAssignable(node.expression, isLHS); + break; + + case "AssignmentExpression": + if (!isLHS && node.left.type === "TSTypeCastExpression") { + node.left = this.typeCastToParameter(node.left); + } default: - return super.toAssignable(node, isLHS); + super.toAssignable(node, isLHS); } } @@ -9940,48 +10794,40 @@ case "TSNonNullExpression": case "TSTypeAssertion": case "ParenthesizedExpression": - node.expression = this.toAssignable(node.expression, isLHS); - return node; + this.toAssignable(node.expression, isLHS); + break; default: - return super.toAssignable(node, isLHS); + super.toAssignable(node, isLHS); } } - checkLVal(expr, contextDescription, ...args) { - var _expr$extra2; - - switch (expr.type) { - case "TSTypeCastExpression": - return; - - case "TSParameterProperty": - this.checkLVal(expr.parameter, "parameter property", ...args); - return; - + checkToRestConversion(node, allowPattern) { + switch (node.type) { case "TSAsExpression": case "TSTypeAssertion": - if (!args[0] && contextDescription !== "parenthesized expression" && !((_expr$extra2 = expr.extra) != null && _expr$extra2.parenthesized)) { - this.raise(expr.start, ErrorMessages.InvalidLhs, contextDescription); - break; - } - - this.checkLVal(expr.expression, "parenthesized expression", ...args); - return; - case "TSNonNullExpression": - this.checkLVal(expr.expression, contextDescription, ...args); - return; + this.checkToRestConversion(node.expression, false); + break; default: - super.checkLVal(expr, contextDescription, ...args); - return; + super.checkToRestConversion(node, allowPattern); } + } + + isValidLVal(type, isUnparenthesizedInAssign, binding) { + return getOwn$1({ + TSTypeCastExpression: true, + TSParameterProperty: "parameter", + TSNonNullExpression: "expression", + TSAsExpression: (binding !== BIND_NONE || !isUnparenthesizedInAssign) && ["expression", true], + TSTypeAssertion: (binding !== BIND_NONE || !isUnparenthesizedInAssign) && ["expression", true] + }, type) || super.isValidLVal(type, isUnparenthesizedInAssign, binding); } parseBindingAtom() { switch (this.state.type) { - case 69: + case 78: return this.parseIdentifier(true); default: @@ -9990,8 +10836,8 @@ } parseMaybeDecoratorArguments(expr) { - if (this.isRelational("<")) { - const typeArguments = this.tsParseTypeArguments(); + if (this.match(47) || this.match(51)) { + const typeArguments = this.tsParseTypeArgumentsInExpression(); if (this.match(10)) { const call = super.parseMaybeDecoratorArguments(expr); @@ -9999,7 +10845,7 @@ return call; } - this.unexpected(this.state.start, 10); + this.unexpected(null, 10); } return super.parseMaybeDecoratorArguments(expr); @@ -10008,76 +10854,89 @@ checkCommaAfterRest(close) { if (this.state.isAmbientContext && this.match(12) && this.lookaheadCharCode() === close) { this.next(); + return false; } else { - super.checkCommaAfterRest(close); + return super.checkCommaAfterRest(close); } } isClassMethod() { - return this.isRelational("<") || super.isClassMethod(); + return this.match(47) || super.isClassMethod(); } isClassProperty() { - return this.match(32) || this.match(14) || super.isClassProperty(); + return this.match(35) || this.match(14) || super.isClassProperty(); } parseMaybeDefault(...args) { const node = super.parseMaybeDefault(...args); if (node.type === "AssignmentPattern" && node.typeAnnotation && node.right.start < node.typeAnnotation.start) { - this.raise(node.typeAnnotation.start, TSErrors.TypeAnnotationAfterAssign); + this.raise(TSErrors.TypeAnnotationAfterAssign, { + at: node.typeAnnotation + }); } return node; } getTokenFromCode(code) { - if (this.state.inType && (code === 62 || code === 60)) { - return this.finishOp(42, 1); - } else { - return super.getTokenFromCode(code); + if (this.state.inType) { + if (code === 62) { + return this.finishOp(48, 1); + } + + if (code === 60) { + return this.finishOp(47, 1); + } } + + return super.getTokenFromCode(code); } reScan_lt_gt() { - if (this.match(42)) { - const code = this.input.charCodeAt(this.state.start); + const { + type + } = this.state; - if (code === 60 || code === 62) { - this.state.pos -= 1; - this.readToken_lt_gt(code); - } + if (type === 47) { + this.state.pos -= 1; + this.readToken_lt(); + } else if (type === 48) { + this.state.pos -= 1; + this.readToken_gt(); } + } + + reScan_lt() { + const { + type + } = this.state; + + if (type === 51) { + this.state.pos -= 2; + this.finishOp(47, 1); + return 47; + } + + return type; } toAssignableList(exprList) { for (let i = 0; i < exprList.length; i++) { const expr = exprList[i]; - if (!expr) continue; - switch (expr.type) { - case "TSTypeCastExpression": - exprList[i] = this.typeCastToParameter(expr); - break; - - case "TSAsExpression": - case "TSTypeAssertion": - if (!this.state.maybeInArrowParameters) { - exprList[i] = this.typeCastToParameter(expr); - } else { - this.raise(expr.start, TSErrors.UnexpectedTypeCastInParameter); - } - - break; + if ((expr == null ? void 0 : expr.type) === "TSTypeCastExpression") { + exprList[i] = this.typeCastToParameter(expr); } } - return super.toAssignableList(...arguments); + super.toAssignableList(...arguments); } typeCastToParameter(node) { node.expression.typeAnnotation = node.typeAnnotation; - this.resetEndLocation(node.expression, node.typeAnnotation.end, node.typeAnnotation.loc.end); + this.resetEndLocation(node.expression, node.typeAnnotation.loc.end); return node.expression; } @@ -10098,8 +10957,8 @@ } jsxParseOpeningElementAfterName(node) { - if (this.isRelational("<")) { - const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArguments()); + if (this.match(47) || this.match(51)) { + const typeArguments = this.tsTryParseAndCatch(() => this.tsParseTypeArgumentsInExpression()); if (typeArguments) node.typeParameters = typeArguments; } @@ -10149,18 +11008,19 @@ } tsParseAbstractDeclaration(node) { - if (this.match(71)) { + if (this.match(80)) { node.abstract = true; return this.parseClass(node, true, false); - } else if (this.isContextual(116)) { + } else if (this.isContextual(125)) { if (!this.hasFollowingLineBreak()) { node.abstract = true; - this.raise(node.start, TSErrors.NonClassMethodPropertyHasAbstractModifer); - this.next(); + this.raise(TSErrors.NonClassMethodPropertyHasAbstractModifer, { + at: node + }); return this.tsParseInterfaceDeclaration(node); } } else { - this.unexpected(null, 71); + this.unexpected(null, 80); } } @@ -10174,7 +11034,10 @@ const { key } = method; - this.raise(method.start, TSErrors.AbstractMethodHasImplementation, key.type === "Identifier" && !method.computed ? key.name : `[${this.input.slice(key.start, key.end)}]`); + this.raise(TSErrors.AbstractMethodHasImplementation, { + at: method, + methodName: key.type === "Identifier" && !method.computed ? key.name : `[${this.input.slice(key.start, key.end)}]` + }); } } @@ -10206,20 +11069,131 @@ return super.getExpression(); } + parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly) { + if (!isString && isMaybeTypeOnly) { + this.parseTypeOnlyImportExportSpecifier(node, false, isInTypeExport); + return this.finishNode(node, "ExportSpecifier"); + } + + node.exportKind = "value"; + return super.parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly); + } + + parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly) { + if (!importedIsString && isMaybeTypeOnly) { + this.parseTypeOnlyImportExportSpecifier(specifier, true, isInTypeOnlyImport); + return this.finishNode(specifier, "ImportSpecifier"); + } + + specifier.importKind = "value"; + return super.parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly); + } + + parseTypeOnlyImportExportSpecifier(node, isImport, isInTypeOnlyImportExport) { + const leftOfAsKey = isImport ? "imported" : "local"; + const rightOfAsKey = isImport ? "local" : "exported"; + let leftOfAs = node[leftOfAsKey]; + let rightOfAs; + let hasTypeSpecifier = false; + let canParseAsKeyword = true; + const loc = leftOfAs.loc.start; + + if (this.isContextual(93)) { + const firstAs = this.parseIdentifier(); + + if (this.isContextual(93)) { + const secondAs = this.parseIdentifier(); + + if (tokenIsKeywordOrIdentifier(this.state.type)) { + hasTypeSpecifier = true; + leftOfAs = firstAs; + rightOfAs = isImport ? this.parseIdentifier() : this.parseModuleExportName(); + canParseAsKeyword = false; + } else { + rightOfAs = secondAs; + canParseAsKeyword = false; + } + } else if (tokenIsKeywordOrIdentifier(this.state.type)) { + canParseAsKeyword = false; + rightOfAs = isImport ? this.parseIdentifier() : this.parseModuleExportName(); + } else { + hasTypeSpecifier = true; + leftOfAs = firstAs; + } + } else if (tokenIsKeywordOrIdentifier(this.state.type)) { + hasTypeSpecifier = true; + + if (isImport) { + leftOfAs = this.parseIdentifier(true); + + if (!this.isContextual(93)) { + this.checkReservedWord(leftOfAs.name, leftOfAs.loc.start, true, true); + } + } else { + leftOfAs = this.parseModuleExportName(); + } + } + + if (hasTypeSpecifier && isInTypeOnlyImportExport) { + this.raise(isImport ? TSErrors.TypeModifierIsUsedInTypeImports : TSErrors.TypeModifierIsUsedInTypeExports, { + at: loc + }); + } + + node[leftOfAsKey] = leftOfAs; + node[rightOfAsKey] = rightOfAs; + const kindKey = isImport ? "importKind" : "exportKind"; + node[kindKey] = hasTypeSpecifier ? "type" : "value"; + + if (canParseAsKeyword && this.eatContextual(93)) { + node[rightOfAsKey] = isImport ? this.parseIdentifier() : this.parseModuleExportName(); + } + + if (!node[rightOfAsKey]) { + node[rightOfAsKey] = cloneIdentifier(node[leftOfAsKey]); + } + + if (isImport) { + this.checkIdentifier(node[rightOfAsKey], BIND_LEXICAL); + } + } + }); -const PlaceHolderErrors = makeErrorTemplates({ - ClassNameIsRequired: "A class name is required." -}, ErrorCodes.SyntaxError); +function isPossiblyLiteralEnum(expression) { + if (expression.type !== "MemberExpression") return false; + const { + computed, + property + } = expression; + + if (computed && property.type !== "StringLiteral" && (property.type !== "TemplateLiteral" || property.expressions.length > 0)) { + return false; + } + + return isUncomputedMemberExpressionChain(expression.object); +} + +function isUncomputedMemberExpressionChain(expression) { + if (expression.type === "Identifier") return true; + if (expression.type !== "MemberExpression") return false; + if (expression.computed) return false; + return isUncomputedMemberExpressionChain(expression.object); +} + +const PlaceholderErrors = ParseErrorEnum`placeholders`(_ => ({ + ClassNameIsRequired: _("A class name is required."), + UnexpectedSpace: _("Unexpected space in placeholder.") +})); var placeholders = (superClass => class extends superClass { parsePlaceholder(expectedNode) { - if (this.match(131)) { + if (this.match(140)) { const node = this.startNode(); this.next(); - this.assertNoSpace("Unexpected space in placeholder."); + this.assertNoSpace(); node.name = super.parseIdentifier(true); - this.assertNoSpace("Unexpected space in placeholder."); - this.expect(131); + this.assertNoSpace(); + this.expect(140); return this.finishPlaceholder(node, expectedNode); } } @@ -10232,7 +11206,7 @@ getTokenFromCode(code) { if (code === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) { - return this.finishOp(131, 2); + return this.finishOp(140, 2); } return super.getTokenFromCode(...arguments); @@ -10254,17 +11228,16 @@ return this.parsePlaceholder("Pattern") || super.parseBindingAtom(...arguments); } - checkLVal(expr) { - if (expr.type !== "Placeholder") super.checkLVal(...arguments); + isValidLVal(type, ...rest) { + return type === "Placeholder" || super.isValidLVal(type, ...rest); } toAssignable(node) { if (node && node.type === "Placeholder" && node.expectedNode === "Expression") { node.expectedNode = "Pattern"; - return node; + } else { + super.toAssignable(...arguments); } - - return super.toAssignable(...arguments); } isLet(context) { @@ -10272,14 +11245,14 @@ return true; } - if (!this.isContextual(90)) { + if (!this.isContextual(99)) { return false; } if (context) return false; const nextToken = this.lookahead(); - if (nextToken.type === 131) { + if (nextToken.type === 140) { return true; } @@ -10325,14 +11298,16 @@ const placeholder = this.parsePlaceholder("Identifier"); if (placeholder) { - if (this.match(72) || this.match(131) || this.match(5)) { + if (this.match(81) || this.match(140) || this.match(5)) { node.id = placeholder; } else if (optionalId || !isStatement) { node.id = null; node.body = this.finishPlaceholder(placeholder, "ClassBody"); return this.finishNode(node, type); } else { - this.unexpected(null, PlaceHolderErrors.ClassNameIsRequired); + throw this.raise(PlaceholderErrors.ClassNameIsRequired, { + at: this.state.startLoc + }); } } else { this.parseClassId(node, isStatement, optionalId); @@ -10347,7 +11322,7 @@ const placeholder = this.parsePlaceholder("Identifier"); if (!placeholder) return super.parseExport(...arguments); - if (!this.isContextual(88) && !this.match(12)) { + if (!this.isContextual(97) && !this.match(12)) { node.specifiers = []; node.source = null; node.declaration = this.finishPlaceholder(placeholder, "Declaration"); @@ -10362,11 +11337,11 @@ } isExportDefaultSpecifier() { - if (this.match(56)) { + if (this.match(65)) { const next = this.nextTokenStart(); if (this.isUnparsedContextual(next, "from")) { - if (this.input.startsWith(tokenLabelName(131), this.nextTokenStartSince(next + 4))) { + if (this.input.startsWith(tokenLabelName(140), this.nextTokenStartSince(next + 4))) { return true; } } @@ -10401,7 +11376,7 @@ if (!placeholder) return super.parseImport(...arguments); node.specifiers = []; - if (!this.isContextual(88) && !this.match(12)) { + if (!this.isContextual(97) && !this.match(12)) { node.source = this.finishPlaceholder(placeholder, "StringLiteral"); this.semicolon(); return this.finishNode(node, "ImportDeclaration"); @@ -10417,7 +11392,7 @@ if (!hasStarImport) this.parseNamedImportSpecifiers(node); } - this.expectContextual(88); + this.expectContextual(97); node.source = this.parseImportSource(); this.semicolon(); return this.finishNode(node, "ImportDeclaration"); @@ -10427,12 +11402,20 @@ return this.parsePlaceholder("StringLiteral") || super.parseImportSource(...arguments); } + assertNoSpace() { + if (this.state.start > this.state.lastTokEndLoc.index) { + this.raise(PlaceholderErrors.UnexpectedSpace, { + at: this.state.lastTokEndLoc + }); + } + } + }); var v8intrinsic = (superClass => class extends superClass { parseV8Intrinsic() { - if (this.match(45)) { - const v8IntrinsicStart = this.state.start; + if (this.match(54)) { + const v8IntrinsicStartLoc = this.state.startLoc; const node = this.startNode(); this.next(); @@ -10446,7 +11429,7 @@ } } - this.unexpected(v8IntrinsicStart); + this.unexpected(v8IntrinsicStartLoc); } } @@ -10456,12 +11439,27 @@ }); -function hasPlugin(plugins, name) { - return plugins.some(plugin => { - if (Array.isArray(plugin)) { - return plugin[0] === name; +function hasPlugin(plugins, expectedConfig) { + const [expectedName, expectedOptions] = typeof expectedConfig === "string" ? [expectedConfig, {}] : expectedConfig; + const expectedKeys = Object.keys(expectedOptions); + const expectedOptionsIsEmpty = expectedKeys.length === 0; + return plugins.some(p => { + if (typeof p === "string") { + return expectedOptionsIsEmpty && p === expectedName; } else { - return plugin === name; + const [pluginName, pluginOptions] = p; + + if (pluginName !== expectedName) { + return false; + } + + for (const key of expectedKeys) { + if (pluginOptions[key] !== expectedOptions[key]) { + return false; + } + } + + return true; } }); } @@ -10481,7 +11479,7 @@ return null; } const PIPELINE_PROPOSALS = ["minimal", "fsharp", "hack", "smart"]; -const TOPIC_TOKENS = ["%", "#"]; +const TOPIC_TOKENS = ["^^", "@@", "^", "%", "#"]; const RECORD_AND_TUPLE_SYNTAX_TYPES = ["hash", "bar"]; function validatePlugins(plugins) { if (hasPlugin(plugins, "decorators")) { @@ -10514,7 +11512,9 @@ throw new Error(`"pipelineOperator" requires "proposal" option whose value must be one of: ${proposalList}.`); } - const tupleSyntaxIsHash = hasPlugin(plugins, "recordAndTuple") && getPluginOption(plugins, "recordAndTuple", "syntaxType") === "hash"; + const tupleSyntaxIsHash = hasPlugin(plugins, ["recordAndTuple", { + syntaxType: "hash" + }]); if (proposal === "hack") { if (hasPlugin(plugins, "placeholders")) { @@ -10577,6 +11577,7 @@ const defaultOptions = { sourceType: "script", sourceFilename: undefined, + startColumn: 0, startLine: 1, allowAwaitOutsideFunction: false, allowReturnOutsideFunction: false, @@ -10601,6 +11602,8 @@ return options; } +const getOwn = (object, key) => Object.hasOwnProperty.call(object, key) && object[key]; + const unwrapParenthesizedExpression = node => { return node.type === "ParenthesizedExpression" ? unwrapParenthesizedExpression(node.expression) : node; }; @@ -10616,12 +11619,18 @@ if (isLHS) { if (parenthesized.type === "Identifier") { - this.expressionScope.recordParenthesizedIdentifierError(node.start, ErrorMessages.InvalidParenthesizedAssignment); + this.expressionScope.recordArrowParemeterBindingError(Errors.InvalidParenthesizedAssignment, { + at: node + }); } else if (parenthesized.type !== "MemberExpression") { - this.raise(node.start, ErrorMessages.InvalidParenthesizedAssignment); + this.raise(Errors.InvalidParenthesizedAssignment, { + at: node + }); } } else { - this.raise(node.start, ErrorMessages.InvalidParenthesizedAssignment); + this.raise(Errors.InvalidParenthesizedAssignment, { + at: node + }); } } @@ -10643,34 +11652,45 @@ const isLast = i === last; this.toAssignableObjectExpressionProp(prop, isLast, isLHS); - if (isLast && prop.type === "RestElement" && (_node$extra2 = node.extra) != null && _node$extra2.trailingComma) { - this.raiseRestNotLast(node.extra.trailingComma); + if (isLast && prop.type === "RestElement" && (_node$extra2 = node.extra) != null && _node$extra2.trailingCommaLoc) { + this.raise(Errors.RestTrailingComma, { + at: node.extra.trailingCommaLoc + }); } } break; case "ObjectProperty": - this.toAssignable(node.value, isLHS); - break; + { + const { + key, + value + } = node; + + if (this.isPrivateName(key)) { + this.classScope.usePrivateName(this.getPrivateNameSV(key), key.loc.start); + } + + this.toAssignable(value, isLHS); + break; + } case "SpreadElement": { - this.checkToRestConversion(node); - node.type = "RestElement"; - const arg = node.argument; - this.toAssignable(arg, isLHS); - break; + throw new Error("Internal @babel/parser error (this is a bug, please report it)." + " SpreadElement should be converted by .toAssignable's caller."); } case "ArrayExpression": node.type = "ArrayPattern"; - this.toAssignableList(node.elements, (_node$extra3 = node.extra) == null ? void 0 : _node$extra3.trailingComma, isLHS); + this.toAssignableList(node.elements, (_node$extra3 = node.extra) == null ? void 0 : _node$extra3.trailingCommaLoc, isLHS); break; case "AssignmentExpression": if (node.operator !== "=") { - this.raise(node.left.end, ErrorMessages.MissingEqInAssignment); + this.raise(Errors.MissingEqInAssignment, { + at: node.left.loc.end + }); } node.type = "AssignmentPattern"; @@ -10682,60 +11702,57 @@ this.toAssignable(parenthesized, isLHS); break; } - - return node; } toAssignableObjectExpressionProp(prop, isLast, isLHS) { if (prop.type === "ObjectMethod") { - const error = prop.kind === "get" || prop.kind === "set" ? ErrorMessages.PatternHasAccessor : ErrorMessages.PatternHasMethod; - this.raise(prop.key.start, error); - } else if (prop.type === "SpreadElement" && !isLast) { - this.raiseRestNotLast(prop.start); + this.raise(prop.kind === "get" || prop.kind === "set" ? Errors.PatternHasAccessor : Errors.PatternHasMethod, { + at: prop.key + }); + } else if (prop.type === "SpreadElement") { + prop.type = "RestElement"; + const arg = prop.argument; + this.checkToRestConversion(arg, false); + this.toAssignable(arg, isLHS); + + if (!isLast) { + this.raise(Errors.RestTrailingComma, { + at: prop + }); + } } else { this.toAssignable(prop, isLHS); } } - toAssignableList(exprList, trailingCommaPos, isLHS) { - let end = exprList.length; + toAssignableList(exprList, trailingCommaLoc, isLHS) { + const end = exprList.length - 1; - if (end) { - const last = exprList[end - 1]; - - if ((last == null ? void 0 : last.type) === "RestElement") { - --end; - } else if ((last == null ? void 0 : last.type) === "SpreadElement") { - last.type = "RestElement"; - let arg = last.argument; - this.toAssignable(arg, isLHS); - arg = unwrapParenthesizedExpression(arg); - - if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern" && arg.type !== "ObjectPattern") { - this.unexpected(arg.start); - } - - if (trailingCommaPos) { - this.raiseTrailingCommaAfterRest(trailingCommaPos); - } - - --end; - } - } - - for (let i = 0; i < end; i++) { + for (let i = 0; i <= end; i++) { const elt = exprList[i]; + if (!elt) continue; - if (elt) { + if (elt.type === "SpreadElement") { + elt.type = "RestElement"; + const arg = elt.argument; + this.checkToRestConversion(arg, true); + this.toAssignable(arg, isLHS); + } else { this.toAssignable(elt, isLHS); + } - if (elt.type === "RestElement") { - this.raiseRestNotLast(elt.start); + if (elt.type === "RestElement") { + if (i < end) { + this.raise(Errors.RestTrailingComma, { + at: elt + }); + } else if (trailingCommaLoc) { + this.raise(Errors.RestTrailingComma, { + at: trailingCommaLoc + }); } } } - - return exprList; } isAssignable(node, isBinding) { @@ -10841,17 +11858,21 @@ break; } else if (this.match(21)) { elts.push(this.parseAssignableListItemTypes(this.parseRestBinding())); - this.checkCommaAfterRest(closeCharCode); - this.expect(close); - break; + + if (!this.checkCommaAfterRest(closeCharCode)) { + this.expect(close); + break; + } } else { const decorators = []; - if (this.match(24) && this.hasPlugin("decorators")) { - this.raise(this.state.start, ErrorMessages.UnsupportedParameterDecorator); + if (this.match(26) && this.hasPlugin("decorators")) { + this.raise(Errors.UnsupportedParameterDecorator, { + at: this.state.startLoc + }); } - while (this.match(24)) { + while (this.match(26)) { decorators.push(this.parseDecorator()); } @@ -10860,6 +11881,36 @@ } return elts; + } + + parseBindingRestProperty(prop) { + this.next(); + prop.argument = this.parseIdentifier(); + this.checkCommaAfterRest(125); + return this.finishNode(prop, "RestElement"); + } + + parseBindingProperty() { + const prop = this.startNode(); + const { + type, + start: startPos, + startLoc + } = this.state; + + if (type === 21) { + return this.parseBindingRestProperty(prop); + } else if (type === 134) { + this.expectPlugin("destructuringPrivate", startLoc); + this.classScope.usePrivateName(this.state.value, startLoc); + prop.key = this.parsePrivateName(); + } else { + this.parsePropertyName(prop); + } + + prop.method = false; + this.parseObjPropValue(prop, startPos, startLoc, false, false, true, false); + return prop; } parseAssignableListItem(allowModifiers, decorators) { @@ -10884,114 +11935,164 @@ startLoc = (_startLoc = startLoc) != null ? _startLoc : this.state.startLoc; startPos = (_startPos = startPos) != null ? _startPos : this.state.start; left = (_left = left) != null ? _left : this.parseBindingAtom(); - if (!this.eat(27)) return left; + if (!this.eat(29)) return left; const node = this.startNodeAt(startPos, startLoc); node.left = left; node.right = this.parseMaybeAssignAllowIn(); return this.finishNode(node, "AssignmentPattern"); } - checkLVal(expr, contextDescription, bindingType = BIND_NONE, checkClashes, disallowLetBinding, strictModeChanged = false) { - switch (expr.type) { - case "Identifier": - { - const { - name - } = expr; - - if (this.state.strict && (strictModeChanged ? isStrictBindReservedWord(name, this.inModule) : isStrictBindOnlyReservedWord(name))) { - this.raise(expr.start, bindingType === BIND_NONE ? ErrorMessages.StrictEvalArguments : ErrorMessages.StrictEvalArgumentsBinding, name); - } - - if (checkClashes) { - if (checkClashes.has(name)) { - this.raise(expr.start, ErrorMessages.ParamDupe); - } else { - checkClashes.add(name); - } - } - - if (disallowLetBinding && name === "let") { - this.raise(expr.start, ErrorMessages.LetInLexicalBinding); - } - - if (!(bindingType & BIND_NONE)) { - this.scope.declareName(name, bindingType, expr.start); - } - - break; - } - - case "MemberExpression": - if (bindingType !== BIND_NONE) { - this.raise(expr.start, ErrorMessages.InvalidPropertyBindingPattern); - } - - break; - - case "ObjectPattern": - for (let prop of expr.properties) { - if (this.isObjectProperty(prop)) prop = prop.value;else if (this.isObjectMethod(prop)) continue; - this.checkLVal(prop, "object destructuring pattern", bindingType, checkClashes, disallowLetBinding); - } - - break; - - case "ArrayPattern": - for (const elem of expr.elements) { - if (elem) { - this.checkLVal(elem, "array destructuring pattern", bindingType, checkClashes, disallowLetBinding); - } - } - - break; - - case "AssignmentPattern": - this.checkLVal(expr.left, "assignment pattern", bindingType, checkClashes); - break; - - case "RestElement": - this.checkLVal(expr.argument, "rest element", bindingType, checkClashes); - break; - - case "ParenthesizedExpression": - this.checkLVal(expr.expression, "parenthesized expression", bindingType, checkClashes); - break; - - default: - { - this.raise(expr.start, bindingType === BIND_NONE ? ErrorMessages.InvalidLhs : ErrorMessages.InvalidLhsBinding, contextDescription); - } - } + isValidLVal(type, isUnparenthesizedInAssign, binding) { + return getOwn({ + AssignmentPattern: "left", + RestElement: "argument", + ObjectProperty: "value", + ParenthesizedExpression: "expression", + ArrayPattern: "elements", + ObjectPattern: "properties" + }, type); } - checkToRestConversion(node) { - if (node.argument.type !== "Identifier" && node.argument.type !== "MemberExpression") { - this.raise(node.argument.start, ErrorMessages.InvalidRestAssignmentPattern); - } - } + checkLVal(expression, { + in: ancestor, + binding = BIND_NONE, + checkClashes = false, + strictModeChanged = false, + allowingSloppyLetBinding = !(binding & BIND_SCOPE_LEXICAL), + hasParenthesizedAncestor = false + }) { + var _expression$extra; - checkCommaAfterRest(close) { - if (this.match(12)) { - if (this.lookaheadCharCode() === close) { - this.raiseTrailingCommaAfterRest(this.state.start); - } else { - this.raiseRestNotLast(this.state.start); + const type = expression.type; + if (this.isObjectMethod(expression)) return; + + if (type === "MemberExpression") { + if (binding !== BIND_NONE) { + this.raise(Errors.InvalidPropertyBindingPattern, { + at: expression + }); + } + + return; + } + + if (expression.type === "Identifier") { + this.checkIdentifier(expression, binding, strictModeChanged, allowingSloppyLetBinding); + const { + name + } = expression; + + if (checkClashes) { + if (checkClashes.has(name)) { + this.raise(Errors.ParamDupe, { + at: expression + }); + } else { + checkClashes.add(name); + } + } + + return; + } + + const validity = this.isValidLVal(expression.type, !(hasParenthesizedAncestor || (_expression$extra = expression.extra) != null && _expression$extra.parenthesized) && ancestor.type === "AssignmentExpression", binding); + if (validity === true) return; + + if (validity === false) { + const ParseErrorClass = binding === BIND_NONE ? Errors.InvalidLhs : Errors.InvalidLhsBinding; + this.raise(ParseErrorClass, { + at: expression, + ancestor: ancestor.type === "UpdateExpression" ? { + type: "UpdateExpression", + prefix: ancestor.prefix + } : { + type: ancestor.type + } + }); + return; + } + + const [key, isParenthesizedExpression] = Array.isArray(validity) ? validity : [validity, type === "ParenthesizedExpression"]; + const nextAncestor = expression.type === "ArrayPattern" || expression.type === "ObjectPattern" || expression.type === "ParenthesizedExpression" ? expression : ancestor; + + for (const child of [].concat(expression[key])) { + if (child) { + this.checkLVal(child, { + in: nextAncestor, + binding, + checkClashes, + allowingSloppyLetBinding, + strictModeChanged, + hasParenthesizedAncestor: isParenthesizedExpression + }); } } } - raiseRestNotLast(pos) { - throw this.raise(pos, ErrorMessages.ElementAfterRest); + checkIdentifier(at, bindingType, strictModeChanged = false, allowLetBinding = !(bindingType & BIND_SCOPE_LEXICAL)) { + if (this.state.strict && (strictModeChanged ? isStrictBindReservedWord(at.name, this.inModule) : isStrictBindOnlyReservedWord(at.name))) { + if (bindingType === BIND_NONE) { + this.raise(Errors.StrictEvalArguments, { + at, + referenceName: at.name + }); + } else { + this.raise(Errors.StrictEvalArgumentsBinding, { + at, + bindingName: at.name + }); + } + } + + if (!allowLetBinding && at.name === "let") { + this.raise(Errors.LetInLexicalBinding, { + at + }); + } + + if (!(bindingType & BIND_NONE)) { + this.declareNameFromIdentifier(at, bindingType); + } } - raiseTrailingCommaAfterRest(pos) { - this.raise(pos, ErrorMessages.RestTrailingComma); + declareNameFromIdentifier(identifier, binding) { + this.scope.declareName(identifier.name, binding, identifier.loc.start); + } + + checkToRestConversion(node, allowPattern) { + switch (node.type) { + case "ParenthesizedExpression": + this.checkToRestConversion(node.expression, allowPattern); + break; + + case "Identifier": + case "MemberExpression": + break; + + case "ArrayExpression": + case "ObjectExpression": + if (allowPattern) break; + + default: + this.raise(Errors.InvalidRestAssignmentPattern, { + at: node + }); + } + } + + checkCommaAfterRest(close) { + if (!this.match(12)) { + return false; + } + + this.raise(this.lookaheadCharCode() === close ? Errors.RestTrailingComma : Errors.ElementAfterRest, { + at: this.state.startLoc + }); + return true; } } -const invalidHackPipeBodies = new Map([["ArrowFunctionExpression", "arrow function"], ["AssignmentExpression", "assignment"], ["ConditionalExpression", "conditional"], ["YieldExpression", "yield"]]); class ExpressionParser extends LValParser { checkProto(prop, isRecord, protoRef, refExpressionErrors) { if (prop.type === "SpreadElement" || this.isObjectMethod(prop) || prop.computed || prop.shorthand) { @@ -11003,17 +12104,21 @@ if (name === "__proto__") { if (isRecord) { - this.raise(key.start, ErrorMessages.RecordNoProto); + this.raise(Errors.RecordNoProto, { + at: key + }); return; } if (protoRef.used) { if (refExpressionErrors) { - if (refExpressionErrors.doubleProto === -1) { - refExpressionErrors.doubleProto = key.start; + if (refExpressionErrors.doubleProtoLoc === null) { + refExpressionErrors.doubleProtoLoc = key.loc.start; } } else { - this.raise(key.start, ErrorMessages.DuplicateProto); + this.raise(Errors.DuplicateProto, { + at: key + }); } } @@ -11030,7 +12135,7 @@ this.nextToken(); const expr = this.parseExpression(); - if (!this.match(126)) { + if (!this.match(135)) { this.unexpected(); } @@ -11082,16 +12187,16 @@ } setOptionalParametersError(refExpressionErrors, resultError) { - var _resultError$pos; + var _resultError$loc; - refExpressionErrors.optionalParameters = (_resultError$pos = resultError == null ? void 0 : resultError.pos) != null ? _resultError$pos : this.state.start; + refExpressionErrors.optionalParametersLoc = (_resultError$loc = resultError == null ? void 0 : resultError.loc) != null ? _resultError$loc : this.state.startLoc; } parseMaybeAssign(refExpressionErrors, afterLeftParse) { const startPos = this.state.start; const startLoc = this.state.startLoc; - if (this.isContextual(96)) { + if (this.isContextual(105)) { if (this.prodParam.hasYield) { let left = this.parseYield(); @@ -11131,21 +12236,32 @@ const operator = this.state.value; node.operator = operator; - if (this.match(27)) { - node.left = this.toAssignable(left, true); - refExpressionErrors.doubleProto = -1; + if (this.match(29)) { + this.toAssignable(left, true); + node.left = left; + + if (refExpressionErrors.doubleProtoLoc != null && refExpressionErrors.doubleProtoLoc.index >= startPos) { + refExpressionErrors.doubleProtoLoc = null; + } + + if (refExpressionErrors.shorthandAssignLoc != null && refExpressionErrors.shorthandAssignLoc.index >= startPos) { + refExpressionErrors.shorthandAssignLoc = null; + } + + if (refExpressionErrors.privateKeyLoc != null && refExpressionErrors.privateKeyLoc.index >= startPos) { + this.checkDestructuringPrivate(refExpressionErrors); + refExpressionErrors.privateKeyLoc = null; + } } else { node.left = left; } - if (refExpressionErrors.shorthandAssign >= node.left.start) { - refExpressionErrors.shorthandAssign = -1; - } - - this.checkLVal(left, "assignment expression"); this.next(); node.right = this.parseMaybeAssign(); - return this.finishNode(node, "AssignmentExpression"); + this.checkLVal(left, { + in: this.finishNode(node, "AssignmentExpression") + }); + return node; } else if (ownExpressionErrors) { this.checkExpressionErrors(refExpressionErrors, true); } @@ -11180,7 +12296,7 @@ } parseMaybeUnaryOrPrivate(refExpressionErrors) { - return this.match(125) ? this.parsePrivateName() : this.parseMaybeUnary(refExpressionErrors); + return this.match(134) ? this.parsePrivateName() : this.parseMaybeUnary(refExpressionErrors); } parseExprOps(refExpressionErrors) { @@ -11199,48 +12315,52 @@ parseExprOp(left, leftStartPos, leftStartLoc, minPrec) { if (this.isPrivateName(left)) { const value = this.getPrivateNameSV(left); - const { - start - } = left; - if (minPrec >= tokenOperatorPrecedence(49) || !this.prodParam.hasIn || !this.match(49)) { - this.raise(start, ErrorMessages.PrivateInExpectedIn, value); + if (minPrec >= tokenOperatorPrecedence(58) || !this.prodParam.hasIn || !this.match(58)) { + this.raise(Errors.PrivateInExpectedIn, { + at: left, + identifierName: value + }); } - this.classScope.usePrivateName(value, start); + this.classScope.usePrivateName(value, left.loc.start); } const op = this.state.type; - if (tokenIsOperator(op) && (this.prodParam.hasIn || !this.match(49))) { + if (tokenIsOperator(op) && (this.prodParam.hasIn || !this.match(58))) { let prec = tokenOperatorPrecedence(op); if (prec > minPrec) { - if (op === 34) { + if (op === 39) { this.expectPlugin("pipelineOperator"); if (this.state.inFSharpPipelineDirectBody) { return left; } - this.checkPipelineAtInfixOperator(left, leftStartPos); + this.checkPipelineAtInfixOperator(left, leftStartLoc); } const node = this.startNodeAt(leftStartPos, leftStartLoc); node.left = left; node.operator = this.state.value; - const logical = op === 36 || op === 37; - const coalesce = op === 35; + const logical = op === 41 || op === 42; + const coalesce = op === 40; if (coalesce) { - prec = tokenOperatorPrecedence(37); + prec = tokenOperatorPrecedence(42); } this.next(); - if (op === 34 && this.getPluginOption("pipelineOperator", "proposal") === "minimal") { - if (this.state.type === 87 && this.prodParam.hasAwait) { - throw this.raise(this.state.start, ErrorMessages.UnexpectedAwaitAfterPipelineBody); + if (op === 39 && this.hasPlugin(["pipelineOperator", { + proposal: "minimal" + }])) { + if (this.state.type === 96 && this.prodParam.hasAwait) { + throw this.raise(Errors.UnexpectedAwaitAfterPipelineBody, { + at: this.state.startLoc + }); } } @@ -11248,8 +12368,10 @@ this.finishNode(node, logical || coalesce ? "LogicalExpression" : "BinaryExpression"); const nextOp = this.state.type; - if (coalesce && (nextOp === 36 || nextOp === 37) || logical && nextOp === 35) { - throw this.raise(this.state.start, ErrorMessages.MixingCoalesceWithLogical); + if (coalesce && (nextOp === 41 || nextOp === 42) || logical && nextOp === 40) { + throw this.raise(Errors.MixingCoalesceWithLogical, { + at: this.state.startLoc + }); } return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec); @@ -11264,7 +12386,7 @@ const startLoc = this.state.startLoc; switch (op) { - case 34: + case 39: switch (this.getPluginOption("pipelineOperator", "proposal")) { case "hack": return this.withTopicBindingContext(() => { @@ -11273,8 +12395,10 @@ case "smart": return this.withTopicBindingContext(() => { - if (this.prodParam.hasYield && this.isContextual(96)) { - throw this.raise(this.state.start, ErrorMessages.PipeBodyIsTighter, this.state.value); + if (this.prodParam.hasYield && this.isContextual(105)) { + throw this.raise(Errors.PipeBodyIsTighter, { + at: this.state.startLoc + }); } return this.parseSmartPipelineBodyInStyle(this.parseExprOpBaseRightExpr(op, prec), startPos, startLoc); @@ -11301,31 +12425,39 @@ var _body$extra; const { - start + startLoc } = this.state; const body = this.parseMaybeAssign(); + const requiredParentheses = UnparenthesizedPipeBodyDescriptions.has(body.type); - if (invalidHackPipeBodies.has(body.type) && !((_body$extra = body.extra) != null && _body$extra.parenthesized)) { - this.raise(start, ErrorMessages.PipeUnparenthesizedBody, invalidHackPipeBodies.get(body.type)); + if (requiredParentheses && !((_body$extra = body.extra) != null && _body$extra.parenthesized)) { + this.raise(Errors.PipeUnparenthesizedBody, { + at: startLoc, + type: body.type + }); } if (!this.topicReferenceWasUsedInCurrentContext()) { - this.raise(start, ErrorMessages.PipeTopicUnused); + this.raise(Errors.PipeTopicUnused, { + at: startLoc + }); } return body; } checkExponentialAfterUnary(node) { - if (this.match(48)) { - this.raise(node.argument.start, ErrorMessages.UnexpectedTokenUnaryExponentiation); + if (this.match(57)) { + this.raise(Errors.UnexpectedTokenUnaryExponentiation, { + at: node.argument + }); } } parseMaybeUnary(refExpressionErrors, sawUnary) { const startPos = this.state.start; const startLoc = this.state.startLoc; - const isAwait = this.isContextual(87); + const isAwait = this.isContextual(96); if (isAwait && this.isAwaitAllowed()) { this.next(); @@ -11334,18 +12466,18 @@ return expr; } - const update = this.match(31); + const update = this.match(34); const node = this.startNode(); if (tokenIsPrefix(this.state.type)) { node.operator = this.state.value; node.prefix = true; - if (this.match(63)) { + if (this.match(72)) { this.expectPlugin("throwExpressions"); } - const isDelete = this.match(80); + const isDelete = this.match(89); this.next(); node.argument = this.parseMaybeUnary(null, true); this.checkExpressionErrors(refExpressionErrors, true); @@ -11354,9 +12486,13 @@ const arg = node.argument; if (arg.type === "Identifier") { - this.raise(node.start, ErrorMessages.StrictDelete); + this.raise(Errors.StrictDelete, { + at: node + }); } else if (this.hasPropertyAsPrivateName(arg)) { - this.raise(node.start, ErrorMessages.DeletePrivateField); + this.raise(Errors.DeletePrivateField, { + at: node + }); } } @@ -11372,10 +12508,12 @@ const { type } = this.state; - const startsExpr = this.hasPlugin("v8intrinsic") ? tokenCanStartExpression(type) : tokenCanStartExpression(type) && !this.match(45); + const startsExpr = this.hasPlugin("v8intrinsic") ? tokenCanStartExpression(type) : tokenCanStartExpression(type) && !this.match(54); if (startsExpr && !this.isAmbiguousAwait()) { - this.raiseOverwrite(startPos, ErrorMessages.AwaitNotInAsyncContext); + this.raiseOverwrite(Errors.AwaitNotInAsyncContext, { + at: startLoc + }); return this.parseAwait(startPos, startLoc); } } @@ -11385,8 +12523,10 @@ parseUpdate(node, update, refExpressionErrors) { if (update) { - this.checkLVal(node.argument, "prefix operation"); - return this.finishNode(node, "UpdateExpression"); + this.checkLVal(node.argument, { + in: this.finishNode(node, "UpdateExpression") + }); + return node; } const startPos = this.state.start; @@ -11399,9 +12539,10 @@ node.operator = this.state.value; node.prefix = false; node.argument = expr; - this.checkLVal(expr, "postfix operation"); this.next(); - expr = this.finishNode(node, "UpdateExpression"); + this.checkLVal(expr, { + in: expr = this.finishNode(node, "UpdateExpression") + }); } return expr; @@ -11436,15 +12577,19 @@ } parseSubscript(base, startPos, startLoc, noCalls, state) { - if (!noCalls && this.eat(15)) { + const { + type + } = this.state; + + if (!noCalls && type === 15) { return this.parseBind(base, startPos, startLoc, noCalls, state); - } else if (this.match(22)) { + } else if (tokenIsTemplate(type)) { return this.parseTaggedTemplateExpression(base, startPos, startLoc, state); } let optional = false; - if (this.match(18)) { + if (type === 18) { if (noCalls && this.lookaheadCharCode() === 40) { state.stop = true; return base; @@ -11472,21 +12617,21 @@ const node = this.startNodeAt(startPos, startLoc); node.object = base; node.computed = computed; - const privateName = !computed && this.match(125) && this.state.value; - const property = computed ? this.parseExpression() : privateName ? this.parsePrivateName() : this.parseIdentifier(true); - - if (privateName !== false) { - if (node.object.type === "Super") { - this.raise(startPos, ErrorMessages.SuperPrivateField); - } - - this.classScope.usePrivateName(privateName, property.start); - } - - node.property = property; if (computed) { + node.property = this.parseExpression(); this.expect(3); + } else if (this.match(134)) { + if (base.type === "Super") { + this.raise(Errors.SuperPrivateField, { + at: startLoc + }); + } + + this.classScope.usePrivateName(this.state.value, this.state.startLoc); + node.property = this.parsePrivateName(); + } else { + node.property = this.parseIdentifier(true); } if (state.optionalChainMember) { @@ -11500,6 +12645,7 @@ parseBind(base, startPos, startLoc, noCalls, state) { const node = this.startNodeAt(startPos, startLoc); node.object = base; + this.next(); node.callee = this.parseNoCallExpr(); state.stop = true; return this.parseSubscripts(this.finishNode(node, "BindExpression"), startPos, startLoc, noCalls); @@ -11512,13 +12658,17 @@ this.next(); let node = this.startNodeAt(startPos, startLoc); node.callee = base; + const { + maybeAsyncArrow, + optionalChainMember + } = state; - if (state.maybeAsyncArrow) { + if (maybeAsyncArrow) { this.expressionScope.enter(newAsyncArrowScope()); refExpressionErrors = new ExpressionErrors(); } - if (state.optionalChainMember) { + if (optionalChainMember) { node.optional = optional; } @@ -11528,15 +12678,16 @@ node.arguments = this.parseCallExpressionArguments(11, base.type === "Import", base.type !== "Super", node, refExpressionErrors); } - this.finishCallExpression(node, state.optionalChainMember); + this.finishCallExpression(node, optionalChainMember); - if (state.maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) { + if (maybeAsyncArrow && this.shouldParseAsyncArrow() && !optional) { state.stop = true; + this.checkDestructuringPrivate(refExpressionErrors); this.expressionScope.validateAsPattern(); this.expressionScope.exit(); node = this.parseAsyncArrowFromCallExpression(this.startNodeAt(startPos, startLoc), node); } else { - if (state.maybeAsyncArrow) { + if (maybeAsyncArrow) { this.checkExpressionErrors(refExpressionErrors, true); this.expressionScope.exit(); } @@ -11558,14 +12709,16 @@ node.quasi = this.parseTemplate(true); if (state.optionalChainMember) { - this.raise(startPos, ErrorMessages.OptionalChainingNoTemplate); + this.raise(Errors.OptionalChainingNoTemplate, { + at: startLoc + }); } return this.finishNode(node, "TaggedTemplateExpression"); } atPossibleAsyncArrow(base) { - return base.type === "Identifier" && base.name === "async" && this.state.lastTokEnd === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && base.start === this.state.potentialArrowAt; + return base.type === "Identifier" && base.name === "async" && this.state.lastTokEndLoc.index === base.end && !this.canInsertSemicolon() && base.end - base.start === 5 && base.start === this.state.potentialArrowAt; } finishCallExpression(node, optional) { @@ -11579,11 +12732,16 @@ } if (node.arguments.length === 0 || node.arguments.length > 2) { - this.raise(node.start, ErrorMessages.ImportCallArity, this.hasPlugin("importAssertions") || this.hasPlugin("moduleAttributes") ? "one or two arguments" : "one argument"); + this.raise(Errors.ImportCallArity, { + at: node, + maxArgumentCount: this.hasPlugin("importAssertions") || this.hasPlugin("moduleAttributes") ? 2 : 1 + }); } else { for (const arg of node.arguments) { if (arg.type === "SpreadElement") { - this.raise(arg.start, ErrorMessages.ImportCallSpreadArgument); + this.raise(Errors.ImportCallSpreadArgument, { + at: arg + }); } } } @@ -11606,11 +12764,13 @@ if (this.match(close)) { if (dynamicImport && !this.hasPlugin("importAssertions") && !this.hasPlugin("moduleAttributes")) { - this.raise(this.state.lastTokStart, ErrorMessages.ImportCallArgumentTrailingComma); + this.raise(Errors.ImportCallArgumentTrailingComma, { + at: this.state.lastTokStartLoc + }); } if (nodeForExtra) { - this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart); + this.addTrailingCommaExtraToNode(nodeForExtra); } this.next(); @@ -11634,7 +12794,7 @@ this.resetPreviousNodeTrailingComments(call); this.expect(19); - this.parseArrowExpression(node, call.arguments, true, (_call$extra = call.extra) == null ? void 0 : _call$extra.trailingComma); + this.parseArrowExpression(node, call.arguments, true, (_call$extra = call.extra) == null ? void 0 : _call$extra.trailingCommaLoc); if (call.innerComments) { setInnerComments(node, call.innerComments); @@ -11660,10 +12820,10 @@ } = this.state; switch (type) { - case 70: + case 79: return this.parseSuper(); - case 74: + case 83: node = this.startNode(); this.next(); @@ -11672,47 +12832,49 @@ } if (!this.match(10)) { - this.raise(this.state.lastTokStart, ErrorMessages.UnsupportedImport); + this.raise(Errors.UnsupportedImport, { + at: this.state.lastTokStartLoc + }); } return this.finishNode(node, "Import"); - case 69: + case 78: node = this.startNode(); this.next(); return this.finishNode(node, "ThisExpression"); - case 81: + case 90: { return this.parseDo(this.startNode(), false); } - case 47: - case 29: + case 56: + case 31: { this.readRegexp(); return this.parseRegExpLiteral(this.state.value); } - case 121: + case 130: return this.parseNumericLiteral(this.state.value); - case 122: + case 131: return this.parseBigIntLiteral(this.state.value); - case 123: + case 132: return this.parseDecimalLiteral(this.state.value); - case 120: + case 129: return this.parseStringLiteral(this.state.value); - case 75: + case 84: return this.parseNullLiteral(); - case 76: + case 85: return this.parseBooleanLiteral(true); - case 77: + case 86: return this.parseBooleanLiteral(false); case 10: @@ -11724,7 +12886,7 @@ case 2: case 1: { - return this.parseArrayLike(this.state.type === 2 ? 4 : 3, false, true, refExpressionErrors); + return this.parseArrayLike(this.state.type === 2 ? 4 : 3, false, true); } case 0: @@ -11735,7 +12897,7 @@ case 6: case 7: { - return this.parseObjectLike(this.state.type === 6 ? 9 : 8, false, true, refExpressionErrors); + return this.parseObjectLike(this.state.type === 6 ? 9 : 8, false, true); } case 5: @@ -11743,21 +12905,22 @@ return this.parseObjectLike(8, false, false, refExpressionErrors); } - case 59: + case 68: return this.parseFunctionOrFunctionSent(); - case 24: + case 26: this.parseDecorators(); - case 71: + case 80: node = this.startNode(); this.takeDecorators(node); return this.parseClass(node, false); - case 68: + case 77: return this.parseNewOrNewTarget(); - case 22: + case 25: + case 24: return this.parseTemplate(false); case 15: @@ -11770,55 +12933,65 @@ if (callee.type === "MemberExpression") { return this.finishNode(node, "BindExpression"); } else { - throw this.raise(callee.start, ErrorMessages.UnsupportedBind); + throw this.raise(Errors.UnsupportedBind, { + at: callee + }); } } - case 125: + case 134: { - this.raise(this.state.start, ErrorMessages.PrivateInExpectedIn, this.state.value); + this.raise(Errors.PrivateInExpectedIn, { + at: this.state.startLoc, + identifierName: this.state.value + }); return this.parsePrivateName(); } - case 30: - if (this.getPluginOption("pipelineOperator", "proposal") === "hack" && this.getPluginOption("pipelineOperator", "topicToken") === "%") { - this.state.value = "%"; - this.state.type = 45; - this.state.pos--; - this.state.end--; - this.state.endLoc.column--; - } else { - throw this.unexpected(); + case 33: + { + return this.parseTopicReferenceThenEqualsSign(54, "%"); } - case 45: - case 25: + case 32: + { + return this.parseTopicReferenceThenEqualsSign(44, "^"); + } + + case 37: + case 38: + { + return this.parseTopicReference("hack"); + } + + case 44: + case 54: + case 27: { const pipeProposal = this.getPluginOption("pipelineOperator", "proposal"); if (pipeProposal) { - node = this.startNode(); - const start = this.state.start; - const tokenType = this.state.type; - this.next(); - return this.finishTopicReference(node, start, pipeProposal, tokenType); + return this.parseTopicReference(pipeProposal); + } else { + throw this.unexpected(); } } - case 42: + case 47: { - if (this.state.value === "<") { - const lookaheadCh = this.input.codePointAt(this.nextTokenStart()); + const lookaheadCh = this.input.codePointAt(this.nextTokenStart()); - if (isIdentifierStart(lookaheadCh) || lookaheadCh === 62) { - this.expectOnePlugin(["jsx", "flow", "typescript"]); - } + if (isIdentifierStart(lookaheadCh) || lookaheadCh === 62) { + this.expectOnePlugin(["jsx", "flow", "typescript"]); + break; + } else { + throw this.unexpected(); } } default: if (tokenIsIdentifier(type)) { - if (this.isContextual(114) && this.lookaheadCharCode() === 123 && !this.hasFollowingLineBreak()) { + if (this.isContextual(123) && this.lookaheadCharCode() === 123 && !this.hasFollowingLineBreak()) { return this.parseModuleExpression(); } @@ -11831,7 +13004,7 @@ type } = this.state; - if (type === 59) { + if (type === 68) { this.resetPreviousNodeTrailingComments(id); this.next(); return this.parseFunction(this.startNodeAtNode(id), undefined, true); @@ -11841,7 +13014,7 @@ } else { return id; } - } else if (type === 81) { + } else if (type === 90) { this.resetPreviousNodeTrailingComments(id); return this.parseDo(this.startNodeAtNode(id), true); } @@ -11860,44 +13033,65 @@ } } - finishTopicReference(node, start, pipeProposal, tokenType) { - if (this.testTopicReferenceConfiguration(pipeProposal, start, tokenType)) { - let nodeType; + parseTopicReferenceThenEqualsSign(topicTokenType, topicTokenValue) { + const pipeProposal = this.getPluginOption("pipelineOperator", "proposal"); - if (pipeProposal === "smart") { - nodeType = "PipelinePrimaryTopicReference"; - } else { - nodeType = "TopicReference"; - } + if (pipeProposal) { + this.state.type = topicTokenType; + this.state.value = topicTokenValue; + this.state.pos--; + this.state.end--; + this.state.endLoc = createPositionWithColumnOffset(this.state.endLoc, -1); + return this.parseTopicReference(pipeProposal); + } else { + throw this.unexpected(); + } + } + + parseTopicReference(pipeProposal) { + const node = this.startNode(); + const startLoc = this.state.startLoc; + const tokenType = this.state.type; + this.next(); + return this.finishTopicReference(node, startLoc, pipeProposal, tokenType); + } + + finishTopicReference(node, startLoc, pipeProposal, tokenType) { + if (this.testTopicReferenceConfiguration(pipeProposal, startLoc, tokenType)) { + const nodeType = pipeProposal === "smart" ? "PipelinePrimaryTopicReference" : "TopicReference"; if (!this.topicReferenceIsAllowedInCurrentContext()) { - if (pipeProposal === "smart") { - this.raise(start, ErrorMessages.PrimaryTopicNotAllowed); - } else { - this.raise(start, ErrorMessages.PipeTopicUnbound); - } + this.raise(pipeProposal === "smart" ? Errors.PrimaryTopicNotAllowed : Errors.PipeTopicUnbound, { + at: startLoc + }); } this.registerTopicReference(); return this.finishNode(node, nodeType); } else { - throw this.raise(start, ErrorMessages.PipeTopicUnconfiguredToken, tokenLabelName(tokenType)); + throw this.raise(Errors.PipeTopicUnconfiguredToken, { + at: startLoc, + token: tokenLabelName(tokenType) + }); } } - testTopicReferenceConfiguration(pipeProposal, start, tokenType) { + testTopicReferenceConfiguration(pipeProposal, startLoc, tokenType) { switch (pipeProposal) { case "hack": { - const pluginTopicToken = this.getPluginOption("pipelineOperator", "topicToken"); - return tokenLabelName(tokenType) === pluginTopicToken; + return this.hasPlugin(["pipelineOperator", { + topicToken: tokenLabelName(tokenType) + }]); } case "smart": - return tokenType === 25; + return tokenType === 27; default: - throw this.raise(start, ErrorMessages.PipeTopicRequiresHackPipes); + throw this.raise(Errors.PipeTopicRequiresHackPipes, { + at: startLoc + }); } } @@ -11907,7 +13101,9 @@ this.prodParam.exit(); if (this.hasPrecedingLineBreak()) { - this.raise(this.state.pos, ErrorMessages.LineTerminatorBeforeArrow); + this.raise(Errors.LineTerminatorBeforeArrow, { + at: this.state.curPosition() + }); } this.expect(19); @@ -11944,35 +13140,27 @@ this.next(); if (this.match(10) && !this.scope.allowDirectSuper && !this.options.allowSuperOutsideMethod) { - this.raise(node.start, ErrorMessages.SuperNotAllowed); + this.raise(Errors.SuperNotAllowed, { + at: node + }); } else if (!this.scope.allowSuper && !this.options.allowSuperOutsideMethod) { - this.raise(node.start, ErrorMessages.UnexpectedSuper); + this.raise(Errors.UnexpectedSuper, { + at: node + }); } if (!this.match(10) && !this.match(0) && !this.match(16)) { - this.raise(node.start, ErrorMessages.UnsupportedSuper); + this.raise(Errors.UnsupportedSuper, { + at: node + }); } return this.finishNode(node, "Super"); } - parseMaybePrivateName(isPrivateNameAllowed) { - const isPrivate = this.match(125); - - if (isPrivate) { - if (!isPrivateNameAllowed) { - this.raise(this.state.start + 1, ErrorMessages.UnexpectedPrivateField); - } - - return this.parsePrivateName(); - } else { - return this.parseIdentifier(true); - } - } - parsePrivateName() { const node = this.startNode(); - const id = this.startNodeAt(this.state.start + 1, new Position(this.state.curLine, this.state.start + 1 - this.state.lineStart)); + const id = this.startNodeAt(this.state.start + 1, new Position(this.state.curLine, this.state.start + 1 - this.state.lineStart, this.state.start + 1)); const name = this.state.value; this.next(); node.id = this.createIdentifier(id, name); @@ -11987,7 +13175,7 @@ const meta = this.createIdentifier(this.startNodeAtNode(node), "function"); this.next(); - if (this.match(93)) { + if (this.match(102)) { this.expectPlugin("functionSent"); } else if (!this.hasPlugin("functionSent")) { this.unexpected(); @@ -12005,7 +13193,11 @@ node.property = this.parseIdentifier(true); if (node.property.name !== propertyName || containsEsc) { - this.raise(node.property.start, ErrorMessages.UnsupportedMetaProperty, meta.name, propertyName); + this.raise(Errors.UnsupportedMetaProperty, { + at: node.property, + target: meta.name, + onlyValidPropertyName: propertyName + }); } return this.finishNode(node, "MetaProperty"); @@ -12015,9 +13207,11 @@ const id = this.createIdentifier(this.startNodeAtNode(node), "import"); this.next(); - if (this.isContextual(91)) { + if (this.isContextual(100)) { if (!this.inModule) { - this.raise(id.start, SourceTypeModuleErrorMessages.ImportMetaOutsideModule); + this.raise(Errors.ImportMetaOutsideModule, { + at: id + }); } this.sawUnambiguousESM = true; @@ -12090,17 +13284,17 @@ const exprList = []; const refExpressionErrors = new ExpressionErrors(); let first = true; - let spreadStart; - let optionalCommaStart; + let spreadStartLoc; + let optionalCommaStartLoc; while (!this.match(11)) { if (first) { first = false; } else { - this.expect(12, refExpressionErrors.optionalParameters === -1 ? null : refExpressionErrors.optionalParameters); + this.expect(12, refExpressionErrors.optionalParametersLoc === null ? null : refExpressionErrors.optionalParametersLoc); if (this.match(11)) { - optionalCommaStart = this.state.start; + optionalCommaStartLoc = this.state.startLoc; break; } } @@ -12108,16 +13302,17 @@ if (this.match(21)) { const spreadNodeStartPos = this.state.start; const spreadNodeStartLoc = this.state.startLoc; - spreadStart = this.state.start; + spreadStartLoc = this.state.startLoc; exprList.push(this.parseParenItem(this.parseRestBinding(), spreadNodeStartPos, spreadNodeStartLoc)); - this.checkCommaAfterRest(41); - break; + + if (!this.checkCommaAfterRest(41)) { + break; + } } else { exprList.push(this.parseMaybeAssignAllowIn(refExpressionErrors, this.parseParenItem)); } } - const innerEndPos = this.state.lastTokEnd; const innerEndLoc = this.state.lastTokEndLoc; this.expect(11); this.state.maybeInArrowParameters = oldMaybeInArrowParameters; @@ -12125,6 +13320,7 @@ let arrowNode = this.startNodeAt(startPos, startLoc); if (canBeArrow && this.shouldParseArrow(exprList) && (arrowNode = this.parseArrow(arrowNode))) { + this.checkDestructuringPrivate(refExpressionErrors); this.expressionScope.validateAsPattern(); this.expressionScope.exit(); this.parseArrowExpression(arrowNode, exprList, false); @@ -12134,11 +13330,11 @@ this.expressionScope.exit(); if (!exprList.length) { - this.unexpected(this.state.lastTokStart); + this.unexpected(this.state.lastTokStartLoc); } - if (optionalCommaStart) this.unexpected(optionalCommaStart); - if (spreadStart) this.unexpected(spreadStart); + if (optionalCommaStartLoc) this.unexpected(optionalCommaStartLoc); + if (spreadStartLoc) this.unexpected(spreadStartLoc); this.checkExpressionErrors(refExpressionErrors, true); this.toReferencedListDeep(exprList, true); @@ -12146,20 +13342,24 @@ val = this.startNodeAt(innerStartPos, innerStartLoc); val.expressions = exprList; this.finishNode(val, "SequenceExpression"); - this.resetEndLocation(val, innerEndPos, innerEndLoc); + this.resetEndLocation(val, innerEndLoc); } else { val = exprList[0]; } + return this.wrapParenthesis(startPos, startLoc, val); + } + + wrapParenthesis(startPos, startLoc, expression) { if (!this.options.createParenthesizedExpressions) { - this.addExtra(val, "parenthesized", true); - this.addExtra(val, "parenStart", startPos); - this.takeSurroundingComments(val, startPos, this.state.lastTokEnd); - return val; + this.addExtra(expression, "parenthesized", true); + this.addExtra(expression, "parenStart", startPos); + this.takeSurroundingComments(expression, startPos, this.state.lastTokEndLoc.index); + return expression; } const parenExpression = this.startNodeAt(startPos, startLoc); - parenExpression.expression = val; + parenExpression.expression = expression; this.finishNode(parenExpression, "ParenthesizedExpression"); return parenExpression; } @@ -12188,7 +13388,9 @@ const metaProp = this.parseMetaProperty(node, meta, "target"); if (!this.scope.inNonArrowFunction && !this.scope.inClass) { - this.raise(metaProp.start, ErrorMessages.UnexpectedNewTarget); + this.raise(Errors.UnexpectedNewTarget, { + at: metaProp + }); } return metaProp; @@ -12201,11 +13403,17 @@ node.callee = this.parseNoCallExpr(); if (node.callee.type === "Import") { - this.raise(node.callee.start, ErrorMessages.ImportCallNotNewExpression); + this.raise(Errors.ImportCallNotNewExpression, { + at: node.callee + }); } else if (this.isOptionalChain(node.callee)) { - this.raise(this.state.lastTokEnd, ErrorMessages.OptionalChainingNoNew); + this.raise(Errors.OptionalChainingNoNew, { + at: this.state.lastTokEndLoc + }); } else if (this.eat(18)) { - this.raise(this.state.start, ErrorMessages.OptionalChainingNoNew); + this.raise(Errors.OptionalChainingNoNew, { + at: this.state.startLoc + }); } this.parseNewArguments(node); @@ -12223,38 +13431,49 @@ } parseTemplateElement(isTagged) { - const elem = this.startNode(); + const { + start, + startLoc, + end, + value + } = this.state; + const elemStart = start + 1; + const elem = this.startNodeAt(elemStart, createPositionWithColumnOffset(startLoc, 1)); - if (this.state.value === null) { + if (value === null) { if (!isTagged) { - this.raise(this.state.start + 1, ErrorMessages.InvalidEscapeSequenceTemplate); + this.raise(Errors.InvalidEscapeSequenceTemplate, { + at: createPositionWithColumnOffset(startLoc, 2) + }); } } + const isTail = this.match(24); + const endOffset = isTail ? -1 : -2; + const elemEnd = end + endOffset; elem.value = { - raw: this.input.slice(this.state.start, this.state.end).replace(/\r\n?/g, "\n"), - cooked: this.state.value + raw: this.input.slice(elemStart, elemEnd).replace(/\r\n?/g, "\n"), + cooked: value === null ? null : value.slice(1, endOffset) }; + elem.tail = isTail; this.next(); - elem.tail = this.match(22); - return this.finishNode(elem, "TemplateElement"); + this.finishNode(elem, "TemplateElement"); + this.resetEndLocation(elem, createPositionWithColumnOffset(this.state.lastTokEndLoc, endOffset)); + return elem; } parseTemplate(isTagged) { const node = this.startNode(); - this.next(); node.expressions = []; let curElt = this.parseTemplateElement(isTagged); node.quasis = [curElt]; while (!curElt.tail) { - this.expect(23); node.expressions.push(this.parseTemplateSubstitution()); - this.expect(8); + this.readTemplateContinuation(); node.quasis.push(curElt = this.parseTemplateElement(isTagged)); } - this.next(); return this.finishNode(node, "TemplateLiteral"); } @@ -12282,19 +13501,24 @@ this.expect(12); if (this.match(close)) { - this.addExtra(node, "trailingComma", this.state.lastTokStart); + this.addTrailingCommaExtraToNode(node); break; } } - const prop = this.parsePropertyDefinition(isPattern, refExpressionErrors); + let prop; - if (!isPattern) { + if (isPattern) { + prop = this.parseBindingProperty(); + } else { + prop = this.parsePropertyDefinition(refExpressionErrors); this.checkProto(prop, isRecord, propHash, refExpressionErrors); } if (isRecord && !this.isObjectProperty(prop) && prop.type !== "SpreadElement") { - this.raise(prop.start, ErrorMessages.InvalidRecordProperty); + this.raise(Errors.InvalidRecordProperty, { + at: prop + }); } if (prop.shorthand) { @@ -12317,25 +13541,31 @@ return this.finishNode(node, type); } - maybeAsyncOrAccessorProp(prop) { - return !prop.computed && prop.key.type === "Identifier" && (this.isLiteralPropertyName() || this.match(0) || this.match(46)); + addTrailingCommaExtraToNode(node) { + this.addExtra(node, "trailingComma", this.state.lastTokStart); + this.addExtra(node, "trailingCommaLoc", this.state.lastTokStartLoc, false); } - parsePropertyDefinition(isPattern, refExpressionErrors) { + maybeAsyncOrAccessorProp(prop) { + return !prop.computed && prop.key.type === "Identifier" && (this.isLiteralPropertyName() || this.match(0) || this.match(55)); + } + + parsePropertyDefinition(refExpressionErrors) { let decorators = []; - if (this.match(24)) { + if (this.match(26)) { if (this.hasPlugin("decorators")) { - this.raise(this.state.start, ErrorMessages.UnsupportedPropertyDecorator); + this.raise(Errors.UnsupportedPropertyDecorator, { + at: this.state.startLoc + }); } - while (this.match(24)) { + while (this.match(26)) { decorators.push(this.parseDecorator()); } } const prop = this.startNode(); - let isGenerator = false; let isAsync = false; let isAccessor = false; let startPos; @@ -12343,14 +13573,6 @@ if (this.match(21)) { if (decorators.length) this.unexpected(); - - if (isPattern) { - this.next(); - prop.argument = this.parseIdentifier(); - this.checkCommaAfterRest(125); - return this.finishNode(prop, "RestElement"); - } - return this.parseSpread(); } @@ -12361,26 +13583,24 @@ prop.method = false; - if (isPattern || refExpressionErrors) { + if (refExpressionErrors) { startPos = this.state.start; startLoc = this.state.startLoc; } - if (!isPattern) { - isGenerator = this.eat(46); - } - + let isGenerator = this.eat(55); + this.parsePropertyNamePrefixOperator(prop); const containsEsc = this.state.containsEsc; - const key = this.parsePropertyName(prop, false); + const key = this.parsePropertyName(prop, refExpressionErrors); - if (!isPattern && !isGenerator && !containsEsc && this.maybeAsyncOrAccessorProp(prop)) { + if (!isGenerator && !containsEsc && this.maybeAsyncOrAccessorProp(prop)) { const keyName = key.name; if (keyName === "async" && !this.hasPrecedingLineBreak()) { isAsync = true; this.resetPreviousNodeTrailingComments(key); - isGenerator = this.eat(46); - this.parsePropertyName(prop, false); + isGenerator = this.eat(55); + this.parsePropertyName(prop); } if (keyName === "get" || keyName === "set") { @@ -12388,17 +13608,20 @@ this.resetPreviousNodeTrailingComments(key); prop.kind = keyName; - if (this.match(46)) { + if (this.match(55)) { isGenerator = true; - this.raise(this.state.pos, ErrorMessages.AccessorIsGenerator, keyName); + this.raise(Errors.AccessorIsGenerator, { + at: this.state.curPosition(), + kind: keyName + }); this.next(); } - this.parsePropertyName(prop, false); + this.parsePropertyName(prop); } } - this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, isPattern, isAccessor, refExpressionErrors); + this.parseObjPropValue(prop, startPos, startLoc, isGenerator, isAsync, false, isAccessor, refExpressionErrors); return prop; } @@ -12415,18 +13638,17 @@ const paramCount = this.getGetterSetterExpectedParamCount(method); const params = this.getObjectOrClassMethodParams(method); - const start = method.start; if (params.length !== paramCount) { - if (method.kind === "get") { - this.raise(start, ErrorMessages.BadGetterArity); - } else { - this.raise(start, ErrorMessages.BadSetterArity); - } + this.raise(method.kind === "get" ? Errors.BadGetterArity : Errors.BadSetterArity, { + at: method + }); } if (method.kind === "set" && ((_params = params[params.length - 1]) == null ? void 0 : _params.type) === "RestElement") { - this.raise(start, ErrorMessages.BadSetterRestParameter); + this.raise(Errors.BadSetterRestParameter, { + at: method + }); } } @@ -12454,13 +13676,21 @@ } if (!prop.computed && prop.key.type === "Identifier") { - this.checkReservedWord(prop.key.name, prop.key.start, true, false); + this.checkReservedWord(prop.key.name, prop.key.loc.start, true, false); if (isPattern) { prop.value = this.parseMaybeDefault(startPos, startLoc, cloneIdentifier(prop.key)); - } else if (this.match(27) && refExpressionErrors) { - if (refExpressionErrors.shorthandAssign === -1) { - refExpressionErrors.shorthandAssign = this.state.start; + } else if (this.match(29)) { + const shorthandAssignLoc = this.state.startLoc; + + if (refExpressionErrors != null) { + if (refExpressionErrors.shorthandAssignLoc === null) { + refExpressionErrors.shorthandAssignLoc = shorthandAssignLoc; + } + } else { + this.raise(Errors.InvalidCoverInitializedName, { + at: shorthandAssignLoc + }); } prop.value = this.parseMaybeDefault(startPos, startLoc, cloneIdentifier(prop.key)); @@ -12479,22 +13709,66 @@ return node; } - parsePropertyName(prop, isPrivateNameAllowed) { + parsePropertyName(prop, refExpressionErrors) { if (this.eat(0)) { prop.computed = true; prop.key = this.parseMaybeAssignAllowIn(); this.expect(3); } else { - const oldInPropertyName = this.state.inPropertyName; - this.state.inPropertyName = true; - const type = this.state.type; - prop.key = type === 121 || type === 120 || type === 122 || type === 123 ? this.parseExprAtom() : this.parseMaybePrivateName(isPrivateNameAllowed); + const { + type, + value + } = this.state; + let key; - if (type !== 125) { - prop.computed = false; + if (tokenIsKeywordOrIdentifier(type)) { + key = this.parseIdentifier(true); + } else { + switch (type) { + case 130: + key = this.parseNumericLiteral(value); + break; + + case 129: + key = this.parseStringLiteral(value); + break; + + case 131: + key = this.parseBigIntLiteral(value); + break; + + case 132: + key = this.parseDecimalLiteral(value); + break; + + case 134: + { + const privateKeyLoc = this.state.startLoc; + + if (refExpressionErrors != null) { + if (refExpressionErrors.privateKeyLoc === null) { + refExpressionErrors.privateKeyLoc = privateKeyLoc; + } + } else { + this.raise(Errors.UnexpectedPrivateField, { + at: privateKeyLoc + }); + } + + key = this.parsePrivateName(); + break; + } + + default: + throw this.unexpected(); + } } - this.state.inPropertyName = oldInPropertyName; + prop.key = key; + + if (type !== 134) { + prop.computed = false; + } } return prop.key; @@ -12533,11 +13807,11 @@ return this.finishNode(node, isTuple ? "TupleExpression" : "ArrayExpression"); } - parseArrowExpression(node, params, isAsync, trailingCommaPos) { + parseArrowExpression(node, params, isAsync, trailingCommaLoc) { this.scope.enter(SCOPE_FUNCTION | SCOPE_ARROW); let flags = functionFlags(isAsync, false); - if (!this.match(0) && this.prodParam.hasIn) { + if (!this.match(5) && this.prodParam.hasIn) { flags |= PARAM_IN; } @@ -12547,7 +13821,7 @@ if (params) { this.state.maybeInArrowParameters = true; - this.setArrowFunctionParameters(node, params, trailingCommaPos); + this.setArrowFunctionParameters(node, params, trailingCommaLoc); } this.state.maybeInArrowParameters = false; @@ -12558,8 +13832,9 @@ return this.finishNode(node, "ArrowFunctionExpression"); } - setArrowFunctionParameters(node, params, trailingCommaPos) { - node.params = this.toAssignableList(params, trailingCommaPos, false); + setArrowFunctionParameters(node, params, trailingCommaLoc) { + this.toAssignableList(params, trailingCommaLoc, false); + node.params = params; } parseFunctionBodyAndFinish(node, type, isMethod = false) { @@ -12583,36 +13858,50 @@ const nonSimple = !this.isSimpleParamList(node.params); if (hasStrictModeDirective && nonSimple) { - const errorPos = (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.end : node.start; - this.raise(errorPos, ErrorMessages.IllegalLanguageModeDirective); + this.raise(Errors.IllegalLanguageModeDirective, { + at: (node.kind === "method" || node.kind === "constructor") && !!node.key ? node.key.loc.end : node + }); } const strictModeChanged = !oldStrict && this.state.strict; this.checkParams(node, !this.state.strict && !allowExpression && !isMethod && !nonSimple, allowExpression, strictModeChanged); if (this.state.strict && node.id) { - this.checkLVal(node.id, "function name", BIND_OUTSIDE, undefined, undefined, strictModeChanged); + this.checkIdentifier(node.id, BIND_OUTSIDE, strictModeChanged); } }); this.prodParam.exit(); - this.expressionScope.exit(); this.state.labels = oldLabels; } + + this.expressionScope.exit(); + } + + isSimpleParameter(node) { + return node.type === "Identifier"; } isSimpleParamList(params) { for (let i = 0, len = params.length; i < len; i++) { - if (params[i].type !== "Identifier") return false; + if (!this.isSimpleParameter(params[i])) return false; } return true; } checkParams(node, allowDuplicates, isArrowFunction, strictModeChanged = true) { - const checkClashes = new Set(); + const checkClashes = !allowDuplicates && new Set(); + const formalParameters = { + type: "FormalParameters" + }; for (const param of node.params) { - this.checkLVal(param, "function parameter list", BIND_VAR, allowDuplicates ? null : checkClashes, undefined, strictModeChanged); + this.checkLVal(param, { + in: formalParameters, + binding: BIND_VAR, + checkClashes, + strictModeChanged + }); } } @@ -12628,7 +13917,7 @@ if (this.match(close)) { if (nodeForExtra) { - this.addExtra(nodeForExtra, "trailingComma", this.state.lastTokStart); + this.addTrailingCommaExtraToNode(nodeForExtra); } this.next(); @@ -12647,7 +13936,10 @@ if (this.match(12)) { if (!allowEmpty) { - this.raise(this.state.pos, ErrorMessages.UnexpectedToken, ","); + this.raise(Errors.UnexpectedToken, { + at: this.state.curPosition(), + unexpected: "," + }); } elt = null; @@ -12659,7 +13951,9 @@ this.expectPlugin("partialApplication"); if (!allowPlaceholder) { - this.raise(this.state.start, ErrorMessages.UnexpectedArgumentPlaceholder); + this.raise(Errors.UnexpectedArgumentPlaceholder, { + at: this.state.startLoc + }); } const node = this.startNode(); @@ -12687,7 +13981,7 @@ parseIdentifierName(pos, liberal) { let name; const { - start, + startLoc, type } = this.state; @@ -12697,10 +13991,14 @@ throw this.unexpected(); } + const tokenIsKeyword = tokenKeywordOrIdentifierIsKeyword(type); + if (liberal) { - this.state.type = 119; + if (tokenIsKeyword) { + this.replaceToken(128); + } } else { - this.checkReservedWord(name, start, tokenIsKeyword(type), false); + this.checkReservedWord(name, startLoc, tokenIsKeyword, false); } this.next(); @@ -12718,35 +14016,53 @@ if (word === "yield") { if (this.prodParam.hasYield) { - this.raise(startLoc, ErrorMessages.YieldBindingIdentifier); + this.raise(Errors.YieldBindingIdentifier, { + at: startLoc + }); return; } } else if (word === "await") { if (this.prodParam.hasAwait) { - this.raise(startLoc, ErrorMessages.AwaitBindingIdentifier); + this.raise(Errors.AwaitBindingIdentifier, { + at: startLoc + }); return; - } else if (this.scope.inStaticBlock) { - this.raise(startLoc, ErrorMessages.AwaitBindingIdentifierInStaticBlock); - return; - } else { - this.expressionScope.recordAsyncArrowParametersError(startLoc, ErrorMessages.AwaitBindingIdentifier); } + + if (this.scope.inStaticBlock) { + this.raise(Errors.AwaitBindingIdentifierInStaticBlock, { + at: startLoc + }); + return; + } + + this.expressionScope.recordAsyncArrowParametersError({ + at: startLoc + }); } else if (word === "arguments") { if (this.scope.inClassAndNotInNonArrowFunction) { - this.raise(startLoc, ErrorMessages.ArgumentsInClass); + this.raise(Errors.ArgumentsInClass, { + at: startLoc + }); return; } } if (checkKeywords && isKeyword(word)) { - this.raise(startLoc, ErrorMessages.UnexpectedKeyword, word); + this.raise(Errors.UnexpectedKeyword, { + at: startLoc, + keyword: word + }); return; } const reservedTest = !this.state.strict ? isReservedWord : isBinding ? isStrictBindReservedWord : isStrictReservedWord; if (reservedTest(word, this.inModule)) { - this.raise(startLoc, ErrorMessages.UnexpectedReservedWord, word); + this.raise(Errors.UnexpectedReservedWord, { + at: startLoc, + reservedWord: word + }); } } @@ -12762,10 +14078,14 @@ parseAwait(startPos, startLoc) { const node = this.startNodeAt(startPos, startLoc); - this.expressionScope.recordParameterInitializerError(node.start, ErrorMessages.AwaitExpressionFormalParameter); + this.expressionScope.recordParameterInitializerError(Errors.AwaitExpressionFormalParameter, { + at: node + }); - if (this.eat(46)) { - this.raise(node.start, ErrorMessages.ObsoleteAwaitStar); + if (this.eat(55)) { + this.raise(Errors.ObsoleteAwaitStar, { + at: node + }); } if (!this.scope.inFunction && !this.options.allowAwaitOutsideFunction) { @@ -12784,22 +14104,28 @@ } isAmbiguousAwait() { - return this.hasPrecedingLineBreak() || this.match(44) || this.match(10) || this.match(0) || this.match(22) || this.match(124) || this.match(47) || this.hasPlugin("v8intrinsic") && this.match(45); + if (this.hasPrecedingLineBreak()) return true; + const { + type + } = this.state; + return type === 53 || type === 10 || type === 0 || tokenIsTemplate(type) || type === 133 || type === 56 || this.hasPlugin("v8intrinsic") && type === 54; } parseYield() { const node = this.startNode(); - this.expressionScope.recordParameterInitializerError(node.start, ErrorMessages.YieldInParameter); + this.expressionScope.recordParameterInitializerError(Errors.YieldInParameter, { + at: node + }); this.next(); let delegating = false; let argument = null; if (!this.hasPrecedingLineBreak()) { - delegating = this.eat(46); + delegating = this.eat(55); switch (this.state.type) { case 13: - case 126: + case 135: case 8: case 11: case 3: @@ -12818,17 +14144,15 @@ return this.finishNode(node, "YieldExpression"); } - checkPipelineAtInfixOperator(left, leftStartPos) { - if (this.getPluginOption("pipelineOperator", "proposal") === "smart") { + checkPipelineAtInfixOperator(left, leftStartLoc) { + if (this.hasPlugin(["pipelineOperator", { + proposal: "smart" + }])) { if (left.type === "SequenceExpression") { - this.raise(leftStartPos, ErrorMessages.PipelineHeadSequenceExpression); + this.raise(Errors.PipelineHeadSequenceExpression, { + at: leftStartLoc + }); } - } - } - - checkHackPipeBodyEarlyErrors(startPos) { - if (!this.topicReferenceWasUsedInCurrentContext()) { - this.raise(startPos, ErrorMessages.PipeTopicUnused); } } @@ -12839,7 +14163,7 @@ bodyNode.callee = childExpr; return this.finishNode(bodyNode, "PipelineBareFunction"); } else { - this.checkSmartPipeTopicBodyEarlyErrors(startPos); + this.checkSmartPipeTopicBodyEarlyErrors(startLoc); bodyNode.expression = childExpr; return this.finishNode(bodyNode, "PipelineTopicExpression"); } @@ -12858,11 +14182,17 @@ } } - checkSmartPipeTopicBodyEarlyErrors(startPos) { + checkSmartPipeTopicBodyEarlyErrors(startLoc) { if (this.match(19)) { - throw this.raise(this.state.start, ErrorMessages.PipelineBodyNoArrow); - } else if (!this.topicReferenceWasUsedInCurrentContext()) { - this.raise(startPos, ErrorMessages.PipelineTopicUnused); + throw this.raise(Errors.PipelineBodyNoArrow, { + at: this.state.startLoc + }); + } + + if (!this.topicReferenceWasUsedInCurrentContext()) { + this.raise(Errors.PipelineTopicUnused, { + at: startLoc + }); } } @@ -12881,9 +14211,9 @@ } withSmartMixTopicForbiddingContext(callback) { - const proposal = this.getPluginOption("pipelineOperator", "proposal"); - - if (proposal === "smart") { + if (this.hasPlugin(["pipelineOperator", { + proposal: "smart" + }])) { const outerContextTopicState = this.state.topicContext; this.state.topicContext = { maxNumOfResolvableTopics: 0, @@ -12987,6 +14317,8 @@ return this.finishNode(node, "ModuleExpression"); } + parsePropertyNamePrefixOperator(prop) {} + } const loopLabel = { @@ -13002,44 +14334,114 @@ const loneSurrogate = /[\uD800-\uDFFF]/u; const keywordRelationalOperator = /in(?:stanceof)?/y; -function babel7CompatTokens(tokens) { +function babel7CompatTokens(tokens, input) { for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; const { type } = token; - if (type === 125) { - { - const { - loc, - start, - value, - end - } = token; - const hashEndPos = start + 1; - const hashEndLoc = new Position(loc.start.line, loc.start.column + 1); - tokens.splice(i, 1, new Token({ - type: getExportedToken(25), - value: "#", - start: start, - end: hashEndPos, - startLoc: loc.start, - endLoc: hashEndLoc - }), new Token({ - type: getExportedToken(119), - value: value, - start: hashEndPos, - end: end, - startLoc: hashEndLoc, - endLoc: loc.end - })); - i++; - continue; - } - } - if (typeof type === "number") { + { + if (type === 134) { + const { + loc, + start, + value, + end + } = token; + const hashEndPos = start + 1; + const hashEndLoc = createPositionWithColumnOffset(loc.start, 1); + tokens.splice(i, 1, new Token({ + type: getExportedToken(27), + value: "#", + start: start, + end: hashEndPos, + startLoc: loc.start, + endLoc: hashEndLoc + }), new Token({ + type: getExportedToken(128), + value: value, + start: hashEndPos, + end: end, + startLoc: hashEndLoc, + endLoc: loc.end + })); + i++; + continue; + } + + if (tokenIsTemplate(type)) { + const { + loc, + start, + value, + end + } = token; + const backquoteEnd = start + 1; + const backquoteEndLoc = createPositionWithColumnOffset(loc.start, 1); + let startToken; + + if (input.charCodeAt(start) === 96) { + startToken = new Token({ + type: getExportedToken(22), + value: "`", + start: start, + end: backquoteEnd, + startLoc: loc.start, + endLoc: backquoteEndLoc + }); + } else { + startToken = new Token({ + type: getExportedToken(8), + value: "}", + start: start, + end: backquoteEnd, + startLoc: loc.start, + endLoc: backquoteEndLoc + }); + } + + let templateValue, templateElementEnd, templateElementEndLoc, endToken; + + if (type === 24) { + templateElementEnd = end - 1; + templateElementEndLoc = createPositionWithColumnOffset(loc.end, -1); + templateValue = value === null ? null : value.slice(1, -1); + endToken = new Token({ + type: getExportedToken(22), + value: "`", + start: templateElementEnd, + end: end, + startLoc: templateElementEndLoc, + endLoc: loc.end + }); + } else { + templateElementEnd = end - 2; + templateElementEndLoc = createPositionWithColumnOffset(loc.end, -2); + templateValue = value === null ? null : value.slice(1, -2); + endToken = new Token({ + type: getExportedToken(23), + value: "${", + start: templateElementEnd, + end: end, + startLoc: templateElementEndLoc, + endLoc: loc.end + }); + } + + tokens.splice(i, 1, startToken, new Token({ + type: getExportedToken(20), + value: templateValue, + start: backquoteEnd, + end: templateElementEnd, + startLoc: backquoteEndLoc, + endLoc: templateElementEndLoc + }), endToken); + i += 2; + continue; + } + } token.type = getExportedToken(type); } } @@ -13051,19 +14453,25 @@ parseTopLevel(file, program) { file.program = this.parseProgram(program); file.comments = this.state.comments; - if (this.options.tokens) file.tokens = babel7CompatTokens(this.tokens); + + if (this.options.tokens) { + file.tokens = babel7CompatTokens(this.tokens, this.input); + } + return this.finishNode(file, "File"); } - parseProgram(program, end = 126, sourceType = this.options.sourceType) { + parseProgram(program, end = 135, sourceType = this.options.sourceType) { program.sourceType = sourceType; program.interpreter = this.parseInterpreterDirective(); this.parseBlockBody(program, true, true, end); if (this.inModule && !this.options.allowUndeclaredExports && this.scope.undefinedExports.size > 0) { - for (const [name] of Array.from(this.scope.undefinedExports)) { - const pos = this.scope.undefinedExports.get(name); - this.raise(pos, ErrorMessages.ModuleExportUndefined, name); + for (const [localName, at] of Array.from(this.scope.undefinedExports)) { + this.raise(Errors.ModuleExportUndefined, { + at, + localName + }); } } @@ -13076,16 +14484,18 @@ directive.value = directive.expression; delete directive.expression; const directiveLiteral = directive.value; + const expressionValue = directiveLiteral.value; const raw = this.input.slice(directiveLiteral.start, directiveLiteral.end); const val = directiveLiteral.value = raw.slice(1, -1); this.addExtra(directiveLiteral, "raw", raw); this.addExtra(directiveLiteral, "rawValue", val); + this.addExtra(directiveLiteral, "expressionValue", expressionValue); directiveLiteral.type = "DirectiveLiteral"; return directive; } parseInterpreterDirective() { - if (!this.match(26)) { + if (!this.match(28)) { return null; } @@ -13096,7 +14506,7 @@ } isLet(context) { - if (!this.isContextual(90)) { + if (!this.isContextual(99)) { return false; } @@ -13132,7 +14542,7 @@ } parseStatement(context, topLevel) { - if (this.match(24)) { + if (this.match(26)) { this.parseDecorators(true); } @@ -13145,72 +14555,78 @@ let kind; if (this.isLet(context)) { - starttype = 65; + starttype = 74; kind = "let"; } switch (starttype) { - case 51: + case 60: return this.parseBreakContinueStatement(node, true); - case 54: + case 63: return this.parseBreakContinueStatement(node, false); - case 55: + case 64: return this.parseDebuggerStatement(node); - case 81: + case 90: return this.parseDoStatement(node); - case 82: + case 91: return this.parseForStatement(node); - case 59: + case 68: if (this.lookaheadCharCode() === 46) break; if (context) { if (this.state.strict) { - this.raise(this.state.start, ErrorMessages.StrictFunction); + this.raise(Errors.StrictFunction, { + at: this.state.startLoc + }); } else if (context !== "if" && context !== "label") { - this.raise(this.state.start, ErrorMessages.SloppyFunction); + this.raise(Errors.SloppyFunction, { + at: this.state.startLoc + }); } } return this.parseFunctionStatement(node, false, !context); - case 71: + case 80: if (context) this.unexpected(); return this.parseClass(node, true); - case 60: + case 69: return this.parseIfStatement(node); - case 61: + case 70: return this.parseReturnStatement(node); - case 62: + case 71: return this.parseSwitchStatement(node); - case 63: + case 72: return this.parseThrowStatement(node); - case 64: + case 73: return this.parseTryStatement(node); - case 66: - case 65: + case 75: + case 74: kind = kind || this.state.value; if (context && kind !== "var") { - this.raise(this.state.start, ErrorMessages.UnexpectedLexicalDeclaration); + this.raise(Errors.UnexpectedLexicalDeclaration, { + at: this.state.startLoc + }); } return this.parseVarStatement(node, kind); - case 83: + case 92: return this.parseWhileStatement(node); - case 67: + case 76: return this.parseWithStatement(node); case 5: @@ -13219,7 +14635,7 @@ case 13: return this.parseEmptyStatement(node); - case 74: + case 83: { const nextTokenCharCode = this.lookaheadCharCode(); @@ -13228,16 +14644,18 @@ } } - case 73: + case 82: { if (!this.options.allowImportExportEverywhere && !topLevel) { - this.raise(this.state.start, ErrorMessages.UnexpectedImportExport); + this.raise(Errors.UnexpectedImportExport, { + at: this.state.startLoc + }); } this.next(); let result; - if (starttype === 74) { + if (starttype === 83) { result = this.parseImport(node); if (result.type === "ImportDeclaration" && (!result.importKind || result.importKind === "value")) { @@ -13259,7 +14677,9 @@ { if (this.isAsyncFunction()) { if (context) { - this.raise(this.state.start, ErrorMessages.AsyncFunctionInSingleStatementContext); + this.raise(Errors.AsyncFunctionInSingleStatementContext, { + at: this.state.startLoc + }); } this.next(); @@ -13280,7 +14700,9 @@ assertModuleNodeAllowed(node) { if (!this.options.allowImportExportEverywhere && !this.inModule) { - this.raise(node.start, SourceTypeModuleErrorMessages.ImportOutsideModule); + this.raise(Errors.ImportOutsideModule, { + at: node + }); } } @@ -13295,27 +14717,31 @@ } canHaveLeadingDecorator() { - return this.match(71); + return this.match(80); } parseDecorators(allowExport) { const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; - while (this.match(24)) { + while (this.match(26)) { const decorator = this.parseDecorator(); currentContextDecorators.push(decorator); } - if (this.match(73)) { + if (this.match(82)) { if (!allowExport) { this.unexpected(); } if (this.hasPlugin("decorators") && !this.getPluginOption("decorators", "decoratorsBeforeExport")) { - this.raise(this.state.start, ErrorMessages.DecoratorExportClass); + this.raise(Errors.DecoratorExportClass, { + at: this.state.startLoc + }); } } else if (!this.canHaveLeadingDecorator()) { - throw this.raise(this.state.start, ErrorMessages.UnexpectedLeadingDecorator); + throw this.raise(Errors.UnexpectedLeadingDecorator, { + at: this.state.startLoc + }); } } @@ -13330,9 +14756,13 @@ const startLoc = this.state.startLoc; let expr; - if (this.eat(10)) { + if (this.match(10)) { + const startPos = this.state.start; + const startLoc = this.state.startLoc; + this.next(); expr = this.parseExpression(); this.expect(11); + expr = this.wrapParenthesis(startPos, startLoc, expr); } else { expr = this.parseIdentifier(false); @@ -13393,7 +14823,11 @@ } if (i === this.state.labels.length) { - this.raise(node.start, ErrorMessages.IllegalBreakContinue, isBreak ? "break" : "continue"); + const type = isBreak ? "BreakStatement" : "ContinueStatement"; + this.raise(Errors.IllegalBreakContinue, { + at: node, + type + }); } } @@ -13415,7 +14849,7 @@ this.state.labels.push(loopLabel); node.body = this.withSmartMixTopicForbiddingContext(() => this.parseStatement("do")); this.state.labels.pop(); - this.expect(83); + this.expect(92); node.test = this.parseHeaderExpression(); this.eat(13); return this.finishNode(node, "DoWhileStatement"); @@ -13424,67 +14858,78 @@ parseForStatement(node) { this.next(); this.state.labels.push(loopLabel); - let awaitAt = -1; + let awaitAt = null; - if (this.isAwaitAllowed() && this.eatContextual(87)) { - awaitAt = this.state.lastTokStart; + if (this.isAwaitAllowed() && this.eatContextual(96)) { + awaitAt = this.state.lastTokStartLoc; } this.scope.enter(SCOPE_OTHER); this.expect(10); if (this.match(13)) { - if (awaitAt > -1) { + if (awaitAt !== null) { this.unexpected(awaitAt); } return this.parseFor(node, null); } - const startsWithLet = this.isContextual(90); + const startsWithLet = this.isContextual(99); const isLet = startsWithLet && this.isLetKeyword(); - if (this.match(65) || this.match(66) || isLet) { + if (this.match(74) || this.match(75) || isLet) { const init = this.startNode(); const kind = isLet ? "let" : this.state.value; this.next(); this.parseVar(init, true, kind); this.finishNode(init, "VariableDeclaration"); - if ((this.match(49) || this.isContextual(92)) && init.declarations.length === 1) { + if ((this.match(58) || this.isContextual(101)) && init.declarations.length === 1) { return this.parseForIn(node, init, awaitAt); } - if (awaitAt > -1) { + if (awaitAt !== null) { this.unexpected(awaitAt); } return this.parseFor(node, init); } - const startsWithAsync = this.isContextual(86); + const startsWithAsync = this.isContextual(95); const refExpressionErrors = new ExpressionErrors(); const init = this.parseExpression(true, refExpressionErrors); - const isForOf = this.isContextual(92); + const isForOf = this.isContextual(101); if (isForOf) { if (startsWithLet) { - this.raise(init.start, ErrorMessages.ForOfLet); - } else if (awaitAt === -1 && startsWithAsync && init.type === "Identifier") { - this.raise(init.start, ErrorMessages.ForOfAsync); + this.raise(Errors.ForOfLet, { + at: init + }); + } + + if (awaitAt === null && startsWithAsync && init.type === "Identifier") { + this.raise(Errors.ForOfAsync, { + at: init + }); } } - if (isForOf || this.match(49)) { + if (isForOf || this.match(58)) { + this.checkDestructuringPrivate(refExpressionErrors); this.toAssignable(init, true); - const description = isForOf ? "for-of statement" : "for-in statement"; - this.checkLVal(init, description); + const type = isForOf ? "ForOfStatement" : "ForInStatement"; + this.checkLVal(init, { + in: { + type + } + }); return this.parseForIn(node, init, awaitAt); } else { this.checkExpressionErrors(refExpressionErrors, true); } - if (awaitAt > -1) { + if (awaitAt !== null) { this.unexpected(awaitAt); } @@ -13500,13 +14945,15 @@ this.next(); node.test = this.parseHeaderExpression(); node.consequent = this.parseStatement("if"); - node.alternate = this.eat(57) ? this.parseStatement("if") : null; + node.alternate = this.eat(66) ? this.parseStatement("if") : null; return this.finishNode(node, "IfStatement"); } parseReturnStatement(node) { if (!this.prodParam.hasReturn && !this.options.allowReturnOutsideFunction) { - this.raise(this.state.start, ErrorMessages.IllegalReturn); + this.raise(Errors.IllegalReturn, { + at: this.state.startLoc + }); } this.next(); @@ -13531,8 +14978,8 @@ let cur; for (let sawDefault; !this.match(8);) { - if (this.match(52) || this.match(56)) { - const isCase = this.match(52); + if (this.match(61) || this.match(65)) { + const isCase = this.match(61); if (cur) this.finishNode(cur, "SwitchCase"); cases.push(cur = this.startNode()); cur.consequent = []; @@ -13542,7 +14989,9 @@ cur.test = this.parseExpression(); } else { if (sawDefault) { - this.raise(this.state.lastTokStart, ErrorMessages.MultipleDefaultsInSwitch); + this.raise(Errors.MultipleDefaultsInSwitch, { + at: this.state.lastTokStartLoc + }); } sawDefault = true; @@ -13570,7 +15019,9 @@ this.next(); if (this.hasPrecedingLineBreak()) { - this.raise(this.state.lastTokEnd, ErrorMessages.NewlineAfterThrow); + this.raise(Errors.NewlineAfterThrow, { + at: this.state.lastTokEndLoc + }); } node.argument = this.parseExpression(); @@ -13582,7 +15033,13 @@ const param = this.parseBindingAtom(); const simple = param.type === "Identifier"; this.scope.enter(simple ? SCOPE_SIMPLE_CATCH : 0); - this.checkLVal(param, "catch clause", BIND_LEXICAL); + this.checkLVal(param, { + in: { + type: "CatchClause" + }, + binding: BIND_LEXICAL, + allowingSloppyLetBinding: true + }); return param; } @@ -13591,7 +15048,7 @@ node.block = this.parseBlock(); node.handler = null; - if (this.match(53)) { + if (this.match(62)) { const clause = this.startNode(); this.next(); @@ -13609,18 +15066,20 @@ node.handler = this.finishNode(clause, "CatchClause"); } - node.finalizer = this.eat(58) ? this.parseBlock() : null; + node.finalizer = this.eat(67) ? this.parseBlock() : null; if (!node.handler && !node.finalizer) { - this.raise(node.start, ErrorMessages.NoCatchOrFinally); + this.raise(Errors.NoCatchOrFinally, { + at: node + }); } return this.finishNode(node, "TryStatement"); } - parseVarStatement(node, kind) { + parseVarStatement(node, kind, allowMissingInitializer = false) { this.next(); - this.parseVar(node, false, kind); + this.parseVar(node, false, kind, allowMissingInitializer); this.semicolon(); return this.finishNode(node, "VariableDeclaration"); } @@ -13636,7 +15095,9 @@ parseWithStatement(node) { if (this.state.strict) { - this.raise(this.state.start, ErrorMessages.StrictWith); + this.raise(Errors.StrictWith, { + at: this.state.startLoc + }); } this.next(); @@ -13653,11 +15114,14 @@ parseLabeledStatement(node, maybeName, expr, context) { for (const label of this.state.labels) { if (label.name === maybeName) { - this.raise(expr.start, ErrorMessages.LabelRedeclaration, maybeName); + this.raise(Errors.LabelRedeclaration, { + at: expr, + labelName: maybeName + }); } } - const kind = tokenIsLoop(this.state.type) ? "loop" : this.match(62) ? "switch" : null; + const kind = tokenIsLoop(this.state.type) ? "loop" : this.match(71) ? "switch" : null; for (let i = this.state.labels.length - 1; i >= 0; i--) { const label = this.state.labels[i]; @@ -13772,19 +15236,29 @@ } parseForIn(node, init, awaitAt) { - const isForIn = this.match(49); + const isForIn = this.match(58); this.next(); if (isForIn) { - if (awaitAt > -1) this.unexpected(awaitAt); + if (awaitAt !== null) this.unexpected(awaitAt); } else { - node.await = awaitAt > -1; + node.await = awaitAt !== null; } if (init.type === "VariableDeclaration" && init.declarations[0].init != null && (!isForIn || this.state.strict || init.kind !== "var" || init.declarations[0].id.type !== "Identifier")) { - this.raise(init.start, ErrorMessages.ForInOfLoopInitializer, isForIn ? "for-in" : "for-of"); - } else if (init.type === "AssignmentPattern") { - this.raise(init.start, ErrorMessages.InvalidLhs, "for-loop"); + this.raise(Errors.ForInOfLoopInitializer, { + at: init, + type: isForIn ? "ForInStatement" : "ForOfStatement" + }); + } + + if (init.type === "AssignmentPattern") { + this.raise(Errors.InvalidLhs, { + at: init, + ancestor: { + type: "ForStatement" + } + }); } node.left = init; @@ -13796,27 +15270,27 @@ return this.finishNode(node, isForIn ? "ForInStatement" : "ForOfStatement"); } - parseVar(node, isFor, kind) { + parseVar(node, isFor, kind, allowMissingInitializer = false) { const declarations = node.declarations = []; - const isTypescript = this.hasPlugin("typescript"); node.kind = kind; for (;;) { const decl = this.startNode(); this.parseVarId(decl, kind); + decl.init = !this.eat(29) ? null : isFor ? this.parseMaybeAssignDisallowIn() : this.parseMaybeAssignAllowIn(); - if (this.eat(27)) { - decl.init = isFor ? this.parseMaybeAssignDisallowIn() : this.parseMaybeAssignAllowIn(); - } else { - if (kind === "const" && !(this.match(49) || this.isContextual(92))) { - if (!isTypescript) { - this.raise(this.state.lastTokEnd, ErrorMessages.DeclarationMissingInitializer, "Const declarations"); - } - } else if (decl.id.type !== "Identifier" && !(isFor && (this.match(49) || this.isContextual(92)))) { - this.raise(this.state.lastTokEnd, ErrorMessages.DeclarationMissingInitializer, "Complex binding patterns"); + if (decl.init === null && !allowMissingInitializer) { + if (decl.id.type !== "Identifier" && !(isFor && (this.match(58) || this.isContextual(101)))) { + this.raise(Errors.DeclarationMissingInitializer, { + at: this.state.lastTokEndLoc, + kind: "destructuring" + }); + } else if (kind === "const" && !(this.match(58) || this.isContextual(101))) { + this.raise(Errors.DeclarationMissingInitializer, { + at: this.state.lastTokEndLoc, + kind: "const" + }); } - - decl.init = null; } declarations.push(this.finishNode(decl, "VariableDeclarator")); @@ -13828,7 +15302,12 @@ parseVarId(decl, kind) { decl.id = this.parseBindingAtom(); - this.checkLVal(decl.id, "variable declaration", kind === "var" ? BIND_VAR : BIND_LEXICAL, undefined, kind !== "var"); + this.checkLVal(decl.id, { + in: { + type: "VariableDeclarator" + }, + binding: kind === "var" ? BIND_VAR : BIND_LEXICAL + }); } parseFunction(node, statement = FUNC_NO_FLAGS, isAsync = false) { @@ -13837,11 +15316,13 @@ const requireId = !!isStatement && !(statement & FUNC_NULLABLE_ID); this.initFunction(node, isAsync); - if (this.match(46) && isHangingStatement) { - this.raise(this.state.start, ErrorMessages.GeneratorInSingleStatementContext); + if (this.match(55) && isHangingStatement) { + this.raise(Errors.GeneratorInSingleStatementContext, { + at: this.state.startLoc + }); } - node.generator = this.eat(46); + node.generator = this.eat(55); if (isStatement) { node.id = this.parseFunctionId(requireId); @@ -13884,7 +15365,7 @@ registerFunctionStatementId(node) { if (!node.id) return; - this.scope.declareName(node.id.name, this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION, node.id.start); + this.scope.declareName(node.id.name, this.state.strict || node.generator || node.async ? this.scope.treatFunctionsAsVar ? BIND_VAR : BIND_LEXICAL : BIND_FUNCTION, node.id.loc.start); } parseClass(node, isStatement, optionalId) { @@ -13899,7 +15380,7 @@ } isClassProperty() { - return this.match(27) || this.match(13) || this.match(8); + return this.match(29) || this.match(13) || this.match(8); } isClassMethod() { @@ -13924,13 +15405,15 @@ while (!this.match(8)) { if (this.eat(13)) { if (decorators.length > 0) { - throw this.raise(this.state.lastTokEnd, ErrorMessages.DecoratorSemicolon); + throw this.raise(Errors.DecoratorSemicolon, { + at: this.state.lastTokEndLoc + }); } continue; } - if (this.match(24)) { + if (this.match(26)) { decorators.push(this.parseDecorator()); continue; } @@ -13946,7 +15429,9 @@ this.parseClassMember(classBody, member, state); if (member.kind === "constructor" && member.decorators && member.decorators.length > 0) { - this.raise(member.start, ErrorMessages.DecoratorConstructor); + this.raise(Errors.DecoratorConstructor, { + at: member + }); } } }); @@ -13954,7 +15439,9 @@ this.next(); if (decorators.length) { - throw this.raise(this.state.start, ErrorMessages.TrailingDecorator); + throw this.raise(Errors.TrailingDecorator, { + at: this.state.startLoc + }); } this.classScope.exit(); @@ -13986,7 +15473,7 @@ } parseClassMember(classBody, member, state) { - const isStatic = this.isContextual(95); + const isStatic = this.isContextual(104); if (isStatic) { if (this.parseClassMemberFromModifier(classBody, member)) { @@ -14007,13 +15494,15 @@ const privateMethod = member; const publicProp = member; const privateProp = member; + const accessorProp = member; const method = publicMethod; const publicMember = publicMethod; member.static = isStatic; + this.parsePropertyNamePrefixOperator(member); - if (this.eat(46)) { + if (this.eat(55)) { method.kind = "method"; - const isPrivateName = this.match(125); + const isPrivateName = this.match(134); this.parseClassElementName(method); if (isPrivateName) { @@ -14022,7 +15511,9 @@ } if (this.isNonstaticConstructor(publicMethod)) { - this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsGenerator); + this.raise(Errors.ConstructorIsGenerator, { + at: publicMethod.key + }); } this.pushClassMethod(classBody, publicMethod, true, false, false, false); @@ -14030,9 +15521,9 @@ } const isContextual = tokenIsIdentifier(this.state.type) && !this.state.containsEsc; - const isPrivate = this.match(125); + const isPrivate = this.match(134); const key = this.parseClassElementName(member); - const maybeQuestionTokenStart = this.state.start; + const maybeQuestionTokenStartLoc = this.state.startLoc; this.parsePostMemberNameModifiers(publicMember); if (this.isClassMethod()) { @@ -14050,11 +15541,15 @@ publicMethod.kind = "constructor"; if (state.hadConstructor && !this.hasPlugin("typescript")) { - this.raise(key.start, ErrorMessages.DuplicateConstructor); + this.raise(Errors.DuplicateConstructor, { + at: key + }); } if (isConstructor && this.hasPlugin("typescript") && member.override) { - this.raise(key.start, ErrorMessages.OverrideOnConstructor); + this.raise(Errors.OverrideOnConstructor, { + at: key + }); } state.hadConstructor = true; @@ -14070,14 +15565,14 @@ } } else if (isContextual && key.name === "async" && !this.isLineTerminator()) { this.resetPreviousNodeTrailingComments(key); - const isGenerator = this.eat(46); + const isGenerator = this.eat(55); if (publicMember.optional) { - this.unexpected(maybeQuestionTokenStart); + this.unexpected(maybeQuestionTokenStartLoc); } method.kind = "method"; - const isPrivate = this.match(125); + const isPrivate = this.match(134); this.parseClassElementName(method); this.parsePostMemberNameModifiers(publicMember); @@ -14085,28 +15580,38 @@ this.pushClassPrivateMethod(classBody, privateMethod, isGenerator, true); } else { if (this.isNonstaticConstructor(publicMethod)) { - this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsAsync); + this.raise(Errors.ConstructorIsAsync, { + at: publicMethod.key + }); } this.pushClassMethod(classBody, publicMethod, isGenerator, true, false, false); } - } else if (isContextual && (key.name === "get" || key.name === "set") && !(this.match(46) && this.isLineTerminator())) { + } else if (isContextual && (key.name === "get" || key.name === "set") && !(this.match(55) && this.isLineTerminator())) { this.resetPreviousNodeTrailingComments(key); method.kind = key.name; - const isPrivate = this.match(125); + const isPrivate = this.match(134); this.parseClassElementName(publicMethod); if (isPrivate) { this.pushClassPrivateMethod(classBody, privateMethod, false, false); } else { if (this.isNonstaticConstructor(publicMethod)) { - this.raise(publicMethod.key.start, ErrorMessages.ConstructorIsAccessor); + this.raise(Errors.ConstructorIsAccessor, { + at: publicMethod.key + }); } this.pushClassMethod(classBody, publicMethod, false, false, false, false); } this.checkGetterSetterParams(publicMethod); + } else if (isContextual && key.name === "accessor" && !this.isLineTerminator()) { + this.expectPlugin("decoratorAutoAccessors"); + this.resetPreviousNodeTrailingComments(key); + const isPrivate = this.match(134); + this.parseClassElementName(publicProp); + this.pushClassAccessorProperty(classBody, accessorProp, isPrivate); } else if (this.isLineTerminator()) { if (isPrivate) { this.pushClassPrivateProperty(classBody, privateProp); @@ -14121,25 +15626,33 @@ parseClassElementName(member) { const { type, - value, - start + value } = this.state; - if ((type === 119 || type === 120) && member.static && value === "prototype") { - this.raise(start, ErrorMessages.StaticPrototype); + if ((type === 128 || type === 129) && member.static && value === "prototype") { + this.raise(Errors.StaticPrototype, { + at: this.state.startLoc + }); } - if (type === 125 && value === "constructor") { - this.raise(start, ErrorMessages.ConstructorClassPrivateField); + if (type === 134) { + if (value === "constructor") { + this.raise(Errors.ConstructorClassPrivateField, { + at: this.state.startLoc + }); + } + + const key = this.parsePrivateName(); + member.key = key; + return key; } - return this.parsePropertyName(member, true); + return this.parsePropertyName(member); } parseClassStaticBlock(classBody, member) { var _member$decorators; - this.expectPlugin("classStaticBlock", member.start); this.scope.enter(SCOPE_CLASS | SCOPE_STATIC_BLOCK | SCOPE_SUPER); const oldLabels = this.state.labels; this.state.labels = []; @@ -14152,13 +15665,17 @@ classBody.body.push(this.finishNode(member, "StaticBlock")); if ((_member$decorators = member.decorators) != null && _member$decorators.length) { - this.raise(member.start, ErrorMessages.DecoratorStaticBlock); + this.raise(Errors.DecoratorStaticBlock, { + at: member + }); } } pushClassProperty(classBody, prop) { if (!prop.computed && (prop.key.name === "constructor" || prop.key.value === "constructor")) { - this.raise(prop.key.start, ErrorMessages.ConstructorClassField); + this.raise(Errors.ConstructorClassField, { + at: prop.key + }); } classBody.body.push(this.parseClassProperty(prop)); @@ -14167,7 +15684,26 @@ pushClassPrivateProperty(classBody, prop) { const node = this.parseClassPrivateProperty(prop); classBody.body.push(node); - this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), CLASS_ELEMENT_OTHER, node.key.start); + this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), CLASS_ELEMENT_OTHER, node.key.loc.start); + } + + pushClassAccessorProperty(classBody, prop, isPrivate) { + if (!isPrivate && !prop.computed) { + const key = prop.key; + + if (key.name === "constructor" || key.value === "constructor") { + this.raise(Errors.ConstructorClassField, { + at: key + }); + } + } + + const node = this.parseClassAccessorProperty(prop); + classBody.body.push(node); + + if (isPrivate) { + this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), CLASS_ELEMENT_OTHER, node.key.loc.start); + } } pushClassMethod(classBody, method, isGenerator, isAsync, isConstructor, allowsDirectSuper) { @@ -14178,7 +15714,11 @@ const node = this.parseMethod(method, isGenerator, isAsync, false, false, "ClassPrivateMethod", true); classBody.body.push(node); const kind = node.kind === "get" ? node.static ? CLASS_ELEMENT_STATIC_GETTER : CLASS_ELEMENT_INSTANCE_GETTER : node.kind === "set" ? node.static ? CLASS_ELEMENT_STATIC_SETTER : CLASS_ELEMENT_INSTANCE_SETTER : CLASS_ELEMENT_OTHER; - this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), kind, node.key.start); + this.declareClassPrivateMethodInScope(node, kind); + } + + declareClassPrivateMethodInScope(node, kind) { + this.classScope.declarePrivateName(this.getPrivateNameSV(node.key), kind, node.key.loc.start); } parsePostMemberNameModifiers(methodOrProp) {} @@ -14195,11 +15735,17 @@ return this.finishNode(node, "ClassProperty"); } + parseClassAccessorProperty(node) { + this.parseInitializer(node); + this.semicolon(); + return this.finishNode(node, "ClassAccessorProperty"); + } + parseInitializer(node) { this.scope.enter(SCOPE_CLASS | SCOPE_SUPER); this.expressionScope.enter(newExpressionScope()); this.prodParam.enter(PARAM); - node.value = this.eat(27) ? this.parseMaybeAssignAllowIn() : null; + node.value = this.eat(29) ? this.parseMaybeAssignAllowIn() : null; this.expressionScope.exit(); this.prodParam.exit(); this.scope.exit(); @@ -14210,19 +15756,21 @@ node.id = this.parseIdentifier(); if (isStatement) { - this.checkLVal(node.id, "class name", bindingType); + this.declareNameFromIdentifier(node.id, bindingType); } } else { if (optionalId || !isStatement) { node.id = null; } else { - this.unexpected(null, ErrorMessages.MissingClassName); + throw this.raise(Errors.MissingClassName, { + at: this.state.startLoc + }); } } } parseClassSuper(node) { - node.superClass = this.eat(72) ? this.parseExprSubscripts() : null; + node.superClass = this.eat(81) ? this.parseExprSubscripts() : null; } parseExport(node) { @@ -14259,7 +15807,7 @@ return this.finishNode(node, "ExportNamedDeclaration"); } - if (this.eat(56)) { + if (this.eat(65)) { node.declaration = this.parseExportDefaultExpression(); this.checkExport(node, true, true); return this.finishNode(node, "ExportDefaultDeclaration"); @@ -14269,7 +15817,7 @@ } eatExportStar(node) { - return this.eat(46); + return this.eat(55); } maybeParseExportDefaultSpecifier(node) { @@ -14285,7 +15833,7 @@ } maybeParseExportNamespaceSpecifier(node) { - if (this.isContextual(84)) { + if (this.isContextual(93)) { if (!node.specifiers) node.specifiers = []; const specifier = this.startNodeAt(this.state.lastTokStart, this.state.lastTokStartLoc); this.next(); @@ -14300,9 +15848,15 @@ maybeParseExportNamedSpecifiers(node) { if (this.match(5)) { if (!node.specifiers) node.specifiers = []; - node.specifiers.push(...this.parseExportSpecifiers()); + const isTypeExport = node.exportKind === "type"; + node.specifiers.push(...this.parseExportSpecifiers(isTypeExport)); node.source = null; node.declaration = null; + + if (this.hasPlugin("importAssertions")) { + node.assertions = []; + } + return true; } @@ -14313,6 +15867,11 @@ if (this.shouldParseExportDeclaration()) { node.specifiers = []; node.source = null; + + if (this.hasPlugin("importAssertions")) { + node.assertions = []; + } + node.declaration = this.parseExportDeclaration(node); return true; } @@ -14321,7 +15880,7 @@ } isAsyncFunction() { - if (!this.isContextual(86)) return false; + if (!this.isContextual(95)) return false; const next = this.nextTokenStart(); return !lineBreak.test(this.input.slice(this.state.pos, next)) && this.isUnparsedContextual(next, "function"); } @@ -14330,7 +15889,7 @@ const expr = this.startNode(); const isAsync = this.isAsyncFunction(); - if (this.match(59) || isAsync) { + if (this.match(68) || isAsync) { this.next(); if (isAsync) { @@ -14338,22 +15897,32 @@ } return this.parseFunction(expr, FUNC_STATEMENT | FUNC_NULLABLE_ID, isAsync); - } else if (this.match(71)) { + } + + if (this.match(80)) { return this.parseClass(expr, true, true); - } else if (this.match(24)) { + } + + if (this.match(26)) { if (this.hasPlugin("decorators") && this.getPluginOption("decorators", "decoratorsBeforeExport")) { - this.raise(this.state.start, ErrorMessages.DecoratorBeforeExport); + this.raise(Errors.DecoratorBeforeExport, { + at: this.state.startLoc + }); } this.parseDecorators(false); return this.parseClass(expr, true, true); - } else if (this.match(66) || this.match(65) || this.isLet()) { - throw this.raise(this.state.start, ErrorMessages.UnsupportedDefaultExport); - } else { - const res = this.parseMaybeAssignAllowIn(); - this.semicolon(); - return res; } + + if (this.match(75) || this.match(74) || this.isLet()) { + throw this.raise(Errors.UnsupportedDefaultExport, { + at: this.state.startLoc + }); + } + + const res = this.parseMaybeAssignAllowIn(); + this.semicolon(); + return res; } parseExportDeclaration(node) { @@ -14366,21 +15935,21 @@ } = this.state; if (tokenIsIdentifier(type)) { - if (type === 86 && !this.state.containsEsc || type === 90) { + if (type === 95 && !this.state.containsEsc || type === 99) { return false; } - if ((type === 117 || type === 116) && !this.state.containsEsc) { + if ((type === 126 || type === 125) && !this.state.containsEsc) { const { type: nextType } = this.lookahead(); - if (tokenIsIdentifier(nextType) && nextType !== 88 || nextType === 5) { + if (tokenIsIdentifier(nextType) && nextType !== 97 || nextType === 5) { this.expectOnePlugin(["flow", "typescript"]); return false; } } - } else if (!this.match(56)) { + } else if (!this.match(65)) { return false; } @@ -14391,7 +15960,7 @@ return true; } - if (this.match(56) && hasFrom) { + if (this.match(65) && hasFrom) { const nextAfterFrom = this.input.charCodeAt(this.nextTokenStartSince(next + 4)); return nextAfterFrom === 34 || nextAfterFrom === 39; } @@ -14400,7 +15969,7 @@ } parseExportFrom(node, expect) { - if (this.eatContextual(88)) { + if (this.eatContextual(97)) { node.source = this.parseImportSource(); this.checkExport(node); const assertions = this.maybeParseImportAssertions(); @@ -14408,12 +15977,8 @@ if (assertions) { node.assertions = assertions; } - } else { - if (expect) { - this.unexpected(); - } else { - node.source = null; - } + } else if (expect) { + this.unexpected(); } this.semicolon(); @@ -14424,19 +15989,21 @@ type } = this.state; - if (type === 24) { + if (type === 26) { this.expectOnePlugin(["decorators", "decorators-legacy"]); if (this.hasPlugin("decorators")) { if (this.getPluginOption("decorators", "decoratorsBeforeExport")) { - this.unexpected(this.state.start, ErrorMessages.DecoratorBeforeExport); - } else { - return true; + throw this.raise(Errors.DecoratorBeforeExport, { + at: this.state.startLoc + }); } + + return true; } } - return type === 65 || type === 66 || type === 59 || type === 71 || this.isLet() || this.isAsyncFunction(); + return type === 74 || type === 75 || type === 68 || type === 80 || this.isLet() || this.isAsyncFunction(); } checkExport(node, checkNames, isDefault, isFrom) { @@ -14450,7 +16017,9 @@ const declaration = node.declaration; if (declaration.type === "Identifier" && declaration.name === "from" && declaration.end - declaration.start === 4 && !((_declaration$extra = declaration.extra) != null && _declaration$extra.parenthesized)) { - this.raise(declaration.start, ErrorMessages.ExportDefaultFromAsIdentifier); + this.raise(Errors.ExportDefaultFromAsIdentifier, { + at: declaration + }); } } } else if (node.specifiers && node.specifiers.length) { @@ -14458,8 +16027,8 @@ const { exported } = specifier; - const exportedName = exported.type === "Identifier" ? exported.name : exported.value; - this.checkDuplicateExports(specifier, exportedName); + const exportName = exported.type === "Identifier" ? exported.name : exported.value; + this.checkDuplicateExports(specifier, exportName); if (!isFrom && specifier.local) { const { @@ -14467,9 +16036,13 @@ } = specifier; if (local.type !== "Identifier") { - this.raise(specifier.start, ErrorMessages.ExportBindingIsString, local.value, exportedName); + this.raise(Errors.ExportBindingIsString, { + at: specifier, + localName: local.value, + exportName + }); } else { - this.checkReservedWord(local.name, local.start, true, false); + this.checkReservedWord(local.name, local.loc.start, true, false); this.scope.checkLocalExport(local); } } @@ -14490,7 +16063,9 @@ const currentContextDecorators = this.state.decoratorStack[this.state.decoratorStack.length - 1]; if (currentContextDecorators.length) { - throw this.raise(node.start, ErrorMessages.UnsupportedDecoratorExport); + throw this.raise(Errors.UnsupportedDecoratorExport, { + at: node + }); } } @@ -14516,15 +16091,24 @@ } } - checkDuplicateExports(node, name) { - if (this.exportedIdentifiers.has(name)) { - this.raise(node.start, name === "default" ? ErrorMessages.DuplicateDefaultExport : ErrorMessages.DuplicateExport, name); + checkDuplicateExports(node, exportName) { + if (this.exportedIdentifiers.has(exportName)) { + if (exportName === "default") { + this.raise(Errors.DuplicateDefaultExport, { + at: node + }); + } else { + this.raise(Errors.DuplicateExport, { + at: node, + exportName + }); + } } - this.exportedIdentifiers.add(name); + this.exportedIdentifiers.add(exportName); } - parseExportSpecifiers() { + parseExportSpecifiers(isInTypeExport) { const nodes = []; let first = true; this.expect(5); @@ -14537,32 +16121,38 @@ if (this.eat(8)) break; } + const isMaybeTypeOnly = this.isContextual(126); + const isString = this.match(129); const node = this.startNode(); - const isString = this.match(120); - const local = this.parseModuleExportName(); - node.local = local; - - if (this.eatContextual(84)) { - node.exported = this.parseModuleExportName(); - } else if (isString) { - node.exported = cloneStringLiteral(local); - } else { - node.exported = cloneIdentifier(local); - } - - nodes.push(this.finishNode(node, "ExportSpecifier")); + node.local = this.parseModuleExportName(); + nodes.push(this.parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly)); } return nodes; } + parseExportSpecifier(node, isString, isInTypeExport, isMaybeTypeOnly) { + if (this.eatContextual(93)) { + node.exported = this.parseModuleExportName(); + } else if (isString) { + node.exported = cloneStringLiteral(node.local); + } else if (!node.exported) { + node.exported = cloneIdentifier(node.local); + } + + return this.finishNode(node, "ExportSpecifier"); + } + parseModuleExportName() { - if (this.match(120)) { + if (this.match(129)) { const result = this.parseStringLiteral(this.state.value); const surrogate = result.value.match(loneSurrogate); if (surrogate) { - this.raise(result.start, ErrorMessages.ModuleExportNameHasLoneSurrogate, surrogate[0].charCodeAt(0).toString(16)); + this.raise(Errors.ModuleExportNameHasLoneSurrogate, { + at: result, + surrogateCharCode: surrogate[0].charCodeAt(0) + }); } return result; @@ -14574,12 +16164,12 @@ parseImport(node) { node.specifiers = []; - if (!this.match(120)) { + if (!this.match(129)) { const hasDefault = this.maybeParseDefaultImportSpecifier(node); const parseNext = !hasDefault || this.eat(12); const hasStar = parseNext && this.maybeParseStarImportSpecifier(node); if (parseNext && !hasStar) this.parseNamedImportSpecifiers(node); - this.expectContextual(88); + this.expectContextual(97); } node.source = this.parseImportSource(); @@ -14600,7 +16190,7 @@ } parseImportSource() { - if (!this.match(120)) this.unexpected(); + if (!this.match(129)) this.unexpected(); return this.parseExprAtom(); } @@ -14608,10 +16198,17 @@ return tokenIsIdentifier(this.state.type); } - parseImportSpecifierLocal(node, specifier, type, contextDescription) { + parseImportSpecifierLocal(node, specifier, type) { specifier.local = this.parseIdentifier(); - this.checkLVal(specifier.local, contextDescription, BIND_LEXICAL); - node.specifiers.push(this.finishNode(specifier, type)); + node.specifiers.push(this.finishImportSpecifier(specifier, type)); + } + + finishImportSpecifier(specifier, type) { + this.checkLVal(specifier.local, { + in: specifier, + binding: BIND_LEXICAL + }); + return this.finishNode(specifier, type); } parseAssertEntries() { @@ -14627,12 +16224,15 @@ const keyName = this.state.value; if (attrNames.has(keyName)) { - this.raise(this.state.start, ErrorMessages.ModuleAttributesWithDuplicateKeys, keyName); + this.raise(Errors.ModuleAttributesWithDuplicateKeys, { + at: this.state.startLoc, + key: keyName + }); } attrNames.add(keyName); - if (this.match(120)) { + if (this.match(129)) { node.key = this.parseStringLiteral(keyName); } else { node.key = this.parseIdentifier(true); @@ -14640,8 +16240,10 @@ this.expect(14); - if (!this.match(120)) { - throw this.unexpected(this.state.start, ErrorMessages.ModuleAttributeInvalidValue); + if (!this.match(129)) { + throw this.raise(Errors.ModuleAttributeInvalidValue, { + at: this.state.startLoc + }); } node.value = this.parseStringLiteral(this.state.value); @@ -14653,7 +16255,7 @@ } maybeParseModuleAttributes() { - if (this.match(67) && !this.hasPrecedingLineBreak()) { + if (this.match(76) && !this.hasPrecedingLineBreak()) { this.expectPlugin("moduleAttributes"); this.next(); } else { @@ -14669,18 +16271,25 @@ node.key = this.parseIdentifier(true); if (node.key.name !== "type") { - this.raise(node.key.start, ErrorMessages.ModuleAttributeDifferentFromType, node.key.name); + this.raise(Errors.ModuleAttributeDifferentFromType, { + at: node.key + }); } if (attributes.has(node.key.name)) { - this.raise(node.key.start, ErrorMessages.ModuleAttributesWithDuplicateKeys, node.key.name); + this.raise(Errors.ModuleAttributesWithDuplicateKeys, { + at: node.key, + key: node.key.name + }); } attributes.add(node.key.name); this.expect(14); - if (!this.match(120)) { - throw this.unexpected(this.state.start, ErrorMessages.ModuleAttributeInvalidValue); + if (!this.match(129)) { + throw this.raise(Errors.ModuleAttributeInvalidValue, { + at: this.state.startLoc + }); } node.value = this.parseStringLiteral(this.state.value); @@ -14692,7 +16301,7 @@ } maybeParseImportAssertions() { - if (this.isContextual(85) && !this.hasPrecedingLineBreak()) { + if (this.isContextual(94) && !this.hasPrecedingLineBreak()) { this.expectPlugin("importAssertions"); this.next(); } else { @@ -14708,7 +16317,7 @@ maybeParseDefaultImportSpecifier(node) { if (this.shouldParseDefaultImport(node)) { - this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier", "default import specifier"); + this.parseImportSpecifierLocal(node, this.startNode(), "ImportDefaultSpecifier"); return true; } @@ -14716,11 +16325,11 @@ } maybeParseStarImportSpecifier(node) { - if (this.match(46)) { + if (this.match(55)) { const specifier = this.startNode(); this.next(); - this.expectContextual(84); - this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier", "import namespace specifier"); + this.expectContextual(93); + this.parseImportSpecifierLocal(node, specifier, "ImportNamespaceSpecifier"); return true; } @@ -14736,23 +16345,26 @@ first = false; } else { if (this.eat(14)) { - throw this.raise(this.state.start, ErrorMessages.DestructureNamedImport); + throw this.raise(Errors.DestructureNamedImport, { + at: this.state.startLoc + }); } this.expect(12); if (this.eat(8)) break; } - this.parseImportSpecifier(node); + const specifier = this.startNode(); + const importedIsString = this.match(129); + const isMaybeTypeOnly = this.isContextual(126); + specifier.imported = this.parseModuleExportName(); + const importSpecifier = this.parseImportSpecifier(specifier, importedIsString, node.importKind === "type" || node.importKind === "typeof", isMaybeTypeOnly); + node.specifiers.push(importSpecifier); } } - parseImportSpecifier(node) { - const specifier = this.startNode(); - const importedIsString = this.match(120); - specifier.imported = this.parseModuleExportName(); - - if (this.eatContextual(84)) { + parseImportSpecifier(specifier, importedIsString, isInTypeOnlyImport, isMaybeTypeOnly) { + if (this.eatContextual(93)) { specifier.local = this.parseIdentifier(); } else { const { @@ -14760,15 +16372,20 @@ } = specifier; if (importedIsString) { - throw this.raise(specifier.start, ErrorMessages.ImportBindingIsString, imported.value); + throw this.raise(Errors.ImportBindingIsString, { + at: specifier, + importName: imported.value + }); } - this.checkReservedWord(imported.name, specifier.start, true, true); - specifier.local = cloneIdentifier(imported); + this.checkReservedWord(imported.name, specifier.loc.start, true, true); + + if (!specifier.local) { + specifier.local = cloneIdentifier(imported); + } } - this.checkLVal(specifier.local, "import specifier", BIND_LEXICAL); - node.specifiers.push(this.finishNode(specifier, "ImportSpecifier")); + return this.finishImportSpecifier(specifier, "ImportSpecifier"); } isThisParam(param) { -- Gitblit v1.8.0