Skip to content

Commit

Permalink
Breaking: syncing start/end with range (fixes #349) (#461)
Browse files Browse the repository at this point in the history
* Fix: sycing range and loc with start/end (fixes #349)

* Chore: independent logic for start end

* Chore: updating templateElement's prop using state
  • Loading branch information
anikethsaha committed Apr 28, 2021
1 parent e86f386 commit dffb7aa
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/espree.js
Expand Up @@ -104,7 +104,8 @@ export default () => Parser => {
impliedStrict: ecmaFeatures.impliedStrict === true && this.options.ecmaVersion >= 5,
ecmaVersion: this.options.ecmaVersion,
jsxAttrValueToken: false,
lastToken: null
lastToken: null,
templateElements: []
};
}

Expand Down Expand Up @@ -167,6 +168,16 @@ export default () => Parser => {
program.loc.end = extra.lastToken ? extra.lastToken.loc.end : program.loc.end;
}

program.start = program.body.length ? program.body[0].start : program.start;
program.end = extra.lastToken ? extra.lastToken.end : program.end;

this[STATE].templateElements.forEach(templateElement => {
const terminalDollarBraceL = this.input.slice(templateElement.end, templateElement.end + 2) === "${";

templateElement.start--;
templateElement.end += (terminalDollarBraceL ? 2 : 1);
});

return program;
}

Expand Down Expand Up @@ -273,6 +284,8 @@ export default () => Parser => {
result.loc.start.column--;
result.loc.end.column += (terminalDollarBraceL ? 2 : 1);
}

this[STATE].templateElements.push(result);
}

if (result.type.includes("Function") && !result.generator) {
Expand Down
87 changes: 87 additions & 0 deletions tests/lib/parse.js
Expand Up @@ -80,6 +80,93 @@ describe("parse()", () => {
assert.deepStrictEqual(tester.getRaw(ast), allPiecesJson);
});

it("should output the same value for program.start, end and range when there is a leading/trailing comments", () => {
const ast = espree.parse("/* foo */ bar /* baz */", {
range: true
});

assert.strictEqual(ast.start, ast.range[0]);
assert.strictEqual(ast.end, ast.range[1]);
});

it("should output the same value for program.start, end and range and loc when there is a leading comments with range and loc true", () => {
const ast = espree.parse("/* foo */ bar", {
range: true,
loc: true
});

assert.strictEqual(ast.start, ast.range[0]);
assert.strictEqual(ast.end, ast.range[1]);
assert.strictEqual(ast.start, ast.loc.start.column);
assert.strictEqual(ast.end, ast.loc.end.column);
});

it("should output the same value for program.start, end and loc when there is a leading comments with loc", () => {
const ast = espree.parse("/* foo */ bar", {
loc: true
});

assert.strictEqual(ast.start, ast.loc.start.column);
assert.strictEqual(ast.end, ast.loc.end.column);
});

it("should output the same value for program.start, end and range when there is a trailing comments", () => {
const ast = espree.parse(" bar /* foo */", {
range: true
});

assert.strictEqual(ast.start, ast.range[0]);
assert.strictEqual(ast.end, ast.range[1]);
});

it("should output the same value for range and start and end in templateElement with range", () => {
const ast = espree.parse("`foo ${bar}`;", {
ecmaVersion: 6,
range: true
});

assert.strictEqual(ast.body[0].expression.quasis[0].start, ast.body[0].expression.quasis[0].range[0]);
assert.strictEqual(ast.body[0].expression.quasis[0].end, ast.body[0].expression.quasis[0].range[1]);
assert.strictEqual(ast.body[0].expression.quasis[1].start, ast.body[0].expression.quasis[1].range[0]);
assert.strictEqual(ast.body[0].expression.quasis[1].end, ast.body[0].expression.quasis[1].range[1]);
});

it("should output the same value for loc and start and end in templateElement with loc", () => {
const ast = espree.parse("`foo ${bar}`;", {
ecmaVersion: 6,
loc: true
});

assert.strictEqual(ast.body[0].expression.quasis[0].start, ast.body[0].expression.quasis[0].loc.start.column);
assert.strictEqual(ast.body[0].expression.quasis[0].end, ast.body[0].expression.quasis[0].loc.end.column);
assert.strictEqual(ast.body[0].expression.quasis[1].start, ast.body[0].expression.quasis[1].loc.start.column);
assert.strictEqual(ast.body[0].expression.quasis[1].end, ast.body[0].expression.quasis[1].loc.end.column);
});

it("should output the same value for loc, range and start and end in templateElement with loc and range", () => {
const ast = espree.parse("`foo ${bar}`;", {
ecmaVersion: 6,
loc: true,
range: true
});

assert.strictEqual(ast.body[0].expression.quasis[0].start, ast.body[0].expression.quasis[0].loc.start.column);
assert.strictEqual(ast.body[0].expression.quasis[0].end, ast.body[0].expression.quasis[0].loc.end.column);
assert.strictEqual(ast.body[0].expression.quasis[1].start, ast.body[0].expression.quasis[1].range[0]);
assert.strictEqual(ast.body[0].expression.quasis[1].end, ast.body[0].expression.quasis[1].range[1]);
});

it("should output the same value for loc, range and start and end in templateElement", () => {
const ast = espree.parse("`foo ${bar}`;", {
ecmaVersion: 6
});

assert.strictEqual(ast.body[0].expression.quasis[0].start, 0);
assert.strictEqual(ast.body[0].expression.quasis[0].end, 7);
assert.strictEqual(ast.body[0].expression.quasis[1].start, 10);
assert.strictEqual(ast.body[0].expression.quasis[1].end, 12);
});

it("should reset lastToken on each parse", () => {
espree.parse("var foo = bar;");
const ast = espree.parse("//foo", {
Expand Down

0 comments on commit dffb7aa

Please sign in to comment.