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