Skip to content

Commit

Permalink
Improve errors location tracking (#14130)
Browse files Browse the repository at this point in the history
  • Loading branch information
tolmasky committed Jan 18, 2022
1 parent a6ca39c commit 478a970
Show file tree
Hide file tree
Showing 77 changed files with 2,140 additions and 1,141 deletions.
Expand Up @@ -146,7 +146,7 @@ export default {
"CallExpression[callee.type='MemberExpression'][callee.object.type='ThisExpression'][callee.property.name='raise'][arguments.length>=2]"(
node,
) {
const [, errorMsgNode] = node.arguments;
const [errorMsgNode] = node.arguments;
const nodesToCheck = findIdNodes(errorMsgNode);

if (
Expand Down

Large diffs are not rendered by default.

44 changes: 24 additions & 20 deletions packages/babel-parser/src/parser/error.js
@@ -1,8 +1,9 @@
// @flow
/* eslint sort-keys: "error" */
import { getLineInfo, type Position } from "../util/location";
import { type Position, indexes } from "../util/location";
import CommentsParser from "./comments";
import { type ErrorCode, ErrorCodes } from "./error-codes";
import { type Node } from "../types";

// This function is used to raise exceptions on parse errors. It
// takes an offset integer (into the current `input`) to indicate
Expand All @@ -28,7 +29,14 @@ export type ErrorTemplates = {
[key: string]: ErrorTemplate,
};

type SyntaxPlugin = "flow" | "typescript" | "jsx" | typeof undefined;
type Origin = {| node: Node |} | {| at: Position |};

type SyntaxPlugin =
| "flow"
| "typescript"
| "jsx"
| "placeholders"
| typeof undefined;

function keepReasonCodeCompat(reasonCode: string, syntaxPlugin: SyntaxPlugin) {
if (!process.env.BABEL_8_BREAKING) {
Expand Down Expand Up @@ -64,31 +72,26 @@ export {
SourceTypeModuleErrorMessages as SourceTypeModuleErrors,
} from "./error-message";

export type raiseFunction = (number, ErrorTemplate, ...any) => void;
export type raiseFunction = (ErrorTemplate, Origin, ...any) => void;
export type ErrorData = {| message: ErrorTemplate, loc: Position |};

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,
{ code, reasonCode, template }: ErrorTemplate,
origin: Origin,
...params: any
): Error | empty {
return this.raiseWithData(pos, { code, reasonCode }, template, ...params);
return this.raiseWithData(
origin.node ? origin.node.loc.start : origin.at,
{ code, reasonCode },
template,
...params,
);
}

/**
Expand All @@ -104,11 +107,12 @@ export default class ParserError extends CommentsParser {
* @memberof ParserError
*/
raiseOverwrite(
pos: number,
loc: Position,
{ code, template }: ErrorTemplate,
...params: any
): Error | empty {
const loc = this.getLocationForPosition(pos);
// $FlowIgnore[incompatible-type] We know this exists, so it can't be undefined.
const pos: number = indexes.get(loc);
const message =
template.replace(/%(\d+)/g, (_, i: number) => params[i]) +
` (${loc.line}:${loc.column})`;
Expand All @@ -127,15 +131,15 @@ export default class ParserError extends CommentsParser {
}

raiseWithData(
pos: number,
loc: Position,
data?: {
missingPlugin?: Array<string>,
code?: string,
},
errorTemplate: string,
...params: any
): Error | empty {
const loc = this.getLocationForPosition(pos);
const pos = indexes.get(loc);
const message =
errorTemplate.replace(/%(\d+)/g, (_, i: number) => params[i]) +
` (${loc.line}:${loc.column})`;
Expand Down

0 comments on commit 478a970

Please sign in to comment.