refactor: split locationParser into ParserErrors and error message (#11653)

This commit is contained in:
Huáng Jùnliàng 2020-05-30 15:05:42 -04:00 committed by GitHub
parent 15d6da076a
commit b5c4a46a69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 82 additions and 78 deletions

View File

@ -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<string>,
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<string>,
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;
}
}
}

View File

@ -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<string>,
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<string>,
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;
}
}
}

View File

@ -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

View File

@ -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"

View File

@ -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,

View File

@ -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, Error, Thrown, Aborted, FailState> = {
node: Node,

View File

@ -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 (

View File

@ -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([
"_",

View File

@ -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+$/;

View File

@ -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"

View File

@ -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
/*::

View File

@ -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

View File

@ -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 {