Skip to content

Commit 2d0c76e

Browse files
authored
Improve integrations of using declaration with other transforms (#17330)
* fix: allow using foo = ... in ambient context * update AST spec * improve duplicate accessibility modifier error msg * fix error message type typo * Error when block-scoping transform sees using * remove redundant using detect in destructuring transform * skip valid-namespace-var before upstream issue is resolved
1 parent 35152d8 commit 2d0c76e

19 files changed

Lines changed: 435 additions & 35 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,9 @@ function deeplyRemoveProperties(obj, props) {
338338
);
339339
const fixtures = getFixtures(parserTestFixtureRoot);
340340
const FAILURES = new Set([
341+
// Todo: Remove when https://github.com/typescript-eslint/typescript-eslint/issues/11244 is resolved
342+
"typescript/declare/valid-namespace-var/input.ts",
343+
341344
// ts-eslint/tsc does not support arrow generic in tsx mode
342345
"typescript/arrow-function/async-await-null/input.ts",
343346
"typescript/arrow-function/async-generic-after-await/input.ts",

packages/babel-parser/ast/spec.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ A function declaration. Note that unlike in the parent interface `Function`, the
572572
interface VariableDeclaration <: Declaration {
573573
type: "VariableDeclaration";
574574
declarations: [ VariableDeclarator ];
575-
kind: "var" | "let" | "const" | "using";
575+
kind: "var" | "let" | "const" | "using" | "await using";
576576
}
577577
```
578578

packages/babel-parser/src/plugins/flow/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2927,7 +2927,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
29272927
// parse flow type annotations on variable declarator heads - let foo: string = bar
29282928
parseVarId(
29292929
decl: N.VariableDeclarator,
2930-
kind: "var" | "let" | "const",
2930+
kind: "var" | "let" | "const" | "using" | "await using",
29312931
): void {
29322932
super.parseVarId(decl, kind);
29332933
if (this.match(tt.colon)) {

packages/babel-parser/src/plugins/typescript/index.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,11 @@ const TSErrors = ParseErrorEnum`typescript`({
9191
"Initializers are not allowed in ambient contexts.",
9292
DeclareFunctionHasImplementation:
9393
"An implementation cannot be declared in ambient contexts.",
94-
DuplicateAccessibilityModifier:
95-
// `Accessibility modifier already seen: ${modifier}` would be more helpful.
96-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
97-
({ modifier }: { modifier: N.Accessibility }) =>
98-
`Accessibility modifier already seen.`,
94+
DuplicateAccessibilityModifier: ({
95+
modifier,
96+
}: {
97+
modifier: N.Accessibility;
98+
}) => `Accessibility modifier already seen: '${modifier}'.`,
9999
DuplicateModifier: ({ modifier }: { modifier: TsModifier }) =>
100100
`Duplicate modifier: '${modifier}'.`,
101101
// `token` matches the terminology used by typescript:
@@ -158,7 +158,7 @@ const TSErrors = ParseErrorEnum`typescript`({
158158
"'interface' declarations must be followed by an identifier.",
159159
NonAbstractClassHasAbstractMethod:
160160
"Abstract methods can only appear within an abstract class.",
161-
NonClassMethodPropertyHasAbstractModifer:
161+
NonClassMethodPropertyHasAbstractModifier:
162162
"'abstract' modifier can only appear on a class, method, or property declaration.",
163163
OptionalTypeBeforeRequired:
164164
"A required element cannot follow an optional element.",
@@ -3091,7 +3091,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
30913091

30923092
parseVarStatement(
30933093
node: N.VariableDeclaration,
3094-
kind: "var" | "let" | "const" | "using",
3094+
kind: "var" | "let" | "const" | "using" | "await using",
30953095
allowMissingInitializer: boolean = false,
30963096
) {
30973097
const { isAmbientContext } = this.state;
@@ -3108,7 +3108,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
31083108
if (!init) continue;
31093109

31103110
// var and let aren't ever allowed initializers.
3111-
if (kind !== "const" || !!id.typeAnnotation) {
3111+
if (kind === "var" || kind === "let" || !!id.typeAnnotation) {
31123112
this.raise(TSErrors.InitializerNotAllowedInAmbientContext, init);
31133113
} else if (
31143114
!isValidAmbientConstInitializer(init, this.hasPlugin("estree"))
@@ -3620,7 +3620,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
36203620
// `let x: number;`
36213621
parseVarId(
36223622
decl: N.VariableDeclarator,
3623-
kind: "var" | "let" | "const" | "using",
3623+
kind: "var" | "let" | "const" | "using" | "await using",
36243624
): void {
36253625
super.parseVarId(decl, kind);
36263626
if (
@@ -4205,7 +4205,7 @@ export default (superClass: ClassWithMixin<typeof Parser, IJSXParserMixin>) =>
42054205
// Foo {}
42064206
if (!this.hasFollowingLineBreak()) {
42074207
node.abstract = true;
4208-
this.raise(TSErrors.NonClassMethodPropertyHasAbstractModifer, node);
4208+
this.raise(TSErrors.NonClassMethodPropertyHasAbstractModifier, node);
42094209
return this.tsParseInterfaceDeclaration(
42104210
node as N.TsInterfaceDeclaration,
42114211
);

packages/babel-parser/test/fixtures/typescript/class/duplicates-accessibility/output.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
"type": "File",
33
"start":0,"end":127,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":7,"column":1,"index":127}},
44
"errors": [
5-
"SyntaxError: Accessibility modifier already seen. (2:9)",
6-
"SyntaxError: Accessibility modifier already seen. (3:10)",
7-
"SyntaxError: Accessibility modifier already seen. (4:12)",
8-
"SyntaxError: Accessibility modifier already seen. (5:9)",
9-
"SyntaxError: Accessibility modifier already seen. (6:9)",
10-
"SyntaxError: Accessibility modifier already seen. (6:19)"
5+
"SyntaxError: Accessibility modifier already seen: 'public'. (2:9)",
6+
"SyntaxError: Accessibility modifier already seen: 'public'. (3:10)",
7+
"SyntaxError: Accessibility modifier already seen: 'private'. (4:12)",
8+
"SyntaxError: Accessibility modifier already seen: 'protected'. (5:9)",
9+
"SyntaxError: Accessibility modifier already seen: 'protected'. (6:9)",
10+
"SyntaxError: Accessibility modifier already seen: 'private'. (6:19)"
1111
],
1212
"program": {
1313
"type": "Program",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
declare namespace invalid_namespace_var {
2+
var A = 0;
3+
var A1: number = 0;
4+
let B = 0;
5+
let B1: number = 0;
6+
const C: number = 0;
7+
using D: number = 0;
8+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plugins": ["explicitResourceManagement", "typescript"]
3+
}
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
{
2+
"type": "File",
3+
"start":0,"end":159,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":159}},
4+
"errors": [
5+
"SyntaxError: Initializers are not allowed in ambient contexts. (2:10)",
6+
"SyntaxError: Initializers are not allowed in ambient contexts. (3:19)",
7+
"SyntaxError: Initializers are not allowed in ambient contexts. (4:10)",
8+
"SyntaxError: Initializers are not allowed in ambient contexts. (5:19)",
9+
"SyntaxError: Initializers are not allowed in ambient contexts. (6:20)",
10+
"SyntaxError: Initializers are not allowed in ambient contexts. (7:20)"
11+
],
12+
"program": {
13+
"type": "Program",
14+
"start":0,"end":159,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":159}},
15+
"sourceType": "module",
16+
"interpreter": null,
17+
"body": [
18+
{
19+
"type": "TSModuleDeclaration",
20+
"start":0,"end":159,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":159}},
21+
"kind": "namespace",
22+
"id": {
23+
"type": "Identifier",
24+
"start":18,"end":39,"loc":{"start":{"line":1,"column":18,"index":18},"end":{"line":1,"column":39,"index":39},"identifierName":"invalid_namespace_var"},
25+
"name": "invalid_namespace_var"
26+
},
27+
"body": {
28+
"type": "TSModuleBlock",
29+
"start":40,"end":159,"loc":{"start":{"line":1,"column":40,"index":40},"end":{"line":8,"column":1,"index":159}},
30+
"body": [
31+
{
32+
"type": "VariableDeclaration",
33+
"start":44,"end":54,"loc":{"start":{"line":2,"column":2,"index":44},"end":{"line":2,"column":12,"index":54}},
34+
"declarations": [
35+
{
36+
"type": "VariableDeclarator",
37+
"start":48,"end":53,"loc":{"start":{"line":2,"column":6,"index":48},"end":{"line":2,"column":11,"index":53}},
38+
"id": {
39+
"type": "Identifier",
40+
"start":48,"end":49,"loc":{"start":{"line":2,"column":6,"index":48},"end":{"line":2,"column":7,"index":49},"identifierName":"A"},
41+
"name": "A"
42+
},
43+
"init": {
44+
"type": "NumericLiteral",
45+
"start":52,"end":53,"loc":{"start":{"line":2,"column":10,"index":52},"end":{"line":2,"column":11,"index":53}},
46+
"extra": {
47+
"rawValue": 0,
48+
"raw": "0"
49+
},
50+
"value": 0
51+
}
52+
}
53+
],
54+
"kind": "var"
55+
},
56+
{
57+
"type": "VariableDeclaration",
58+
"start":57,"end":76,"loc":{"start":{"line":3,"column":2,"index":57},"end":{"line":3,"column":21,"index":76}},
59+
"declarations": [
60+
{
61+
"type": "VariableDeclarator",
62+
"start":61,"end":75,"loc":{"start":{"line":3,"column":6,"index":61},"end":{"line":3,"column":20,"index":75}},
63+
"id": {
64+
"type": "Identifier",
65+
"start":61,"end":71,"loc":{"start":{"line":3,"column":6,"index":61},"end":{"line":3,"column":16,"index":71},"identifierName":"A1"},
66+
"name": "A1",
67+
"typeAnnotation": {
68+
"type": "TSTypeAnnotation",
69+
"start":63,"end":71,"loc":{"start":{"line":3,"column":8,"index":63},"end":{"line":3,"column":16,"index":71}},
70+
"typeAnnotation": {
71+
"type": "TSNumberKeyword",
72+
"start":65,"end":71,"loc":{"start":{"line":3,"column":10,"index":65},"end":{"line":3,"column":16,"index":71}}
73+
}
74+
}
75+
},
76+
"init": {
77+
"type": "NumericLiteral",
78+
"start":74,"end":75,"loc":{"start":{"line":3,"column":19,"index":74},"end":{"line":3,"column":20,"index":75}},
79+
"extra": {
80+
"rawValue": 0,
81+
"raw": "0"
82+
},
83+
"value": 0
84+
}
85+
}
86+
],
87+
"kind": "var"
88+
},
89+
{
90+
"type": "VariableDeclaration",
91+
"start":79,"end":89,"loc":{"start":{"line":4,"column":2,"index":79},"end":{"line":4,"column":12,"index":89}},
92+
"declarations": [
93+
{
94+
"type": "VariableDeclarator",
95+
"start":83,"end":88,"loc":{"start":{"line":4,"column":6,"index":83},"end":{"line":4,"column":11,"index":88}},
96+
"id": {
97+
"type": "Identifier",
98+
"start":83,"end":84,"loc":{"start":{"line":4,"column":6,"index":83},"end":{"line":4,"column":7,"index":84},"identifierName":"B"},
99+
"name": "B"
100+
},
101+
"init": {
102+
"type": "NumericLiteral",
103+
"start":87,"end":88,"loc":{"start":{"line":4,"column":10,"index":87},"end":{"line":4,"column":11,"index":88}},
104+
"extra": {
105+
"rawValue": 0,
106+
"raw": "0"
107+
},
108+
"value": 0
109+
}
110+
}
111+
],
112+
"kind": "let"
113+
},
114+
{
115+
"type": "VariableDeclaration",
116+
"start":92,"end":111,"loc":{"start":{"line":5,"column":2,"index":92},"end":{"line":5,"column":21,"index":111}},
117+
"declarations": [
118+
{
119+
"type": "VariableDeclarator",
120+
"start":96,"end":110,"loc":{"start":{"line":5,"column":6,"index":96},"end":{"line":5,"column":20,"index":110}},
121+
"id": {
122+
"type": "Identifier",
123+
"start":96,"end":106,"loc":{"start":{"line":5,"column":6,"index":96},"end":{"line":5,"column":16,"index":106},"identifierName":"B1"},
124+
"name": "B1",
125+
"typeAnnotation": {
126+
"type": "TSTypeAnnotation",
127+
"start":98,"end":106,"loc":{"start":{"line":5,"column":8,"index":98},"end":{"line":5,"column":16,"index":106}},
128+
"typeAnnotation": {
129+
"type": "TSNumberKeyword",
130+
"start":100,"end":106,"loc":{"start":{"line":5,"column":10,"index":100},"end":{"line":5,"column":16,"index":106}}
131+
}
132+
}
133+
},
134+
"init": {
135+
"type": "NumericLiteral",
136+
"start":109,"end":110,"loc":{"start":{"line":5,"column":19,"index":109},"end":{"line":5,"column":20,"index":110}},
137+
"extra": {
138+
"rawValue": 0,
139+
"raw": "0"
140+
},
141+
"value": 0
142+
}
143+
}
144+
],
145+
"kind": "let"
146+
},
147+
{
148+
"type": "VariableDeclaration",
149+
"start":114,"end":134,"loc":{"start":{"line":6,"column":2,"index":114},"end":{"line":6,"column":22,"index":134}},
150+
"declarations": [
151+
{
152+
"type": "VariableDeclarator",
153+
"start":120,"end":133,"loc":{"start":{"line":6,"column":8,"index":120},"end":{"line":6,"column":21,"index":133}},
154+
"id": {
155+
"type": "Identifier",
156+
"start":120,"end":129,"loc":{"start":{"line":6,"column":8,"index":120},"end":{"line":6,"column":17,"index":129},"identifierName":"C"},
157+
"name": "C",
158+
"typeAnnotation": {
159+
"type": "TSTypeAnnotation",
160+
"start":121,"end":129,"loc":{"start":{"line":6,"column":9,"index":121},"end":{"line":6,"column":17,"index":129}},
161+
"typeAnnotation": {
162+
"type": "TSNumberKeyword",
163+
"start":123,"end":129,"loc":{"start":{"line":6,"column":11,"index":123},"end":{"line":6,"column":17,"index":129}}
164+
}
165+
}
166+
},
167+
"init": {
168+
"type": "NumericLiteral",
169+
"start":132,"end":133,"loc":{"start":{"line":6,"column":20,"index":132},"end":{"line":6,"column":21,"index":133}},
170+
"extra": {
171+
"rawValue": 0,
172+
"raw": "0"
173+
},
174+
"value": 0
175+
}
176+
}
177+
],
178+
"kind": "const"
179+
},
180+
{
181+
"type": "VariableDeclaration",
182+
"start":137,"end":157,"loc":{"start":{"line":7,"column":2,"index":137},"end":{"line":7,"column":22,"index":157}},
183+
"declarations": [
184+
{
185+
"type": "VariableDeclarator",
186+
"start":143,"end":156,"loc":{"start":{"line":7,"column":8,"index":143},"end":{"line":7,"column":21,"index":156}},
187+
"id": {
188+
"type": "Identifier",
189+
"start":143,"end":152,"loc":{"start":{"line":7,"column":8,"index":143},"end":{"line":7,"column":17,"index":152},"identifierName":"D"},
190+
"name": "D",
191+
"typeAnnotation": {
192+
"type": "TSTypeAnnotation",
193+
"start":144,"end":152,"loc":{"start":{"line":7,"column":9,"index":144},"end":{"line":7,"column":17,"index":152}},
194+
"typeAnnotation": {
195+
"type": "TSNumberKeyword",
196+
"start":146,"end":152,"loc":{"start":{"line":7,"column":11,"index":146},"end":{"line":7,"column":17,"index":152}}
197+
}
198+
}
199+
},
200+
"init": {
201+
"type": "NumericLiteral",
202+
"start":155,"end":156,"loc":{"start":{"line":7,"column":20,"index":155},"end":{"line":7,"column":21,"index":156}},
203+
"extra": {
204+
"rawValue": 0,
205+
"raw": "0"
206+
},
207+
"value": 0
208+
}
209+
}
210+
],
211+
"kind": "using"
212+
}
213+
]
214+
},
215+
"declare": true
216+
}
217+
],
218+
"directives": [],
219+
"extra": {
220+
"topLevelAwait": false
221+
}
222+
}
223+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
declare namespace valid_namespace_var {
2+
var A;
3+
let B;
4+
const C;
5+
const C1 = 0;
6+
using D;
7+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plugins": ["explicitResourceManagement", "typescript"]
3+
}

0 commit comments

Comments
 (0)