Skip to content

Commit 449e894

Browse files
committed
Fix for trailing comments in root node
1 parent 551ad3b commit 449e894

3 files changed

Lines changed: 50 additions & 2 deletions

File tree

lib/source-code/token-store/utils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ exports.getLastIndex = function getLastIndex(tokens, indexMap, endLoc) {
8484
const index = indexMap[endLoc - 1];
8585
const token = tokens[index];
8686

87-
// If the mapped index is out of bounds, the returned cursor index will point before the start of the tokens array.
87+
// If the mapped index is out of bounds, the returned cursor index will point before the end of the tokens array.
8888
if (!token) {
89-
return -1;
89+
return tokens.length - 1;
9090
}
9191

9292
/*
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Similar to the default parser, but considers leading and trailing comments to be part of the root node.
2+
// Some custom parsers like @typescript-eslint/parser behave in this way.
3+
4+
const espree = require("espree");
5+
exports.parse = function(code, options) {
6+
const ast = espree.parse(code, options);
7+
8+
if (ast.range && ast.comments && ast.comments.length > 0) {
9+
const firstComment = ast.comments[0];
10+
const lastComment = ast.comments[ast.comments.length - 1];
11+
12+
if (ast.range[0] > firstComment.range[0]) {
13+
ast.range[0] = firstComment.range[0];
14+
ast.start = firstComment.start;
15+
if (ast.loc) {
16+
ast.loc.start = firstComment.loc.start;
17+
}
18+
}
19+
if (ast.range[1] < lastComment.range[1]) {
20+
ast.range[1] = lastComment.range[1];
21+
ast.end = lastComment.end;
22+
if (ast.loc) {
23+
ast.loc.end = lastComment.loc.end;
24+
}
25+
}
26+
}
27+
return ast;
28+
};

tests/lib/source-code/token-store.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,16 @@ describe("TokenStore", () => {
654654
assert.strictEqual(token.value, "c");
655655
});
656656

657+
it("should retrieve the first token if the root node contains a trailing comment", () => {
658+
const parser = require("../../fixtures/parsers/all-comments-parser");
659+
const code = "foo // comment";
660+
const ast = parser.parse(code, { loc: true, range: true, tokens: true, comment: true });
661+
const tokenStore = new TokenStore(ast.tokens, ast.comments);
662+
const token = tokenStore.getFirstToken(ast);
663+
664+
assert.strictEqual(token, ast.tokens[0]);
665+
});
666+
657667
it("should return null if the source contains only comments", () => {
658668
const code = "// comment";
659669
const ast = espree.parse(code, { loc: true, range: true, tokens: true, comment: true });
@@ -863,6 +873,16 @@ describe("TokenStore", () => {
863873
assert.strictEqual(token.value, "b");
864874
});
865875

876+
it("should retrieve the last token if the root node contains a trailing comment", () => {
877+
const parser = require("../../fixtures/parsers/all-comments-parser");
878+
const code = "foo // comment";
879+
const ast = parser.parse(code, { loc: true, range: true, tokens: true, comment: true });
880+
const tokenStore = new TokenStore(ast.tokens, ast.comments);
881+
const token = tokenStore.getLastToken(ast);
882+
883+
assert.strictEqual(token, ast.tokens[0]);
884+
});
885+
866886
it("should return null if the source contains only comments", () => {
867887
const code = "// comment";
868888
const ast = espree.parse(code, { loc: true, range: true, tokens: true, comment: true });

0 commit comments

Comments
 (0)