Skip to content

Commit 40dfe9a

Browse files
liuxingbaoyuJLHwungnicolo-ribaudo
authored
fix: Support local exports in TS declare modules (#14941)
Co-authored-by: Huáng Jùnliàng <jlhwung@gmail.com> Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
1 parent ae10b49 commit 40dfe9a

6 files changed

Lines changed: 307 additions & 11 deletions

File tree

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,16 @@ export default class TypeScriptScopeHandler extends ScopeHandler<TypeScriptScope
143143
}
144144

145145
checkLocalExport(id: N.Identifier) {
146-
const topLevelScope = this.scopeStack[0];
147146
const { name } = id;
148-
if (
149-
!topLevelScope.types.has(name) &&
150-
!topLevelScope.exportOnlyBindings.has(name) &&
151-
!this.hasImport(name)
152-
) {
153-
super.checkLocalExport(id);
147+
148+
if (this.hasImport(name)) return;
149+
150+
const len = this.scopeStack.length;
151+
for (let i = len - 1; i >= 0; i--) {
152+
const scope = this.scopeStack[i];
153+
if (scope.types.has(name) || scope.exportOnlyBindings.has(name)) return;
154154
}
155+
156+
super.checkLocalExport(id);
155157
}
156158
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
declare module "m2" {
2+
export module X {
3+
interface I { }
4+
}
5+
function Y();
6+
export { Y as X };
7+
function Z(): X.I;
8+
}
9+
10+
declare module "m2" {
11+
function Z2(): X.I;
12+
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
{
2+
"type": "File",
3+
"start":0,"end":188,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":12,"column":1,"index":188}},
4+
"program": {
5+
"type": "Program",
6+
"start":0,"end":188,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":12,"column":1,"index":188}},
7+
"sourceType": "module",
8+
"interpreter": null,
9+
"body": [
10+
{
11+
"type": "TSModuleDeclaration",
12+
"start":0,"end":139,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":8,"column":1,"index":139}},
13+
"id": {
14+
"type": "StringLiteral",
15+
"start":15,"end":19,"loc":{"start":{"line":1,"column":15,"index":15},"end":{"line":1,"column":19,"index":19}},
16+
"extra": {
17+
"rawValue": "m2",
18+
"raw": "\"m2\""
19+
},
20+
"value": "m2"
21+
},
22+
"body": {
23+
"type": "TSModuleBlock",
24+
"start":20,"end":139,"loc":{"start":{"line":1,"column":20,"index":20},"end":{"line":8,"column":1,"index":139}},
25+
"body": [
26+
{
27+
"type": "ExportNamedDeclaration",
28+
"start":26,"end":73,"loc":{"start":{"line":2,"column":4,"index":26},"end":{"line":4,"column":5,"index":73}},
29+
"exportKind": "value",
30+
"specifiers": [],
31+
"source": null,
32+
"declaration": {
33+
"type": "TSModuleDeclaration",
34+
"start":33,"end":73,"loc":{"start":{"line":2,"column":11,"index":33},"end":{"line":4,"column":5,"index":73}},
35+
"id": {
36+
"type": "Identifier",
37+
"start":40,"end":41,"loc":{"start":{"line":2,"column":18,"index":40},"end":{"line":2,"column":19,"index":41},"identifierName":"X"},
38+
"name": "X"
39+
},
40+
"body": {
41+
"type": "TSModuleBlock",
42+
"start":42,"end":73,"loc":{"start":{"line":2,"column":20,"index":42},"end":{"line":4,"column":5,"index":73}},
43+
"body": [
44+
{
45+
"type": "TSInterfaceDeclaration",
46+
"start":52,"end":67,"loc":{"start":{"line":3,"column":8,"index":52},"end":{"line":3,"column":23,"index":67}},
47+
"id": {
48+
"type": "Identifier",
49+
"start":62,"end":63,"loc":{"start":{"line":3,"column":18,"index":62},"end":{"line":3,"column":19,"index":63},"identifierName":"I"},
50+
"name": "I"
51+
},
52+
"body": {
53+
"type": "TSInterfaceBody",
54+
"start":64,"end":67,"loc":{"start":{"line":3,"column":20,"index":64},"end":{"line":3,"column":23,"index":67}},
55+
"body": []
56+
}
57+
}
58+
]
59+
}
60+
}
61+
},
62+
{
63+
"type": "TSDeclareFunction",
64+
"start":78,"end":91,"loc":{"start":{"line":5,"column":4,"index":78},"end":{"line":5,"column":17,"index":91}},
65+
"id": {
66+
"type": "Identifier",
67+
"start":87,"end":88,"loc":{"start":{"line":5,"column":13,"index":87},"end":{"line":5,"column":14,"index":88},"identifierName":"Y"},
68+
"name": "Y"
69+
},
70+
"generator": false,
71+
"async": false,
72+
"params": []
73+
},
74+
{
75+
"type": "ExportNamedDeclaration",
76+
"start":96,"end":114,"loc":{"start":{"line":6,"column":4,"index":96},"end":{"line":6,"column":22,"index":114}},
77+
"exportKind": "value",
78+
"specifiers": [
79+
{
80+
"type": "ExportSpecifier",
81+
"start":105,"end":111,"loc":{"start":{"line":6,"column":13,"index":105},"end":{"line":6,"column":19,"index":111}},
82+
"local": {
83+
"type": "Identifier",
84+
"start":105,"end":106,"loc":{"start":{"line":6,"column":13,"index":105},"end":{"line":6,"column":14,"index":106},"identifierName":"Y"},
85+
"name": "Y"
86+
},
87+
"exportKind": "value",
88+
"exported": {
89+
"type": "Identifier",
90+
"start":110,"end":111,"loc":{"start":{"line":6,"column":18,"index":110},"end":{"line":6,"column":19,"index":111},"identifierName":"X"},
91+
"name": "X"
92+
}
93+
}
94+
],
95+
"source": null,
96+
"declaration": null
97+
},
98+
{
99+
"type": "TSDeclareFunction",
100+
"start":119,"end":137,"loc":{"start":{"line":7,"column":4,"index":119},"end":{"line":7,"column":22,"index":137}},
101+
"id": {
102+
"type": "Identifier",
103+
"start":128,"end":129,"loc":{"start":{"line":7,"column":13,"index":128},"end":{"line":7,"column":14,"index":129},"identifierName":"Z"},
104+
"name": "Z"
105+
},
106+
"generator": false,
107+
"async": false,
108+
"params": [],
109+
"returnType": {
110+
"type": "TSTypeAnnotation",
111+
"start":131,"end":136,"loc":{"start":{"line":7,"column":16,"index":131},"end":{"line":7,"column":21,"index":136}},
112+
"typeAnnotation": {
113+
"type": "TSTypeReference",
114+
"start":133,"end":136,"loc":{"start":{"line":7,"column":18,"index":133},"end":{"line":7,"column":21,"index":136}},
115+
"typeName": {
116+
"type": "TSQualifiedName",
117+
"start":133,"end":136,"loc":{"start":{"line":7,"column":18,"index":133},"end":{"line":7,"column":21,"index":136}},
118+
"left": {
119+
"type": "Identifier",
120+
"start":133,"end":134,"loc":{"start":{"line":7,"column":18,"index":133},"end":{"line":7,"column":19,"index":134},"identifierName":"X"},
121+
"name": "X"
122+
},
123+
"right": {
124+
"type": "Identifier",
125+
"start":135,"end":136,"loc":{"start":{"line":7,"column":20,"index":135},"end":{"line":7,"column":21,"index":136},"identifierName":"I"},
126+
"name": "I"
127+
}
128+
}
129+
}
130+
}
131+
}
132+
]
133+
},
134+
"declare": true
135+
},
136+
{
137+
"type": "TSModuleDeclaration",
138+
"start":141,"end":188,"loc":{"start":{"line":10,"column":0,"index":141},"end":{"line":12,"column":1,"index":188}},
139+
"id": {
140+
"type": "StringLiteral",
141+
"start":156,"end":160,"loc":{"start":{"line":10,"column":15,"index":156},"end":{"line":10,"column":19,"index":160}},
142+
"extra": {
143+
"rawValue": "m2",
144+
"raw": "\"m2\""
145+
},
146+
"value": "m2"
147+
},
148+
"body": {
149+
"type": "TSModuleBlock",
150+
"start":161,"end":188,"loc":{"start":{"line":10,"column":20,"index":161},"end":{"line":12,"column":1,"index":188}},
151+
"body": [
152+
{
153+
"type": "TSDeclareFunction",
154+
"start":167,"end":186,"loc":{"start":{"line":11,"column":4,"index":167},"end":{"line":11,"column":23,"index":186}},
155+
"id": {
156+
"type": "Identifier",
157+
"start":176,"end":178,"loc":{"start":{"line":11,"column":13,"index":176},"end":{"line":11,"column":15,"index":178},"identifierName":"Z2"},
158+
"name": "Z2"
159+
},
160+
"generator": false,
161+
"async": false,
162+
"params": [],
163+
"returnType": {
164+
"type": "TSTypeAnnotation",
165+
"start":180,"end":185,"loc":{"start":{"line":11,"column":17,"index":180},"end":{"line":11,"column":22,"index":185}},
166+
"typeAnnotation": {
167+
"type": "TSTypeReference",
168+
"start":182,"end":185,"loc":{"start":{"line":11,"column":19,"index":182},"end":{"line":11,"column":22,"index":185}},
169+
"typeName": {
170+
"type": "TSQualifiedName",
171+
"start":182,"end":185,"loc":{"start":{"line":11,"column":19,"index":182},"end":{"line":11,"column":22,"index":185}},
172+
"left": {
173+
"type": "Identifier",
174+
"start":182,"end":183,"loc":{"start":{"line":11,"column":19,"index":182},"end":{"line":11,"column":20,"index":183},"identifierName":"X"},
175+
"name": "X"
176+
},
177+
"right": {
178+
"type": "Identifier",
179+
"start":184,"end":185,"loc":{"start":{"line":11,"column":21,"index":184},"end":{"line":11,"column":22,"index":185},"identifierName":"I"},
180+
"name": "I"
181+
}
182+
}
183+
}
184+
}
185+
}
186+
]
187+
},
188+
"declare": true
189+
}
190+
],
191+
"directives": []
192+
}
193+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module '~popsicle/dist/common' {
2+
import { Request } from '~popsicle/dist/request';
3+
export { Request };
4+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"type": "File",
3+
"start":0,"end":120,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":4,"column":1,"index":120}},
4+
"program": {
5+
"type": "Program",
6+
"start":0,"end":120,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":4,"column":1,"index":120}},
7+
"sourceType": "module",
8+
"interpreter": null,
9+
"body": [
10+
{
11+
"type": "TSModuleDeclaration",
12+
"start":0,"end":120,"loc":{"start":{"line":1,"column":0,"index":0},"end":{"line":4,"column":1,"index":120}},
13+
"id": {
14+
"type": "StringLiteral",
15+
"start":15,"end":38,"loc":{"start":{"line":1,"column":15,"index":15},"end":{"line":1,"column":38,"index":38}},
16+
"extra": {
17+
"rawValue": "~popsicle/dist/common",
18+
"raw": "'~popsicle/dist/common'"
19+
},
20+
"value": "~popsicle/dist/common"
21+
},
22+
"body": {
23+
"type": "TSModuleBlock",
24+
"start":39,"end":120,"loc":{"start":{"line":1,"column":39,"index":39},"end":{"line":4,"column":1,"index":120}},
25+
"body": [
26+
{
27+
"type": "ImportDeclaration",
28+
"start":45,"end":94,"loc":{"start":{"line":2,"column":4,"index":45},"end":{"line":2,"column":53,"index":94}},
29+
"importKind": "value",
30+
"specifiers": [
31+
{
32+
"type": "ImportSpecifier",
33+
"start":54,"end":61,"loc":{"start":{"line":2,"column":13,"index":54},"end":{"line":2,"column":20,"index":61}},
34+
"imported": {
35+
"type": "Identifier",
36+
"start":54,"end":61,"loc":{"start":{"line":2,"column":13,"index":54},"end":{"line":2,"column":20,"index":61},"identifierName":"Request"},
37+
"name": "Request"
38+
},
39+
"importKind": "value",
40+
"local": {
41+
"type": "Identifier",
42+
"start":54,"end":61,"loc":{"start":{"line":2,"column":13,"index":54},"end":{"line":2,"column":20,"index":61},"identifierName":"Request"},
43+
"name": "Request"
44+
}
45+
}
46+
],
47+
"source": {
48+
"type": "StringLiteral",
49+
"start":69,"end":93,"loc":{"start":{"line":2,"column":28,"index":69},"end":{"line":2,"column":52,"index":93}},
50+
"extra": {
51+
"rawValue": "~popsicle/dist/request",
52+
"raw": "'~popsicle/dist/request'"
53+
},
54+
"value": "~popsicle/dist/request"
55+
}
56+
},
57+
{
58+
"type": "ExportNamedDeclaration",
59+
"start":99,"end":118,"loc":{"start":{"line":3,"column":4,"index":99},"end":{"line":3,"column":23,"index":118}},
60+
"exportKind": "value",
61+
"specifiers": [
62+
{
63+
"type": "ExportSpecifier",
64+
"start":108,"end":115,"loc":{"start":{"line":3,"column":13,"index":108},"end":{"line":3,"column":20,"index":115}},
65+
"local": {
66+
"type": "Identifier",
67+
"start":108,"end":115,"loc":{"start":{"line":3,"column":13,"index":108},"end":{"line":3,"column":20,"index":115},"identifierName":"Request"},
68+
"name": "Request"
69+
},
70+
"exportKind": "value",
71+
"exported": {
72+
"type": "Identifier",
73+
"start":108,"end":115,"loc":{"start":{"line":3,"column":13,"index":108},"end":{"line":3,"column":20,"index":115},"identifierName":"Request"},
74+
"name": "Request"
75+
}
76+
}
77+
],
78+
"source": null,
79+
"declaration": null
80+
}
81+
]
82+
},
83+
"declare": true
84+
}
85+
],
86+
"directives": []
87+
}
88+
}

scripts/parser-tests/typescript/allowlist.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ exportDeclarationsInAmbientNamespaces2.ts
1111
multipleExports.ts
1212

1313

14-
# 134 valid programs produced a parsing error
14+
# 131 valid programs produced a parsing error
1515

1616
ArrowFunctionExpression1.ts
1717
MemberAccessorDeclaration15.ts
@@ -71,12 +71,9 @@ exportAssignmentWithDeclareAndExportModifiers.ts
7171
exportAssignmentWithDeclareModifier.ts
7272
exportAssignmentWithExportModifier.ts
7373
exportClassWithoutName.ts
74-
exportDeclarationsInAmbientNamespaces.ts
7574
exportDefaultAsyncFunction2.ts
7675
exportInterfaceClassAndValue.ts
7776
exportSameNameFuncVar.ts
78-
exportSpecifierAndExportedMemberDeclaration.ts
79-
exportSpecifierAndLocalMemberDeclaration.ts
8077
exportSpecifierForAGlobal.ts # We handle this fine, but it doesn't consider the different files together
8178
exportSpecifierReferencingOuterDeclaration2.ts # We handle this fine, but it doesn't consider the different files together
8279
expressionsForbiddenInParameterInitializers.ts

0 commit comments

Comments
 (0)