diff --git a/packages/babel-parser/src/parser/error-message.js b/packages/babel-parser/src/parser/error-message.js index 2a46b8b7be00..bb02300b9356 100644 --- a/packages/babel-parser/src/parser/error-message.js +++ b/packages/babel-parser/src/parser/error-message.js @@ -1,4 +1,7 @@ // @flow + +import type { ErrorTemplates } from "../parser/error"; + /* eslint sort-keys: "error" */ /** @@ -6,215 +9,628 @@ */ // The Errors key follows https://cs.chromium.org/chromium/src/v8/src/common/message-template.h unless it does not exist -export const ErrorMessages = Object.freeze({ - 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: "getter must not have any formal parameters", - BadSetterArity: "setter must have exactly one formal parameter", - BadSetterRestParameter: - "setter 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", - 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()", - ImportMetaOutsideModule: `import.meta may appear only with 'sourceType: "module"'`, - ImportOutsideModule: `'import' and 'export' may appear only with 'sourceType: "module"'`, - 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", - ParamDupe: "Argument name clash", - PatternHasAccessor: "Object pattern can't contain getter or setter", - PatternHasMethod: "Object pattern can't contain methods", - 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: - "Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' 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", - 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", +export const ErrorMessages: ErrorTemplates = Object.freeze({ + AccessorIsGenerator: { + code: "AccessorIsGenerator", + template: "A %0ter cannot be a generator", + }, + ArgumentsInClass: { + code: "ArgumentsInClass", + template: "'arguments' is only allowed in functions and class methods", + }, + AsyncFunctionInSingleStatementContext: { + code: "AsyncFunctionInSingleStatementContext", + template: + "Async functions can only be declared at the top level or inside a block", + }, + AwaitBindingIdentifier: { + code: "AwaitBindingIdentifier", + template: "Can not use 'await' as identifier inside an async function", + }, + AwaitBindingIdentifierInStaticBlock: { + code: "AwaitBindingIdentifierInStaticBlock", + template: "Can not use 'await' as identifier inside a static block", + }, + AwaitExpressionFormalParameter: { + code: "AwaitExpressionFormalParameter", + template: "await is not allowed in async function parameters", + }, + AwaitNotInAsyncContext: { + code: "AwaitNotInAsyncContext", + template: + "'await' is only allowed within async functions and at the top levels of modules", + }, + AwaitNotInAsyncFunction: { + code: "AwaitNotInAsyncFunction", + template: "'await' is only allowed within async functions", + }, + BadGetterArity: { + code: "BadGetterArity", + template: "getter must not have any formal parameters", + }, + BadSetterArity: { + code: "BadSetterArity", + template: "setter must have exactly one formal parameter", + }, + BadSetterRestParameter: { + code: "BadSetterRestParameter", + template: "setter function argument must not be a rest parameter", + }, + ConstructorClassField: { + code: "ConstructorClassField", + template: "Classes may not have a field named 'constructor'", + }, + ConstructorClassPrivateField: { + code: "ConstructorClassPrivateField", + template: "Classes may not have a private field named '#constructor'", + }, + ConstructorIsAccessor: { + code: "ConstructorIsAccessor", + template: "Class constructor may not be an accessor", + }, + ConstructorIsAsync: { + code: "ConstructorIsAsync", + template: "Constructor can't be an async function", + }, + ConstructorIsGenerator: { + code: "ConstructorIsGenerator", + template: "Constructor can't be a generator", + }, + DeclarationMissingInitializer: { + code: "DeclarationMissingInitializer", + template: "%0 require an initialization value", + }, + DecoratorBeforeExport: { + code: "DecoratorBeforeExport", + template: + "Decorators must be placed *before* the 'export' keyword. You can set the 'decoratorsBeforeExport' option to false to use the 'export @decorator class {}' syntax", + }, + DecoratorConstructor: { + code: "DecoratorConstructor", + template: + "Decorators can't be used with a constructor. Did you mean '@dec class { ... }'?", + }, + DecoratorExportClass: { + code: "DecoratorExportClass", + template: + "Using the export keyword between a decorator and a class is not allowed. Please use `export @dec class` instead.", + }, + DecoratorSemicolon: { + code: "DecoratorSemicolon", + template: "Decorators must not be followed by a semicolon", + }, + DecoratorStaticBlock: { + code: "DecoratorStaticBlock", + template: "Decorators can't be used with a static block", + }, + DeletePrivateField: { + code: "DeletePrivateField", + template: "Deleting a private field is not allowed", + }, + DestructureNamedImport: { + code: "DestructureNamedImport", + template: + "ES2015 named imports do not destructure. Use another statement for destructuring after the import.", + }, + DuplicateConstructor: { + code: "DuplicateConstructor", + template: "Duplicate constructor in the same class", + }, + DuplicateDefaultExport: { + code: "DuplicateDefaultExport", + template: "Only one default export allowed per module.", + }, + DuplicateExport: { + code: "DuplicateExport", + template: + "`%0` has already been exported. Exported identifiers must be unique.", + }, + DuplicateProto: { + code: "DuplicateProto", + template: "Redefinition of __proto__ property", + }, + DuplicateRegExpFlags: { + code: "DuplicateRegExpFlags", + template: "Duplicate regular expression flag", + }, + ElementAfterRest: { + code: "ElementAfterRest", + template: "Rest element must be last element", + }, + EscapedCharNotAnIdentifier: { + code: "EscapedCharNotAnIdentifier", + template: "Invalid Unicode escape", + }, + ExportBindingIsString: { + code: "ExportBindingIsString", + template: + "A string literal cannot be used as an exported binding without `from`.\n- Did you mean `export { '%0' as '%1' } from 'some-module'`?", + }, + ExportDefaultFromAsIdentifier: { + code: "ExportDefaultFromAsIdentifier", + template: "'from' is not allowed as an identifier after 'export default'", + }, + ForInOfLoopInitializer: { + code: "ForInOfLoopInitializer", + template: "%0 loop variable declaration may not have an initializer", + }, + GeneratorInSingleStatementContext: { + code: "GeneratorInSingleStatementContext", + template: + "Generators can only be declared at the top level or inside a block", + }, + IllegalBreakContinue: { + code: "IllegalBreakContinue", + template: "Unsyntactic %0", + }, + IllegalLanguageModeDirective: { + code: "IllegalLanguageModeDirective", + template: + "Illegal 'use strict' directive in function with non-simple parameter list", + }, + IllegalReturn: { + code: "IllegalReturn", + template: "'return' outside of function", + }, + ImportBindingIsString: { + code: "ImportBindingIsString", + template: + 'A string literal cannot be used as an imported binding.\n- Did you mean `import { "%0" as foo }`?', + }, + ImportCallArgumentTrailingComma: { + code: "ImportCallArgumentTrailingComma", + template: "Trailing comma is disallowed inside import(...) arguments", + }, + ImportCallArity: { + code: "ImportCallArity", + template: "import() requires exactly %0", + }, + ImportCallNotNewExpression: { + code: "ImportCallNotNewExpression", + template: "Cannot use new with import(...)", + }, + ImportCallSpreadArgument: { + code: "ImportCallSpreadArgument", + template: "... is not allowed in import()", + }, + InvalidBigIntLiteral: { + code: "InvalidBigIntLiteral", + template: "Invalid BigIntLiteral", + }, + InvalidCodePoint: { + code: "InvalidCodePoint", + template: "Code point out of bounds", + }, + InvalidDecimal: { + code: "InvalidDecimal", + template: "Invalid decimal", + }, + InvalidDigit: { + code: "InvalidDigit", + template: "Expected number in radix %0", + }, + InvalidEscapeSequence: { + code: "InvalidEscapeSequence", + template: "Bad character escape sequence", + }, + InvalidEscapeSequenceTemplate: { + code: "InvalidEscapeSequenceTemplate", + template: "Invalid escape sequence in template", + }, + InvalidEscapedReservedWord: { + code: "InvalidEscapedReservedWord", + template: "Escape sequence in keyword %0", + }, + InvalidIdentifier: { + code: "InvalidIdentifier", + template: "Invalid identifier %0", + }, + InvalidLhs: { + code: "InvalidLhs", + template: "Invalid left-hand side in %0", + }, + InvalidLhsBinding: { + code: "InvalidLhsBinding", + template: "Binding invalid left-hand side in %0", + }, + InvalidNumber: { + code: "InvalidNumber", + template: "Invalid number", + }, + InvalidOrMissingExponent: { + code: "InvalidOrMissingExponent", + template: "Floating-point numbers require a valid exponent after the 'e'", + }, + InvalidOrUnexpectedToken: { + code: "InvalidOrUnexpectedToken", + template: "Unexpected character '%0'", + }, + InvalidParenthesizedAssignment: { + code: "InvalidParenthesizedAssignment", + template: "Invalid parenthesized assignment pattern", + }, + InvalidPrivateFieldResolution: { + code: "InvalidPrivateFieldResolution", + template: "Private name #%0 is not defined", + }, + InvalidPropertyBindingPattern: { + code: "InvalidPropertyBindingPattern", + template: "Binding member expression", + }, + InvalidRecordProperty: { + code: "InvalidRecordProperty", + template: + "Only properties and spread elements are allowed in record definitions", + }, + InvalidRestAssignmentPattern: { + code: "InvalidRestAssignmentPattern", + template: "Invalid rest operator's argument", + }, + LabelRedeclaration: { + code: "LabelRedeclaration", + template: "Label '%0' is already declared", + }, + LetInLexicalBinding: { + code: "LetInLexicalBinding", + template: + "'let' is not allowed to be used as a name in 'let' or 'const' declarations.", + }, + LineTerminatorBeforeArrow: { + code: "LineTerminatorBeforeArrow", + template: "No line break is allowed before '=>'", + }, + MalformedRegExpFlags: { + code: "MalformedRegExpFlags", + template: "Invalid regular expression flag", + }, + MissingClassName: { + code: "MissingClassName", + template: "A class name is required", + }, + MissingEqInAssignment: { + code: "MissingEqInAssignment", + template: "Only '=' operator can be used for specifying default value.", + }, + MissingSemicolon: { + code: "MissingSemicolon", + template: "Missing semicolon", + }, + MissingUnicodeEscape: { + code: "MissingUnicodeEscape", + template: "Expecting Unicode escape sequence \\uXXXX", + }, + MixingCoalesceWithLogical: { + code: "MixingCoalesceWithLogical", + template: + "Nullish coalescing operator(??) requires parens when mixing with logical operators", + }, + ModuleAttributeDifferentFromType: { + code: "ModuleAttributeDifferentFromType", + template: "The only accepted module attribute is `type`", + }, + ModuleAttributeInvalidValue: { + code: "ModuleAttributeInvalidValue", + template: "Only string literals are allowed as module attribute values", + }, + ModuleAttributesWithDuplicateKeys: { + code: "ModuleAttributesWithDuplicateKeys", + template: 'Duplicate key "%0" is not allowed in module attributes', + }, + ModuleExportNameHasLoneSurrogate: { + code: "ModuleExportNameHasLoneSurrogate", + template: "An export name cannot include a lone surrogate, found '\\u%0'", + }, + ModuleExportUndefined: { + code: "ModuleExportUndefined", + template: "Export '%0' is not defined", + }, + MultipleDefaultsInSwitch: { + code: "MultipleDefaultsInSwitch", + template: "Multiple default clauses", + }, + NewlineAfterThrow: { + code: "NewlineAfterThrow", + template: "Illegal newline after throw", + }, + NoCatchOrFinally: { + code: "NoCatchOrFinally", + template: "Missing catch or finally clause", + }, + NumberIdentifier: { + code: "NumberIdentifier", + template: "Identifier directly after number", + }, + NumericSeparatorInEscapeSequence: { + code: "NumericSeparatorInEscapeSequence", + template: + "Numeric separators are not allowed inside unicode escape sequences or hex escape sequences", + }, + ObsoleteAwaitStar: { + code: "ObsoleteAwaitStar", + template: + "await* has been removed from the async functions proposal. Use Promise.all() instead.", + }, + OptionalChainingNoNew: { + code: "OptionalChainingNoNew", + template: "constructors in/after an Optional Chain are not allowed", + }, + OptionalChainingNoTemplate: { + code: "OptionalChainingNoTemplate", + template: "Tagged Template Literals are not allowed in optionalChain", + }, + ParamDupe: { + code: "ParamDupe", + template: "Argument name clash", + }, + PatternHasAccessor: { + code: "PatternHasAccessor", + template: "Object pattern can't contain getter or setter", + }, + PatternHasMethod: { + code: "PatternHasMethod", + template: "Object pattern can't contain methods", + }, + PipelineBodyNoArrow: { + code: "PipelineBodyNoArrow", + template: + 'Unexpected arrow "=>" after pipeline body; arrow function in pipeline body must be parenthesized', + }, + PipelineBodySequenceExpression: { + code: "PipelineBodySequenceExpression", + template: "Pipeline body may not be a comma-separated sequence expression", + }, + PipelineHeadSequenceExpression: { + code: "PipelineHeadSequenceExpression", + template: + "Pipeline head should not be a comma-separated sequence expression", + }, + PipelineTopicUnused: { + code: "PipelineTopicUnused", + template: "Pipeline is in topic style but does not use topic reference", + }, + PrimaryTopicNotAllowed: { + code: "PrimaryTopicNotAllowed", + template: + "Topic reference was used in a lexical context without topic binding", + }, + PrimaryTopicRequiresSmartPipeline: { + code: "PrimaryTopicRequiresSmartPipeline", + template: + "Primary Topic Reference found but pipelineOperator not passed 'smart' for 'proposal' option.", + }, + PrivateInExpectedIn: { + code: "PrivateInExpectedIn", + template: + "Private names are only allowed in property accesses (`obj.#%0`) or in `in` expressions (`#%0 in obj`)", + }, + PrivateNameRedeclaration: { + code: "PrivateNameRedeclaration", + template: "Duplicate private name #%0", + }, + RecordExpressionBarIncorrectEndSyntaxType: { + code: "RecordExpressionBarIncorrectEndSyntaxType", + template: + "Record expressions ending with '|}' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + }, + RecordExpressionBarIncorrectStartSyntaxType: { + code: "RecordExpressionBarIncorrectStartSyntaxType", + template: + "Record expressions starting with '{|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + }, + RecordExpressionHashIncorrectStartSyntaxType: { + code: "RecordExpressionHashIncorrectStartSyntaxType", + template: + "Record expressions starting with '#{' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'", + }, + RecordNoProto: { + code: "RecordNoProto", + template: "'__proto__' is not allowed in Record expressions", + }, + RestTrailingComma: { + code: "RestTrailingComma", + template: "Unexpected trailing comma after rest element", + }, + SloppyFunction: { + code: "SloppyFunction", + template: + "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: { + code: "StaticPrototype", + template: "Classes may not have static property named prototype", + }, + StrictDelete: { + code: "StrictDelete", + template: "Deleting local variable in strict mode", + }, + StrictEvalArguments: { + code: "StrictEvalArguments", + template: "Assigning to '%0' in strict mode", + }, + StrictEvalArgumentsBinding: { + code: "StrictEvalArgumentsBinding", + template: "Binding '%0' in strict mode", + }, + StrictFunction: { + code: "StrictFunction", + template: + "In strict mode code, functions can only be declared at top level or inside a block", + }, + StrictNumericEscape: { + code: "StrictNumericEscape", + template: "The only valid numeric escape in strict mode is '\\0'", + }, + StrictOctalLiteral: { + code: "StrictOctalLiteral", + template: "Legacy octal literals are not allowed in strict mode", + }, + StrictWith: { + code: "StrictWith", + template: "'with' in strict mode", + }, + SuperNotAllowed: { + code: "SuperNotAllowed", + template: + "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: { + code: "SuperPrivateField", + template: "Private fields can't be accessed on super", + }, + TrailingDecorator: { + code: "TrailingDecorator", + template: "Decorators must be attached to a class element", + }, + TupleExpressionBarIncorrectEndSyntaxType: { + code: "TupleExpressionBarIncorrectEndSyntaxType", + template: + "Tuple expressions ending with '|]' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + }, + TupleExpressionBarIncorrectStartSyntaxType: { + code: "TupleExpressionBarIncorrectStartSyntaxType", + template: + "Tuple expressions starting with '[|' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'bar'", + }, + TupleExpressionHashIncorrectStartSyntaxType: { + code: "TupleExpressionHashIncorrectStartSyntaxType", + template: + "Tuple expressions starting with '#[' are only allowed when the 'syntaxType' option of the 'recordAndTuple' plugin is set to 'hash'", + }, + UnexpectedArgumentPlaceholder: { + code: "UnexpectedArgumentPlaceholder", + template: "Unexpected argument placeholder", + }, + UnexpectedAwaitAfterPipelineBody: { + code: "UnexpectedAwaitAfterPipelineBody", + template: + 'Unexpected "await" after pipeline body; await must have parentheses in minimal proposal', + }, + UnexpectedDigitAfterHash: { + code: "UnexpectedDigitAfterHash", + template: "Unexpected digit after hash token", + }, + UnexpectedImportExport: { + code: "UnexpectedImportExport", + template: "'import' and 'export' may only appear at the top level", + }, + UnexpectedKeyword: { + code: "UnexpectedKeyword", + template: "Unexpected keyword '%0'", + }, + UnexpectedLeadingDecorator: { + code: "UnexpectedLeadingDecorator", + template: "Leading decorators must be attached to a class declaration", + }, + UnexpectedLexicalDeclaration: { + code: "UnexpectedLexicalDeclaration", + template: "Lexical declaration cannot appear in a single-statement context", + }, + UnexpectedNewTarget: { + code: "UnexpectedNewTarget", + template: "new.target can only be used in functions", + }, + UnexpectedNumericSeparator: { + code: "UnexpectedNumericSeparator", + template: "A numeric separator is only allowed between two digits", + }, + UnexpectedPrivateField: { + code: "UnexpectedPrivateField", + template: + "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: { + code: "UnexpectedReservedWord", + template: "Unexpected reserved word '%0'", + }, + UnexpectedSuper: { + code: "UnexpectedSuper", + template: "super is only allowed in object methods and classes", + }, + UnexpectedToken: { + code: "UnexpectedToken", + template: "Unexpected token '%0'", + }, + UnexpectedTokenUnaryExponentiation: { + code: "UnexpectedTokenUnaryExponentiation", + template: + "Illegal expression. Wrap left hand side or entire exponentiation in parentheses.", + }, + UnsupportedBind: { + code: "UnsupportedBind", + template: "Binding should be performed on object property.", + }, + UnsupportedDecoratorExport: { + code: "UnsupportedDecoratorExport", + template: "A decorated export must export a class declaration", + }, + UnsupportedDefaultExport: { + code: "UnsupportedDefaultExport", + template: + "Only expressions, functions or classes are allowed as the `default` export.", + }, + UnsupportedImport: { + code: "UnsupportedImport", + template: "import can only be used in import() or import.meta", + }, + UnsupportedMetaProperty: { + code: "UnsupportedMetaProperty", + template: "The only valid meta property for %0 is %0.%1", + }, + UnsupportedParameterDecorator: { + code: "UnsupportedParameterDecorator", + template: "Decorators cannot be used to decorate parameters", + }, + UnsupportedPropertyDecorator: { + code: "UnsupportedPropertyDecorator", + template: "Decorators cannot be used to decorate object literal properties", + }, + UnsupportedSuper: { + code: "UnsupportedSuper", + template: + "super can only be used with function calls (i.e. super()) or in property accesses (i.e. super.prop or super[prop])", + }, + UnterminatedComment: { + code: "UnterminatedComment", + template: "Unterminated comment", + }, + UnterminatedRegExp: { + code: "UnterminatedRegExp", + template: "Unterminated regular expression", + }, + UnterminatedString: { + code: "UnterminatedString", + template: "Unterminated string constant", + }, + UnterminatedTemplate: { + code: "UnterminatedTemplate", + template: "Unterminated template", + }, + VarRedeclaration: { + code: "VarRedeclaration", + template: "Identifier '%0' has already been declared", + }, + YieldBindingIdentifier: { + code: "YieldBindingIdentifier", + template: "Can not use 'yield' as identifier inside a generator", + }, + YieldInParameter: { + code: "YieldInParameter", + template: "Yield expression is not allowed in formal parameters", + }, + ZeroDigitNumericSeparator: { + code: "ZeroDigitNumericSeparator", + template: "Numeric separator can not be used after leading 0", + }, +}); + +// These errors have a different error code than the key +export const SourceTypeModuleErrorMessages: ErrorTemplates = Object.freeze({ + ImportMetaOutsideModule: { + code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED", + template: `import.meta may appear only with 'sourceType: "module"'`, + }, + ImportOutsideModule: { + code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED", + template: `'import' and 'export' may appear only with 'sourceType: "module"'`, + }, }); diff --git a/packages/babel-parser/src/parser/error.js b/packages/babel-parser/src/parser/error.js index ead11e796bb0..4fa70995ef2f 100644 --- a/packages/babel-parser/src/parser/error.js +++ b/packages/babel-parser/src/parser/error.js @@ -18,7 +18,21 @@ type ErrorContext = { export type ParsingError = SyntaxError & ErrorContext; -export { ErrorMessages as Errors } from "./error-message"; +export type ErrorTemplate = { + code: string, + template: string, +}; + +export type ErrorTemplates = { + [key: string]: ErrorTemplate, +}; + +export type raiseFunction = (number, ErrorTemplate, ...any) => void; + +export { + ErrorMessages as Errors, + SourceTypeModuleErrorMessages as SourceTypeModuleErrors, +} from "./error-message"; export default class ParserError extends CommentsParser { // Forward-declaration: defined in tokenizer/index.js @@ -37,8 +51,12 @@ export default class ParserError extends CommentsParser { return loc; } - raise(pos: number, errorTemplate: string, ...params: any): Error | empty { - return this.raiseWithData(pos, undefined, errorTemplate, ...params); + raise( + pos: number, + { code, template }: ErrorTemplate, + ...params: any + ): Error | empty { + return this.raiseWithData(pos, { code }, template, ...params); } /** @@ -55,12 +73,12 @@ export default class ParserError extends CommentsParser { */ raiseOverwrite( pos: number, - errorTemplate: string, + { code, template }: ErrorTemplate, ...params: any ): Error | empty { const loc = this.getLocationForPosition(pos); const message = - errorTemplate.replace(/%(\d+)/g, (_, i: number) => params[i]) + + template.replace(/%(\d+)/g, (_, i: number) => params[i]) + ` (${loc.line}:${loc.column})`; if (this.options.errorRecovery) { const errors = this.state.errors; @@ -73,7 +91,7 @@ export default class ParserError extends CommentsParser { } } } - return this._raise({ loc, pos }, message); + return this._raise({ code, loc, pos }, message); } raiseWithData( diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 9a3271a8262b..7866db368ae8 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -54,7 +54,7 @@ import { newAsyncArrowScope, newExpressionScope, } from "../util/expression-scope"; -import { Errors } from "./error"; +import { Errors, SourceTypeModuleErrors } from "./error"; /*:: import type { SourceType } from "../options"; @@ -1358,11 +1358,7 @@ export default class ExpressionParser extends LValParser { if (this.isContextual("meta")) { if (!this.inModule) { - this.raiseWithData( - id.start, - { code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED" }, - Errors.ImportMetaOutsideModule, - ); + this.raise(id.start, SourceTypeModuleErrors.ImportMetaOutsideModule); } this.sawUnambiguousESM = true; } @@ -1524,14 +1520,17 @@ export default class ExpressionParser extends LValParser { const metaProp = this.parseMetaProperty(node, meta, "target"); if (!this.scope.inNonArrowFunction && !this.scope.inClass) { - let error = Errors.UnexpectedNewTarget; + let error = Errors.UnexpectedNewTarget.template; if (this.hasPlugin("classProperties")) { error += " or class properties"; } /* eslint-disable @babel/development-internal/dry-error-messages */ - this.raise(metaProp.start, error); + this.raise(metaProp.start, { + code: Errors.UnexpectedNewTarget.code, + template: error, + }); /* eslint-enable @babel/development-internal/dry-error-messages */ } diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 28813bb6de8b..2c223c7bd5ae 100644 --- a/packages/babel-parser/src/parser/statement.js +++ b/packages/babel-parser/src/parser/statement.js @@ -3,7 +3,7 @@ import * as N from "../types"; import { types as tt, type TokenType } from "../tokenizer/types"; import ExpressionParser from "./expression"; -import { Errors } from "./error"; +import { Errors, SourceTypeModuleErrors } from "./error"; import { isIdentifierChar, isIdentifierStart, @@ -324,13 +324,7 @@ export default class StatementParser extends ExpressionParser { assertModuleNodeAllowed(node: N.Node): void { if (!this.options.allowImportExportEverywhere && !this.inModule) { - this.raiseWithData( - node.start, - { - code: "BABEL_PARSER_SOURCETYPE_MODULE_REQUIRED", - }, - Errors.ImportOutsideModule, - ); + this.raise(node.start, SourceTypeModuleErrors.ImportOutsideModule); } } @@ -1690,7 +1684,7 @@ export default class StatementParser extends ExpressionParser { if (optionalId || !isStatement) { node.id = null; } else { - this.unexpected(null, Errors.MissingClassName); + this.unexpected(null, Errors.MissingClassName.template); } } } @@ -1935,7 +1929,10 @@ export default class StatementParser extends ExpressionParser { this.expectOnePlugin(["decorators", "decorators-legacy"]); if (this.hasPlugin("decorators")) { if (this.getPluginOption("decorators", "decoratorsBeforeExport")) { - this.unexpected(this.state.start, Errors.DecoratorBeforeExport); + this.unexpected( + this.state.start, + Errors.DecoratorBeforeExport.template, + ); } else { return true; } @@ -2236,7 +2233,7 @@ export default class StatementParser extends ExpressionParser { if (!this.match(tt.string)) { throw this.unexpected( this.state.start, - Errors.ModuleAttributeInvalidValue, + Errors.ModuleAttributeInvalidValue.template, ); } node.value = this.parseLiteral( @@ -2290,7 +2287,7 @@ export default class StatementParser extends ExpressionParser { if (!this.match(tt.string)) { throw this.unexpected( this.state.start, - Errors.ModuleAttributeInvalidValue, + Errors.ModuleAttributeInvalidValue.template, ); } node.value = this.parseLiteral(this.state.value, "StringLiteral"); diff --git a/packages/babel-parser/src/parser/util.js b/packages/babel-parser/src/parser/util.js index 53156c577f5d..9f63ac951262 100644 --- a/packages/babel-parser/src/parser/util.js +++ b/packages/babel-parser/src/parser/util.js @@ -142,7 +142,10 @@ export default class UtilParser extends Tokenizer { assertNoSpace(message: string = "Unexpected space."): void { if (this.state.start > this.state.lastTokEnd) { /* eslint-disable @babel/development-internal/dry-error-messages */ - this.raise(this.state.lastTokEnd, message); + this.raise(this.state.lastTokEnd, { + code: "UnexpectedSpace", + template: message, + }); /* eslint-enable @babel/development-internal/dry-error-messages */ } } @@ -158,7 +161,10 @@ export default class UtilParser extends Tokenizer { messageOrType = `Unexpected token, expected "${messageOrType.label}"`; } /* eslint-disable @babel/development-internal/dry-error-messages */ - throw this.raise(pos != null ? pos : this.state.start, messageOrType); + throw this.raise(pos != null ? pos : this.state.start, { + code: "UnexpectedToken", + template: messageOrType, + }); /* eslint-enable @babel/development-internal/dry-error-messages */ } diff --git a/packages/babel-parser/src/plugins/flow/index.js b/packages/babel-parser/src/plugins/flow/index.js index 01bf25e2f351..f036be7320f6 100644 --- a/packages/babel-parser/src/plugins/flow/index.js +++ b/packages/babel-parser/src/plugins/flow/index.js @@ -49,89 +49,221 @@ const reservedTypes = new Set([ /* eslint sort-keys: "error" */ // The Errors key follows https://github.com/facebook/flow/blob/master/src/parser/parse_error.ml unless it does not exist const FlowErrors = Object.freeze({ - 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", - OptionalBindingPattern: - "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 ` async () => {}`, use `async () => {}`", - 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", + AmbiguousConditionalArrow: { + code: "AmbiguousConditionalArrow", + template: + "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate.", + }, + AmbiguousDeclareModuleKind: { + code: "AmbiguousDeclareModuleKind", + template: + "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: { + code: "AssignReservedType", + template: "Cannot overwrite reserved type %0", + }, + DeclareClassElement: { + code: "DeclareClassElement", + template: "The `declare` modifier can only appear on class fields.", + }, + DeclareClassFieldInitializer: { + code: "DeclareClassFieldInitializer", + template: + "Initializers are not allowed in fields with the `declare` modifier.", + }, + DuplicateDeclareModuleExports: { + code: "DuplicateDeclareModuleExports", + template: "Duplicate `declare module.exports` statement", + }, + EnumBooleanMemberNotInitialized: { + code: "EnumBooleanMemberNotInitialized", + template: + "Boolean enum members need to be initialized. Use either `%0 = true,` or `%0 = false,` in enum `%1`.", + }, + EnumDuplicateMemberName: { + code: "EnumDuplicateMemberName", + template: + "Enum member names need to be unique, but the name `%0` has already been used before in enum `%1`.", + }, + EnumInconsistentMemberValues: { + code: "EnumInconsistentMemberValues", + template: + "Enum `%0` has inconsistent member initializers. Either use no initializers, or consistently use literals (either booleans, numbers, or strings) for all member initializers.", + }, + EnumInvalidExplicitType: { + code: "EnumInvalidExplicitType", + template: + "Enum type `%1` is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", + }, + EnumInvalidExplicitTypeUnknownSupplied: { + code: "EnumInvalidExplicitTypeUnknownSupplied", + template: + "Supplied enum type is not valid. Use one of `boolean`, `number`, `string`, or `symbol` in enum `%0`.", + }, + EnumInvalidMemberInitializerPrimaryType: { + code: "EnumInvalidMemberInitializerPrimaryType", + template: + "Enum `%0` has type `%2`, so the initializer of `%1` needs to be a %2 literal.", + }, + EnumInvalidMemberInitializerSymbolType: { + code: "EnumInvalidMemberInitializerSymbolType", + template: + "Symbol enum members cannot be initialized. Use `%1,` in enum `%0`.", + }, + EnumInvalidMemberInitializerUnknownType: { + code: "EnumInvalidMemberInitializerUnknownType", + template: + "The enum member initializer for `%1` needs to be a literal (either a boolean, number, or string) in enum `%0`.", + }, + EnumInvalidMemberName: { + code: "EnumInvalidMemberName", + template: + "Enum member names cannot start with lowercase 'a' through 'z'. Instead of using `%0`, consider using `%1`, in enum `%2`.", + }, + EnumNumberMemberNotInitialized: { + code: "EnumNumberMemberNotInitialized", + template: + "Number enum members need to be initialized, e.g. `%1 = 1` in enum `%0`.", + }, + EnumStringMemberInconsistentlyInitailized: { + code: "EnumStringMemberInconsistentlyInitailized", + template: + "String enum members need to consistently either all use initializers, or use no initializers, in enum `%0`.", + }, + GetterMayNotHaveThisParam: { + code: "GetterMayNotHaveThisParam", + template: "A getter cannot have a `this` parameter.", + }, + ImportTypeShorthandOnlyInPureImport: { + code: "ImportTypeShorthandOnlyInPureImport", + template: + "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: { + code: "InexactInsideExact", + template: + "Explicit inexact syntax cannot appear inside an explicit exact object type", + }, + InexactInsideNonObject: { + code: "InexactInsideNonObject", + template: + "Explicit inexact syntax cannot appear in class or interface definitions", + }, + InexactVariance: { + code: "InexactVariance", + template: "Explicit inexact syntax cannot have variance", + }, + InvalidNonTypeImportInDeclareModule: { + code: "InvalidNonTypeImportInDeclareModule", + template: + "Imports within a `declare module` body must always be `import type` or `import typeof`", + }, + MissingTypeParamDefault: { + code: "MissingTypeParamDefault", + template: + "Type parameter declaration needs a default, since a preceding type parameter declaration has a default.", + }, + NestedDeclareModule: { + code: "NestedDeclareModule", + template: "`declare module` cannot be used inside another `declare module`", + }, + NestedFlowComment: { + code: "NestedFlowComment", + template: "Cannot have a flow comment inside another flow comment", + }, + OptionalBindingPattern: { + code: "OptionalBindingPattern", + template: + "A binding pattern parameter cannot be optional in an implementation signature.", + }, + SetterMayNotHaveThisParam: { + code: "SetterMayNotHaveThisParam", + template: "A setter cannot have a `this` parameter.", + }, + SpreadVariance: { + code: "SpreadVariance", + template: "Spread properties cannot have variance", + }, + ThisParamAnnotationRequired: { + code: "ThisParamAnnotationRequired", + template: "A type annotation is required for the `this` parameter.", + }, + ThisParamBannedInConstructor: { + code: "ThisParamBannedInConstructor", + template: + "Constructors cannot have a `this` parameter; constructors don't bind `this` like other functions.", + }, + ThisParamMayNotBeOptional: { + code: "ThisParamMayNotBeOptional", + template: "The `this` parameter cannot be optional.", + }, + ThisParamMustBeFirst: { + code: "ThisParamMustBeFirst", + template: "The `this` parameter must be the first function parameter.", + }, + ThisParamNoDefault: { + code: "ThisParamNoDefault", + template: "The `this` parameter may not have a default value.", + }, + TypeBeforeInitializer: { + code: "TypeBeforeInitializer", + template: + "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", + }, + TypeCastInPattern: { + code: "TypeCastInPattern", + template: + "The type cast expression is expected to be wrapped with parenthesis", + }, + UnexpectedExplicitInexactInObject: { + code: "UnexpectedExplicitInexactInObject", + template: + "Explicit inexact syntax must appear at the end of an inexact object", + }, + UnexpectedReservedType: { + code: "UnexpectedReservedType", + template: "Unexpected reserved type %0", + }, + UnexpectedReservedUnderscore: { + code: "UnexpectedReservedUnderscore", + template: "`_` is only allowed as a type argument to call or new", + }, + UnexpectedSpaceBetweenModuloChecks: { + code: "UnexpectedSpaceBetweenModuloChecks", + template: "Spaces between `%` and `checks` are not allowed here.", + }, + UnexpectedSpreadType: { + code: "UnexpectedSpreadType", + template: "Spread operator cannot appear in class or interface definitions", + }, + UnexpectedSubtractionOperand: { + code: "UnexpectedSubtractionOperand", + template: 'Unexpected token, expected "number" or "bigint"', + }, + UnexpectedTokenAfterTypeParameter: { + code: "UnexpectedTokenAfterTypeParameter", + template: + "Expected an arrow function after this type parameter declaration", + }, + UnexpectedTypeParameterBeforeAsyncArrowFunction: { + code: "UnexpectedTypeParameterBeforeAsyncArrowFunction", + template: + "Type parameters must come after the async keyword, e.g. instead of ` async () => {}`, use `async () => {}`", + }, + UnsupportedDeclareExportKind: { + code: "UnsupportedDeclareExportKind", + template: "`declare export %0` is not supported. Use `%1` instead", + }, + UnsupportedStatementInDeclareModule: { + code: "UnsupportedStatementInDeclareModule", + template: + "Only declares and type imports are allowed inside declare module", + }, + UnterminatedFlowComment: { + code: "UnterminatedFlowComment", + template: "Unterminated flow-comment", + }, }); /* eslint-disable sort-keys */ @@ -414,7 +546,7 @@ export default (superClass: Class): Class => } else { this.expectContextual( "declare", - FlowErrors.UnsupportedStatementInDeclareModule, + FlowErrors.UnsupportedStatementInDeclareModule.template, ); bodyNode = this.flowParseDeclare(bodyNode, true); @@ -3185,7 +3317,7 @@ export default (superClass: Class): Class => skipBlockComment(): void { if (this.hasPlugin("flowComments") && this.skipFlowComment()) { if (this.state.hasFlowComment) { - this.unexpected(null, FlowErrors.NestedFlowComment); + this.unexpected(null, FlowErrors.NestedFlowComment.template); } this.hasFlowCommentCompletion(); this.state.pos += this.skipFlowComment(); diff --git a/packages/babel-parser/src/plugins/jsx/index.js b/packages/babel-parser/src/plugins/jsx/index.js index f8b6a3dd888b..e62d2c2952ac 100644 --- a/packages/babel-parser/src/plugins/jsx/index.js +++ b/packages/babel-parser/src/plugins/jsx/index.js @@ -21,17 +21,36 @@ const DECIMAL_NUMBER = /^\d+$/; /* eslint sort-keys: "error" */ const JsxErrors = Object.freeze({ - 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 <>...?", + AttributeIsEmpty: { + code: "AttributeIsEmpty", + template: "JSX attributes must only be assigned a non-empty expression", + }, + MissingClosingTagElement: { + code: "MissingClosingTagElement", + template: "Expected corresponding JSX closing tag for <%0>", + }, + MissingClosingTagFragment: { + code: "MissingClosingTagFragment", + template: "Expected corresponding JSX closing tag for <>", + }, + UnexpectedSequenceExpression: { + code: "UnexpectedSequenceExpression", + template: + "Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?", + }, + UnsupportedJsxValue: { + code: "UnsupportedJsxValue", + template: "JSX value should be either an expression or a quoted JSX text", + }, + UnterminatedJsxContent: { + code: "UnterminatedJsxContent", + template: "Unterminated JSX contents", + }, + UnwrappedAdjacentJSXElements: { + code: "UnwrappedAdjacentJSXElements", + template: + "Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...?", + }, }); /* eslint-disable sort-keys */ @@ -133,10 +152,10 @@ export default (superClass: Class): Class => const htmlEntity = ch === charCodes.rightCurlyBrace ? "}" : ">"; const char = this.input[this.state.pos]; - this.raise( - this.state.pos, - `Unexpected token \`${char}\`. Did you mean \`${htmlEntity}\` or \`{'${char}'}\`?`, - ); + this.raise(this.state.pos, { + code: "UnexpectedToken", + template: `Unexpected token \`${char}\`. Did you mean \`${htmlEntity}\` or \`{'${char}'}\`?`, + }); } /* falls through */ diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index 56e3efc99f75..9f0ecb8110ea 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -29,7 +29,7 @@ import TypeScriptScopeHandler from "./scope"; import * as charCodes from "charcodes"; import type { ExpressionErrors } from "../../parser/util"; import { PARAM } from "../../util/production-parameter"; -import { Errors } from "../../parser/error"; +import { Errors, type ErrorTemplate } from "../../parser/error"; type TsModifier = | "readonly" @@ -61,64 +61,155 @@ type ParsingContext = /* eslint sort-keys: "error" */ const TSErrors = Object.freeze({ - AbstractMethodHasImplementation: - "Method '%0' cannot have an implementation because it is marked abstract.", - 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.", - 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'", - 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", - IndexSignatureHasStatic: "Index signatures cannot have the 'static' modifier", - InvalidModifierOnTypeMember: "'%0' modifier cannot appear on a type member.", - InvalidTupleMemberLabel: - "Tuple members must be labeled with a simple 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.", - 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.", - TypeAnnotationAfterAssign: - "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", - 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", + AbstractMethodHasImplementation: { + code: "AbstractMethodHasImplementation", + template: + "Method '%0' cannot have an implementation because it is marked abstract.", + }, + ClassMethodHasDeclare: { + code: "ClassMethodHasDeclare", + template: "Class methods cannot have the 'declare' modifier", + }, + ClassMethodHasReadonly: { + code: "ClassMethodHasReadonly", + template: "Class methods cannot have the 'readonly' modifier", + }, + ConstructorHasTypeParameters: { + code: "ConstructorHasTypeParameters", + template: "Type parameters cannot appear on a constructor declaration.", + }, + DeclareClassFieldHasInitializer: { + code: "DeclareClassFieldHasInitializer", + template: "Initializers are not allowed in ambient contexts.", + }, + DeclareFunctionHasImplementation: { + code: "DeclareFunctionHasImplementation", + template: "An implementation cannot be declared in ambient contexts.", + }, + DuplicateAccessibilityModifier: { + code: "DuplicateAccessibilityModifier", + template: "Accessibility modifier already seen.", + }, + DuplicateModifier: { + code: "DuplicateModifier", + template: "Duplicate modifier: '%0'", + }, + EmptyHeritageClauseType: { + code: "EmptyHeritageClauseType", + template: "'%0' list cannot be empty.", + }, + EmptyTypeArguments: { + code: "EmptyTypeArguments", + template: "Type argument list cannot be empty.", + }, + EmptyTypeParameters: { + code: "EmptyTypeParameters", + template: "Type parameter list cannot be empty.", + }, + ExpectedAmbientAfterExportDeclare: { + code: "ExpectedAmbientAfterExportDeclare", + template: "'export declare' must be followed by an ambient declaration.", + }, + ImportAliasHasImportType: { + code: "ImportAliasHasImportType", + template: "An import alias can not use 'import type'", + }, + IndexSignatureHasAbstract: { + code: "IndexSignatureHasAbstract", + template: "Index signatures cannot have the 'abstract' modifier", + }, + IndexSignatureHasAccessibility: { + code: "IndexSignatureHasAccessibility", + template: "Index signatures cannot have an accessibility modifier ('%0')", + }, + IndexSignatureHasDeclare: { + code: "IndexSignatureHasDeclare", + template: "Index signatures cannot have the 'declare' modifier", + }, + IndexSignatureHasStatic: { + code: "IndexSignatureHasStatic", + template: "Index signatures cannot have the 'static' modifier", + }, + InvalidModifierOnTypeMember: { + code: "InvalidModifierOnTypeMember", + template: "'%0' modifier cannot appear on a type member.", + }, + InvalidTupleMemberLabel: { + code: "InvalidTupleMemberLabel", + template: "Tuple members must be labeled with a simple identifier.", + }, + MixedLabeledAndUnlabeledElements: { + code: "MixedLabeledAndUnlabeledElements", + template: "Tuple members must all have names or all not have names.", + }, + NonAbstractClassHasAbstractMethod: { + code: "NonAbstractClassHasAbstractMethod", + template: "Abstract methods can only appear within an abstract class.", + }, + NonClassMethodPropertyHasAbstractModifer: { + code: "NonClassMethodPropertyHasAbstractModifer", + template: + "'abstract' modifier can only appear on a class, method, or property declaration.", + }, + OptionalTypeBeforeRequired: { + code: "OptionalTypeBeforeRequired", + template: "A required element cannot follow an optional element.", + }, + PatternIsOptional: { + code: "PatternIsOptional", + template: + "A binding pattern parameter cannot be optional in an implementation signature.", + }, + PrivateElementHasAbstract: { + code: "PrivateElementHasAbstract", + template: "Private elements cannot have the 'abstract' modifier.", + }, + PrivateElementHasAccessibility: { + code: "PrivateElementHasAccessibility", + template: "Private elements cannot have an accessibility modifier ('%0')", + }, + ReadonlyForMethodSignature: { + code: "ReadonlyForMethodSignature", + template: + "'readonly' modifier can only appear on a property declaration or index signature.", + }, + TypeAnnotationAfterAssign: { + code: "TypeAnnotationAfterAssign", + template: + "Type annotations must come before default assignments, e.g. instead of `age = 25: number` use `age: number = 25`", + }, + UnexpectedParameterModifier: { + code: "UnexpectedParameterModifier", + template: + "A parameter property is only allowed in a constructor implementation.", + }, + UnexpectedReadonly: { + code: "UnexpectedReadonly", + template: + "'readonly' type modifier is only permitted on array and tuple literal types.", + }, + UnexpectedTypeAnnotation: { + code: "UnexpectedTypeAnnotation", + template: "Did not expect a type annotation here.", + }, + UnexpectedTypeCastInParameter: { + code: "UnexpectedTypeCastInParameter", + template: "Unexpected type cast in parameter position.", + }, + UnsupportedImportTypeArgument: { + code: "UnsupportedImportTypeArgument", + template: "Argument in a type import must be a string literal", + }, + UnsupportedParameterPropertyKind: { + code: "UnsupportedParameterPropertyKind", + template: + "A parameter property may not be declared using a binding pattern.", + }, + UnsupportedSignatureParameterKind: { + code: "UnsupportedSignatureParameterKind", + template: + "Name in a signature must be an Identifier, ObjectPattern or ArrayPattern, instead got %0", + }, }); /* eslint-disable sort-keys */ @@ -216,7 +307,7 @@ export default (superClass: Class): Class => }, allowedModifiers: TsModifier[], disallowedModifiers?: TsModifier[], - errorTemplate?: string, + errorTemplate?: ErrorTemplate, ): void { for (;;) { const startPos = this.state.start; @@ -2095,10 +2186,11 @@ export default (superClass: Class): Class => importNode.specifiers.length > 1 && importNode.specifiers[0].type === "ImportDefaultSpecifier" ) { - this.raise( - importNode.start, - "A type-only import can specify a default import or named bindings, but not both.", - ); + this.raise(importNode.start, { + code: "TSTypeImportCannotSpecifyBothDefaultAndNamedBindings", + template: + "A type-only import can specify a default import or named bindings, but not both.", + }); } return importNode; diff --git a/packages/babel-parser/src/tokenizer/index.js b/packages/babel-parser/src/tokenizer/index.js index 7c119c7d1111..ebe1d2d12424 100644 --- a/packages/babel-parser/src/tokenizer/index.js +++ b/packages/babel-parser/src/tokenizer/index.js @@ -9,7 +9,7 @@ import * as charCodes from "charcodes"; import { isIdentifierStart, isIdentifierChar } from "../util/identifier"; import { types as tt, keywords as keywordTypes, type TokenType } from "./types"; import { type TokContext, types as ct } from "./context"; -import ParserErrors, { Errors } from "../parser/error"; +import ParserErrors, { Errors, type ErrorTemplate } from "../parser/error"; import { SourceLocation } from "../util/location"; import { lineBreak, @@ -1321,7 +1321,7 @@ export default class Tokenizer extends ParserErrors { } } - recordStrictModeErrors(pos: number, message: string) { + recordStrictModeErrors(pos: number, message: ErrorTemplate) { if (this.state.strict && !this.state.strictErrors.has(pos)) { this.raise(pos, message); } else { diff --git a/packages/babel-parser/src/tokenizer/state.js b/packages/babel-parser/src/tokenizer/state.js index b3a45637bbe9..d2bdd9636964 100644 --- a/packages/babel-parser/src/tokenizer/state.js +++ b/packages/babel-parser/src/tokenizer/state.js @@ -6,7 +6,7 @@ import { Position } from "../util/location"; import { types as ct, type TokContext } from "./context"; import { types as tt, type TokenType } from "./types"; -import type { ParsingError } from "../parser/error"; +import type { ParsingError, ErrorTemplate } from "../parser/error"; type TopicContextState = { // When a topic binding has been currently established, @@ -147,7 +147,7 @@ export default class State { // todo(JLHwung): set strictErrors to null and avoid recording string errors // after a non-directive is parsed - strictErrors: Map = new Map(); + strictErrors: Map = new Map(); // Names of exports store. `default` is stored as a name for both // `export default foo;` and `export { foo as default };`. diff --git a/packages/babel-parser/src/util/class-scope.js b/packages/babel-parser/src/util/class-scope.js index 359af336e1a8..e5b973f7c0c8 100644 --- a/packages/babel-parser/src/util/class-scope.js +++ b/packages/babel-parser/src/util/class-scope.js @@ -5,7 +5,7 @@ import { CLASS_ELEMENT_FLAG_STATIC, type ClassElementTypes, } from "./scopeflags"; -import { Errors } from "../parser/error"; +import { Errors, type raiseFunction } from "../parser/error"; export class ClassScope { // A list of private named declared in the current class @@ -19,8 +19,6 @@ export class ClassScope { undefinedPrivateNames: Map = new Map(); } -type raiseFunction = (number, string, ...any) => void; - export default class ClassScopeHandler { stack: Array = []; declare raise: raiseFunction; diff --git a/packages/babel-parser/src/util/expression-scope.js b/packages/babel-parser/src/util/expression-scope.js index 809995864000..5d89b8d2afb8 100644 --- a/packages/babel-parser/src/util/expression-scope.js +++ b/packages/babel-parser/src/util/expression-scope.js @@ -1,5 +1,7 @@ // @flow +import type { ErrorTemplate, raiseFunction } from "../parser/error"; + /*:: declare var invariant; */ /** * @module util/expression-scope @@ -52,8 +54,6 @@ const kExpression = 0, type ExpressionScopeType = 0 | 1 | 2 | 3; -type raiseFunction = (number, string, ...any) => void; - class ExpressionScope { type: ExpressionScopeType; @@ -74,17 +74,17 @@ class ExpressionScope { } class ArrowHeadParsingScope extends ExpressionScope { - errors: Map = new Map(); + errors: Map = new Map(); constructor(type: 1 | 2) { super(type); } - recordDeclarationError(pos: number, message: string) { - this.errors.set(pos, message); + recordDeclarationError(pos: number, template: ErrorTemplate) { + this.errors.set(pos, template); } clearDeclarationError(pos: number) { this.errors.delete(pos); } - iterateErrors(iterator: (message: string, pos: number) => void) { + iterateErrors(iterator: (template: ErrorTemplate, pos: number) => void) { this.errors.forEach(iterator); } } @@ -110,17 +110,17 @@ export default class ExpressionScopeHandler { * otherwise it will be recorded to any ancestry MaybeArrowParameterDeclaration and * MaybeAsyncArrowParameterDeclaration scope until an Expression scope is seen. * @param {number} pos Error position - * @param {string} message Error message + * @param {ErrorTemplate} template Error template * @memberof ExpressionScopeHandler */ - recordParameterInitializerError(pos: number, message: string): void { + recordParameterInitializerError(pos: number, template: ErrorTemplate): void { const { stack } = this; let i = stack.length - 1; let scope: ExpressionScope = stack[i]; while (!scope.isCertainlyParameterDeclaration()) { if (scope.canBeArrowParameterDeclaration()) { /*:: invariant(scope instanceof ArrowHeadParsingScope) */ - scope.recordDeclarationError(pos, message); + scope.recordDeclarationError(pos, template); } else { /*:: invariant(scope.type == kExpression) */ // Type-Expression is the boundary where initializer error can populate to @@ -129,7 +129,7 @@ export default class ExpressionScopeHandler { scope = stack[--i]; } /* eslint-disable @babel/development-internal/dry-error-messages */ - this.raise(pos, message); + this.raise(pos, template); } /** @@ -149,18 +149,21 @@ export default class ExpressionScopeHandler { * arrow scope because when we finish parsing `( [(a) = []] = [] )`, it is an unambiguous assignment * expression and can not be cast to pattern * @param {number} pos - * @param {string} message + * @param {ErrorTemplate} template * @returns {void} * @memberof ExpressionScopeHandler */ - recordParenthesizedIdentifierError(pos: number, message: string): void { + recordParenthesizedIdentifierError( + pos: number, + template: ErrorTemplate, + ): void { const { stack } = this; const scope: ExpressionScope = stack[stack.length - 1]; if (scope.isCertainlyParameterDeclaration()) { - this.raise(pos, message); + this.raise(pos, template); } else if (scope.canBeArrowParameterDeclaration()) { /*:: invariant(scope instanceof ArrowHeadParsingScope) */ - scope.recordDeclarationError(pos, message); + scope.recordDeclarationError(pos, template); } else { return; } @@ -172,17 +175,17 @@ export default class ExpressionScopeHandler { * Errors will be recorded to any ancestry MaybeAsyncArrowParameterDeclaration * scope until an Expression scope is seen. * @param {number} pos - * @param {string} message + * @param {ErrorTemplate} template * @memberof ExpressionScopeHandler */ - recordAsyncArrowParametersError(pos: number, message: string): void { + recordAsyncArrowParametersError(pos: number, template: ErrorTemplate): void { const { stack } = this; let i = stack.length - 1; let scope: ExpressionScope = stack[i]; while (scope.canBeArrowParameterDeclaration()) { if (scope.type === kMaybeAsyncArrowParameterDeclaration) { /*:: invariant(scope instanceof ArrowHeadParsingScope) */ - scope.recordDeclarationError(pos, message); + scope.recordDeclarationError(pos, template); } scope = stack[--i]; } @@ -193,9 +196,9 @@ export default class ExpressionScopeHandler { const currentScope = stack[stack.length - 1]; if (!currentScope.canBeArrowParameterDeclaration()) return; /*:: invariant(currentScope instanceof ArrowHeadParsingScope) */ - currentScope.iterateErrors((message, pos) => { + currentScope.iterateErrors((template, pos) => { /* eslint-disable @babel/development-internal/dry-error-messages */ - this.raise(pos, message); + this.raise(pos, template); // iterate from parent scope let i = stack.length - 2; let scope = stack[i]; diff --git a/packages/babel-parser/src/util/scope.js b/packages/babel-parser/src/util/scope.js index bd3fc8cc37c8..03c01f57d844 100644 --- a/packages/babel-parser/src/util/scope.js +++ b/packages/babel-parser/src/util/scope.js @@ -17,7 +17,7 @@ import { type BindingTypes, } from "./scopeflags"; import * as N from "../types"; -import { Errors } from "../parser/error"; +import { Errors, type raiseFunction } from "../parser/error"; // Start an AST node, attaching a start offset. export class Scope { @@ -34,8 +34,6 @@ export class Scope { } } -type raiseFunction = (number, string, ...any) => void; - // The functions in this module keep track of declared variables in the // current scope in order to detect duplicate variable names. export default class ScopeHandler {