From b1826bf0a0c4d675125991cba32c9f1095813452 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder Date: Fri, 17 May 2019 15:32:34 -0700 Subject: [PATCH] Only compute Position if not already in state (#9989) * Only compute Position if not already in state * Prioritize start locations --- packages/babel-parser/src/parser/location.js | 14 ++++++- .../babel-parser/test/unit/util/location.js | 38 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/babel-parser/test/unit/util/location.js diff --git a/packages/babel-parser/src/parser/location.js b/packages/babel-parser/src/parser/location.js index 79db584a4995..1839f359ae4c 100644 --- a/packages/babel-parser/src/parser/location.js +++ b/packages/babel-parser/src/parser/location.js @@ -10,6 +10,17 @@ import CommentsParser from "./comments"; // message. export default class LocationParser extends CommentsParser { + 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, message: string, @@ -21,7 +32,8 @@ export default class LocationParser extends CommentsParser { code?: string, } = {}, ): empty { - const loc = getLineInfo(this.input, pos); + const loc = this.getLocationForPosition(pos); + message += ` (${loc.line}:${loc.column})`; // $FlowIgnore const err: SyntaxError & { pos: number, loc: Position } = new SyntaxError( diff --git a/packages/babel-parser/test/unit/util/location.js b/packages/babel-parser/test/unit/util/location.js new file mode 100644 index 000000000000..f66d3a3204eb --- /dev/null +++ b/packages/babel-parser/test/unit/util/location.js @@ -0,0 +1,38 @@ +import { getLineInfo } from "../../../src/util/location"; + +describe("getLineInfo", () => { + const input = "a\nb\nc\nd\ne\nf\ng\nh\ni"; + + it("reports correct position", () => { + expect(getLineInfo(input, 7)).toEqual({ + column: 1, + line: 4, + }); + }); + + it("reports correct position for first line", () => { + expect(getLineInfo(input, 0)).toEqual({ + column: 0, + line: 1, + }); + }); + + const inputArray = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]; + const singleCharLineEndings = ["\n", "\r", "\u2028", "\u2029"]; + + singleCharLineEndings.forEach(ending => { + it(`supports ${escape(ending)} line ending`, () => { + expect(getLineInfo(inputArray.join(ending), 7)).toEqual({ + column: 1, + line: 4, + }); + }); + }); + + it(`supports ${escape("\r\n")} line ending`, () => { + expect(getLineInfo(inputArray.join("\r\n"), 7)).toEqual({ + column: 1, + line: 3, + }); + }); +});