From b5c4a46a695116db06a6644381ec38ec3170e2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Sat, 30 May 2020 15:05:42 -0400 Subject: [PATCH] refactor: split locationParser into ParserErrors and error message (#11653) --- .../parser/{location.js => error-message.js} | 67 +----------------- packages/babel-parser/src/parser/error.js | 69 +++++++++++++++++++ .../babel-parser/src/parser/expression.js | 2 +- packages/babel-parser/src/parser/lval.js | 2 +- packages/babel-parser/src/parser/statement.js | 2 +- packages/babel-parser/src/parser/util.js | 2 +- packages/babel-parser/src/plugins/estree.js | 2 +- packages/babel-parser/src/plugins/flow.js | 2 +- .../babel-parser/src/plugins/jsx/index.js | 2 +- .../src/plugins/typescript/index.js | 2 +- packages/babel-parser/src/tokenizer/index.js | 4 +- packages/babel-parser/src/util/class-scope.js | 2 +- packages/babel-parser/src/util/scope.js | 2 +- 13 files changed, 82 insertions(+), 78 deletions(-) rename packages/babel-parser/src/parser/{location.js => error-message.js} (84%) create mode 100644 packages/babel-parser/src/parser/error.js diff --git a/packages/babel-parser/src/parser/location.js b/packages/babel-parser/src/parser/error-message.js similarity index 84% rename from packages/babel-parser/src/parser/location.js rename to packages/babel-parser/src/parser/error-message.js index 472fd95f517a..033fe814e87f 100644 --- a/packages/babel-parser/src/parser/location.js +++ b/packages/babel-parser/src/parser/error-message.js @@ -1,23 +1,8 @@ // @flow /* eslint sort-keys: "error" */ -import { getLineInfo, type Position } from "../util/location"; -import CommentsParser from "./comments"; - -// This function is used to raise exceptions on parse errors. It -// takes an offset integer (into the current `input`) to indicate -// the location of the error, attaches the position to the end -// of the error message, and then raises a `SyntaxError` with that -// message. - -type ErrorContext = { - pos: number, - loc: Position, - missingPlugin?: Array, - code?: string, -}; // The Errors key follows https://cs.chromium.org/chromium/src/v8/src/common/message-template.h unless it does not exist -export const Errors = Object.freeze({ +export const ErrorMessages = Object.freeze({ ArgumentsDisallowedInInitializer: "'arguments' is not allowed in class field initializer", AsyncFunctionInSingleStatementContext: @@ -205,53 +190,3 @@ export const Errors = Object.freeze({ ZeroDigitNumericSeparator: "Numeric separator can not be used after leading 0", }); - -export default class LocationParser extends CommentsParser { - // Forward-declaration: defined in tokenizer/index.js - /*:: - +isLookahead: boolean; - */ - - getLocationForPosition(pos: number): Position { - let loc; - if (pos === this.state.start) loc = this.state.startLoc; - else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc; - else if (pos === this.state.end) loc = this.state.endLoc; - else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc; - else loc = getLineInfo(this.input, pos); - - return loc; - } - - raise(pos: number, errorTemplate: string, ...params: any): Error | empty { - return this.raiseWithData(pos, undefined, errorTemplate, ...params); - } - - raiseWithData( - pos: number, - data?: { - missingPlugin?: Array, - code?: string, - }, - errorTemplate: string, - ...params: any - ): Error | empty { - const loc = this.getLocationForPosition(pos); - const message = - errorTemplate.replace(/%(\d+)/g, (_, i: number) => params[i]) + - ` (${loc.line}:${loc.column})`; - return this._raise(Object.assign(({ loc, pos }: Object), data), message); - } - - _raise(errorContext: ErrorContext, message: string): Error | empty { - // $FlowIgnore - const err: SyntaxError & ErrorContext = new SyntaxError(message); - Object.assign(err, errorContext); - if (this.options.errorRecovery) { - if (!this.isLookahead) this.state.errors.push(err); - return err; - } else { - throw err; - } - } -} diff --git a/packages/babel-parser/src/parser/error.js b/packages/babel-parser/src/parser/error.js new file mode 100644 index 000000000000..4fe08d8c4644 --- /dev/null +++ b/packages/babel-parser/src/parser/error.js @@ -0,0 +1,69 @@ +// @flow +/* eslint sort-keys: "error" */ +import { getLineInfo, type Position } from "../util/location"; +import CommentsParser from "./comments"; + +// This function is used to raise exceptions on parse errors. It +// takes an offset integer (into the current `input`) to indicate +// the location of the error, attaches the position to the end +// of the error message, and then raises a `SyntaxError` with that +// message. + +type ErrorContext = { + pos: number, + loc: Position, + missingPlugin?: Array, + code?: string, +}; + +export { ErrorMessages as Errors } from "./error-message.js"; + +export default class ParserError extends CommentsParser { + // Forward-declaration: defined in tokenizer/index.js + /*:: + +isLookahead: boolean; + */ + + getLocationForPosition(pos: number): Position { + let loc; + if (pos === this.state.start) loc = this.state.startLoc; + else if (pos === this.state.lastTokStart) loc = this.state.lastTokStartLoc; + else if (pos === this.state.end) loc = this.state.endLoc; + else if (pos === this.state.lastTokEnd) loc = this.state.lastTokEndLoc; + else loc = getLineInfo(this.input, pos); + + return loc; + } + + raise(pos: number, errorTemplate: string, ...params: any): Error | empty { + return this.raiseWithData(pos, undefined, errorTemplate, ...params); + } + + raiseWithData( + pos: number, + data?: { + missingPlugin?: Array, + code?: string, + }, + errorTemplate: string, + ...params: any + ): Error | empty { + const loc = this.getLocationForPosition(pos); + const message = + errorTemplate.replace(/%(\d+)/g, (_, i: number) => params[i]) + + ` (${loc.line}:${loc.column})`; + return this._raise(Object.assign(({ loc, pos }: Object), data), message); + } + + _raise(errorContext: ErrorContext, message: string): Error | empty { + // $FlowIgnore + const err: SyntaxError & ErrorContext = new SyntaxError(message); + Object.assign(err, errorContext); + if (this.options.errorRecovery) { + if (!this.isLookahead) this.state.errors.push(err); + return err; + } else { + throw err; + } + } +} diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 947eccc56a4e..0ef5ca4270ef 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -48,7 +48,7 @@ import { PARAM, functionFlags, } from "../util/production-parameter"; -import { Errors } from "./location"; +import { Errors } from "./error"; export default class ExpressionParser extends LValParser { // Forward-declaration: defined in statement.js diff --git a/packages/babel-parser/src/parser/lval.js b/packages/babel-parser/src/parser/lval.js index acb8406649f6..647d48a5389d 100644 --- a/packages/babel-parser/src/parser/lval.js +++ b/packages/babel-parser/src/parser/lval.js @@ -22,7 +22,7 @@ import { import { NodeUtils } from "./node"; import { type BindingTypes, BIND_NONE } from "../util/scopeflags"; import { ExpressionErrors } from "./util"; -import { Errors } from "./location"; +import { Errors } from "./error"; const unwrapParenthesizedExpression = (node: Node) => { return node.type === "ParenthesizedExpression" diff --git a/packages/babel-parser/src/parser/statement.js b/packages/babel-parser/src/parser/statement.js index 13f693c3d593..521d13c9fb63 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 "./location"; +import { Errors } from "./error"; import { isIdentifierChar, isIdentifierStart, diff --git a/packages/babel-parser/src/parser/util.js b/packages/babel-parser/src/parser/util.js index 44bc540b9837..cc91ab28133a 100644 --- a/packages/babel-parser/src/parser/util.js +++ b/packages/babel-parser/src/parser/util.js @@ -7,7 +7,7 @@ import type { Node } from "../types"; import { lineBreak } from "../util/whitespace"; import { isIdentifierChar } from "../util/identifier"; import * as charCodes from "charcodes"; -import { Errors } from "./location"; +import { Errors } from "./error"; type TryParse = { node: Node, diff --git a/packages/babel-parser/src/plugins/estree.js b/packages/babel-parser/src/plugins/estree.js index 3c88260535e2..71265770c2e3 100644 --- a/packages/babel-parser/src/plugins/estree.js +++ b/packages/babel-parser/src/plugins/estree.js @@ -6,7 +6,7 @@ import type { ExpressionErrors } from "../parser/util"; import * as N from "../types"; import type { Position } from "../util/location"; import { type BindingTypes, BIND_NONE } from "../util/scopeflags"; -import { Errors } from "../parser/location"; +import { Errors } from "../parser/error"; function isSimpleProperty(node: N.Node): boolean { return ( diff --git a/packages/babel-parser/src/plugins/flow.js b/packages/babel-parser/src/plugins/flow.js index 184319132924..f2558916a006 100644 --- a/packages/babel-parser/src/plugins/flow.js +++ b/packages/babel-parser/src/plugins/flow.js @@ -22,7 +22,7 @@ import { SCOPE_OTHER, } from "../util/scopeflags"; import type { ExpressionErrors } from "../parser/util"; -import { Errors } from "../parser/location"; +import { Errors } from "../parser/error"; const reservedTypes = new Set([ "_", diff --git a/packages/babel-parser/src/plugins/jsx/index.js b/packages/babel-parser/src/plugins/jsx/index.js index 6158cae7579a..46051e250fe3 100644 --- a/packages/babel-parser/src/plugins/jsx/index.js +++ b/packages/babel-parser/src/plugins/jsx/index.js @@ -11,7 +11,7 @@ import * as N from "../../types"; import { isIdentifierChar, isIdentifierStart } from "../../util/identifier"; import type { Position } from "../../util/location"; import { isNewLine } from "../../util/whitespace"; -import { Errors } from "../../parser/location"; +import { Errors } from "../../parser/error"; const HEX_NUMBER = /^[\da-fA-F]+$/; const DECIMAL_NUMBER = /^\d+$/; diff --git a/packages/babel-parser/src/plugins/typescript/index.js b/packages/babel-parser/src/plugins/typescript/index.js index e56317f53265..2477a62e408d 100644 --- a/packages/babel-parser/src/plugins/typescript/index.js +++ b/packages/babel-parser/src/plugins/typescript/index.js @@ -27,7 +27,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/location"; +import { Errors } from "../../parser/error"; type TsModifier = | "readonly" diff --git a/packages/babel-parser/src/tokenizer/index.js b/packages/babel-parser/src/tokenizer/index.js index c15b98facc2d..a6e44c027d97 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 LocationParser, { Errors } from "../parser/location"; +import ParserErrors, { Errors } from "../parser/error"; import { SourceLocation } from "../util/location"; import { lineBreak, @@ -110,7 +110,7 @@ export class Token { // ## Tokenizer -export default class Tokenizer extends LocationParser { +export default class Tokenizer extends ParserErrors { // Forward-declarations // parser/util.js /*:: diff --git a/packages/babel-parser/src/util/class-scope.js b/packages/babel-parser/src/util/class-scope.js index 6de6d790ea90..1ac00c995e7c 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/location"; +import { Errors } from "../parser/error"; export class ClassScope { // A list of private named declared in the current class diff --git a/packages/babel-parser/src/util/scope.js b/packages/babel-parser/src/util/scope.js index 5875cc3f194b..3d40c5fb877f 100644 --- a/packages/babel-parser/src/util/scope.js +++ b/packages/babel-parser/src/util/scope.js @@ -16,7 +16,7 @@ import { type BindingTypes, } from "./scopeflags"; import * as N from "../types"; -import { Errors } from "../parser/location"; +import { Errors } from "../parser/error"; // Start an AST node, attaching a start offset. export class Scope {