Skip to content

Commit 7979e3f

Browse files
Fill optional AST properties when both estree and typescript parser plugin are enabled (Part 1) (#17224)
* test: reduce jest-diff noises from different location prototype * add more ts-eslint integration tests * fix: provide optional properties for some ts-eslint AST * update Babel parser AST fixtures * Update packages/babel-parser/src/plugins/estree.ts Co-authored-by: Nicolò Ribaudo <[email protected]> * simplify castNodeTo usage * use castNodeTo for TSEmptyBodyFunctionExpression * add a few test cases * handle TSAbstractMethodDefinition * update Babel 8 AST fixtures * fix AST checks * parser type cleanup --------- Co-authored-by: Nicolò Ribaudo <[email protected]>
1 parent 7264384 commit 7979e3f

File tree

40 files changed

+1062
-322
lines changed

40 files changed

+1062
-322
lines changed

eslint/babel-eslint-parser/src/convert/convertAST.cts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,25 @@ const convertNodesVisitor = {
5050
delete node.extra;
5151
}
5252

53-
if (node.loc.identifierName) {
54-
delete node.loc.identifierName;
53+
if (process.env.IS_PUBLISH) {
54+
if (node.loc.identifierName) {
55+
delete node.loc.identifierName;
56+
}
57+
} else {
58+
// To minimize the jest-diff noise comparing Babel AST and third-party AST,
59+
// here we generate a deep copy of loc without identifierName and index
60+
if (node.loc) {
61+
node.loc = {
62+
end: {
63+
column: node.loc.end.column,
64+
line: node.loc.end.line,
65+
},
66+
start: {
67+
column: node.loc.start.column,
68+
line: node.loc.start.line,
69+
},
70+
} as any;
71+
}
5572
}
5673

5774
if (node.type === "TypeParameter") {

eslint/babel-eslint-parser/src/convert/convertTokens.cts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { BabelToken } from "../types.cts";
2+
import type * as t from "@babel/types";
23
import ESLINT_VERSION = require("../utils/eslint-version.cjs");
34

45
function convertTemplateType(tokens: BabelToken[], tl: Record<string, any>) {
@@ -101,6 +102,7 @@ function convertToken(
101102
pattern: string;
102103
flags: string;
103104
};
105+
loc?: t.SourceLocation | null;
104106
} = token as any;
105107
newToken.range = [token.start, token.end];
106108

@@ -203,6 +205,20 @@ function convertToken(
203205
) {
204206
newToken.type = "Template";
205207
}
208+
if (!process.env.IS_PUBLISH) {
209+
// To minimize the jest-diff noise comparing Babel AST and third-party AST,
210+
// here we generate a deep copy of loc without identifierName and index
211+
newToken.loc = {
212+
end: {
213+
column: newToken.loc.end.column,
214+
line: newToken.loc.end.line,
215+
},
216+
start: {
217+
column: newToken.loc.start.column,
218+
line: newToken.loc.start.line,
219+
},
220+
} as any;
221+
}
206222
return newToken;
207223
}
208224

eslint/babel-eslint-parser/test/typescript-estree.test.js

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from "node:path";
22
import { parseForESLint } from "../lib/index.cjs";
33
import { ESLint } from "eslint";
4-
import { itDummy, commonJS } from "$repo-utils";
4+
import { itDummy, commonJS, IS_BABEL_8 } from "$repo-utils";
55

66
const ESLINT_VERSION = ESLint.version;
77
const isESLint9 = ESLINT_VERSION.startsWith("9.");
@@ -12,8 +12,6 @@ const PROPS_TO_REMOVE = [
1212
{ key: "start", type: "Node" },
1313
{ key: "end", type: "Node" },
1414

15-
{ key: "importKind", type: "Node" },
16-
{ key: "exportKind", type: "Node" },
1715
{ key: "variance", type: "Node" },
1816
{ key: "typeArguments", type: "Node" },
1917
{ key: "filename", type: null },
@@ -107,22 +105,80 @@ function deeplyRemoveProperties(obj, props) {
107105

108106
it.each([
109107
["empty", ""],
110-
111108
["boolean", "true"],
112109
["boolean", "false"],
113-
114110
["numeric", "0"],
115111
// ["bigint", "0n"],
116-
112+
["string", `"string"`],
117113
["regexp without flag", `/foo/;`],
118114
["regexp u flag", `/foo/dgimsuy;`],
119115
["regexp v flag", `/foo/dgimsvy;`],
116+
["identifier", "i"],
120117

121118
["logical NOT", `!0`],
122119
["bitwise NOT", `~0`],
120+
121+
["function declaration", "function f(p) {}"],
122+
["function expression", "0, function f(p) {}"],
123+
["arrow function expression", "() => {}"],
124+
["async arrow function expression", "async () => {}"],
125+
126+
["object method", "({ m() {} })"],
127+
["object property", "({ p: 0 })"],
128+
129+
["class declaration", "class C {}"],
130+
["class expression", "0, class C {}"],
131+
["class method", "class C { m() {} }"],
132+
["class property", "class C { p; }"],
133+
["class static block", "class C { static {}; }"],
134+
135+
["variable declaration", "var a = 0"],
136+
[
137+
"variable declaration destructuring",
138+
"var [{ a: x = 0 }, ...b] = [{ a: 0 }]",
139+
],
140+
// pending cloneIdentifier support
141+
// ["variable declaration destructuring shorthand", "let { a = 0 } = { a: 0 }"]
142+
143+
["assignment expression", "x = 1"],
144+
// pending toAssignable support
145+
// ["assignment expression destructuring", "[{ a: x = 0 }, ...b] = [{ a: 0 }]"],
146+
147+
["async call expression", "async ([ x ])"],
148+
149+
["import declaration", `import "foo"`],
150+
["import declaration default", `import foo from "foo"`],
151+
// pending cloneIdentifier support
152+
// ["import declaration named", `import { foo } from "foo"`]
153+
["import declaration named as", `import { foo as bar } from "foo"`],
154+
[
155+
"import declaration with attributes",
156+
`import foo from "./foo.json" with { type: "json" }`,
157+
],
158+
159+
// pending cloneIdentifier support
160+
// ["export declaration", `const foo = 0;export { foo }`],
161+
["export declaration as", `const foo = 0;export { foo as bar }`],
162+
["export function declaration", `export function foo() {}`],
163+
["export class declaration", `export class foo {}`],
164+
165+
["member expression", `foo.bar`],
166+
["call expression", `foo(bar)`],
167+
["new expression", `new foo`],
123168
])("%s: %s", (_, input) => {
124169
parseAndAssertSame(input);
125170
});
171+
172+
if (IS_BABEL_8()) {
173+
it.each([
174+
// ["class private method", "class C { #m() {} }"],
175+
["class abstract property", "abstract class C { abstract p; }"],
176+
// ["class abstract private property", "abstract class C { abstract #p; }"]
177+
["class abstract method", "abstract class C { abstract m(): void }"],
178+
])("%s: %s", (_, input) => {
179+
parseAndAssertSame(input);
180+
});
181+
}
126182
},
127183
);
128184

0 commit comments

Comments
 (0)