Skip to content

Commit 19ada97

Browse files
committed
Fix #14620: Lookup names in exports as well as locals when binding special properties
1 parent 87c291e commit 19ada97

File tree

4 files changed

+331
-2
lines changed

4 files changed

+331
-2
lines changed

src/compiler/binder.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2297,7 +2297,7 @@ namespace ts {
22972297

22982298
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
22992299
if (node.kind === SyntaxKind.Identifier) {
2300-
const symbol = container.locals.get((<Identifier>node).text);
2300+
const symbol = lookupSymbolForName((<Identifier>node).text);
23012301
if (symbol && symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
23022302
const declaration = symbol.valueDeclaration as VariableDeclaration;
23032303
if (declaration.initializer) {
@@ -2399,8 +2399,12 @@ namespace ts {
23992399
}
24002400
}
24012401

2402+
function lookupSymbolForName(name: string) {
2403+
return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || container.locals.get(name);
2404+
}
2405+
24022406
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
2403-
let targetSymbol = container.locals.get(functionName);
2407+
let targetSymbol = lookupSymbolForName(functionName);
24042408

24052409
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
24062410
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
=== tests/cases/conformance/salsa/a.js ===
2+
3+
export class C1 { }
4+
>C1 : Symbol(C1, Decl(a.js, 0, 0))
5+
6+
C1.staticProp = 0;
7+
>C1.staticProp : Symbol(C1.staticProp, Decl(a.js, 1, 19))
8+
>C1 : Symbol(C1, Decl(a.js, 0, 0))
9+
>staticProp : Symbol(C1.staticProp, Decl(a.js, 1, 19))
10+
11+
export function F1() { }
12+
>F1 : Symbol(F1, Decl(a.js, 2, 18))
13+
14+
F1.staticProp = 0;
15+
>F1.staticProp : Symbol(F1.staticProp, Decl(a.js, 4, 24))
16+
>F1 : Symbol(F1, Decl(a.js, 2, 18))
17+
>staticProp : Symbol(F1.staticProp, Decl(a.js, 4, 24))
18+
19+
export var C2 = class { };
20+
>C2 : Symbol(C2, Decl(a.js, 7, 10))
21+
22+
C2.staticProp = 0;
23+
>C2.staticProp : Symbol(C2.staticProp, Decl(a.js, 7, 26))
24+
>C2 : Symbol(C2, Decl(a.js, 7, 10))
25+
>staticProp : Symbol(C2.staticProp, Decl(a.js, 7, 26))
26+
27+
export let F2 = function () { };
28+
>F2 : Symbol(F2, Decl(a.js, 10, 10))
29+
30+
F2.staticProp = 0;
31+
>F2.staticProp : Symbol(F2.staticProp, Decl(a.js, 10, 32))
32+
>F2 : Symbol(F2, Decl(a.js, 10, 10))
33+
>staticProp : Symbol(F2.staticProp, Decl(a.js, 10, 32))
34+
35+
=== tests/cases/conformance/salsa/global.js ===
36+
class C3 { }
37+
>C3 : Symbol(C3, Decl(global.js, 0, 0))
38+
39+
C3.staticProp = 0;
40+
>C3.staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12))
41+
>C3 : Symbol(C3, Decl(global.js, 0, 0))
42+
>staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12))
43+
44+
function F3() { }
45+
>F3 : Symbol(F3, Decl(global.js, 1, 18))
46+
47+
F3.staticProp = 0;
48+
>F3.staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17))
49+
>F3 : Symbol(F3, Decl(global.js, 1, 18))
50+
>staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17))
51+
52+
var C4 = class { };
53+
>C4 : Symbol(C4, Decl(global.js, 6, 3))
54+
55+
C4.staticProp = 0;
56+
>C4.staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19))
57+
>C4 : Symbol(C4, Decl(global.js, 6, 3))
58+
>staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19))
59+
60+
let F4 = function () { };
61+
>F4 : Symbol(F4, Decl(global.js, 9, 3))
62+
63+
F4.staticProp = 0;
64+
>F4.staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25))
65+
>F4 : Symbol(F4, Decl(global.js, 9, 3))
66+
>staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25))
67+
68+
=== tests/cases/conformance/salsa/b.ts ===
69+
import * as a from "./a";
70+
>a : Symbol(a, Decl(b.ts, 0, 6))
71+
72+
var n: number;
73+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
74+
75+
var n = a.C1.staticProp;
76+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
77+
>a.C1.staticProp : Symbol(a.C1.staticProp, Decl(a.js, 1, 19))
78+
>a.C1 : Symbol(a.C1, Decl(a.js, 0, 0))
79+
>a : Symbol(a, Decl(b.ts, 0, 6))
80+
>C1 : Symbol(a.C1, Decl(a.js, 0, 0))
81+
>staticProp : Symbol(a.C1.staticProp, Decl(a.js, 1, 19))
82+
83+
var n = a.C2.staticProp;
84+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
85+
>a.C2.staticProp : Symbol(C2.staticProp, Decl(a.js, 7, 26))
86+
>a.C2 : Symbol(a.C2, Decl(a.js, 7, 10))
87+
>a : Symbol(a, Decl(b.ts, 0, 6))
88+
>C2 : Symbol(a.C2, Decl(a.js, 7, 10))
89+
>staticProp : Symbol(C2.staticProp, Decl(a.js, 7, 26))
90+
91+
var n = a.F1.staticProp;
92+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
93+
>a.F1.staticProp : Symbol(a.F1.staticProp, Decl(a.js, 4, 24))
94+
>a.F1 : Symbol(a.F1, Decl(a.js, 2, 18))
95+
>a : Symbol(a, Decl(b.ts, 0, 6))
96+
>F1 : Symbol(a.F1, Decl(a.js, 2, 18))
97+
>staticProp : Symbol(a.F1.staticProp, Decl(a.js, 4, 24))
98+
99+
var n = a.F2.staticProp;
100+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
101+
>a.F2.staticProp : Symbol(F2.staticProp, Decl(a.js, 10, 32))
102+
>a.F2 : Symbol(a.F2, Decl(a.js, 10, 10))
103+
>a : Symbol(a, Decl(b.ts, 0, 6))
104+
>F2 : Symbol(a.F2, Decl(a.js, 10, 10))
105+
>staticProp : Symbol(F2.staticProp, Decl(a.js, 10, 32))
106+
107+
108+
var n = C3.staticProp;
109+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
110+
>C3.staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12))
111+
>C3 : Symbol(C3, Decl(global.js, 0, 0))
112+
>staticProp : Symbol(C3.staticProp, Decl(global.js, 0, 12))
113+
114+
var n = C4.staticProp;
115+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
116+
>C4.staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19))
117+
>C4 : Symbol(C4, Decl(global.js, 6, 3))
118+
>staticProp : Symbol(C4.staticProp, Decl(global.js, 6, 19))
119+
120+
var n = F3.staticProp;
121+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
122+
>F3.staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17))
123+
>F3 : Symbol(F3, Decl(global.js, 1, 18))
124+
>staticProp : Symbol(F3.staticProp, Decl(global.js, 3, 17))
125+
126+
var n = F4.staticProp;
127+
>n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3), Decl(b.ts, 9, 3), Decl(b.ts, 10, 3), Decl(b.ts, 11, 3), Decl(b.ts, 12, 3))
128+
>F4.staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25))
129+
>F4 : Symbol(F4, Decl(global.js, 9, 3))
130+
>staticProp : Symbol(F4.staticProp, Decl(global.js, 9, 25))
131+
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
=== tests/cases/conformance/salsa/a.js ===
2+
3+
export class C1 { }
4+
>C1 : C1
5+
6+
C1.staticProp = 0;
7+
>C1.staticProp = 0 : 0
8+
>C1.staticProp : number
9+
>C1 : typeof C1
10+
>staticProp : number
11+
>0 : 0
12+
13+
export function F1() { }
14+
>F1 : { (): void; staticProp: number; }
15+
16+
F1.staticProp = 0;
17+
>F1.staticProp = 0 : 0
18+
>F1.staticProp : number
19+
>F1 : { (): void; staticProp: number; }
20+
>staticProp : number
21+
>0 : 0
22+
23+
export var C2 = class { };
24+
>C2 : typeof C2
25+
>class { } : typeof C2
26+
27+
C2.staticProp = 0;
28+
>C2.staticProp = 0 : 0
29+
>C2.staticProp : number
30+
>C2 : typeof C2
31+
>staticProp : number
32+
>0 : 0
33+
34+
export let F2 = function () { };
35+
>F2 : { (): void; staticProp: number; }
36+
>function () { } : { (): void; staticProp: number; }
37+
38+
F2.staticProp = 0;
39+
>F2.staticProp = 0 : 0
40+
>F2.staticProp : number
41+
>F2 : { (): void; staticProp: number; }
42+
>staticProp : number
43+
>0 : 0
44+
45+
=== tests/cases/conformance/salsa/global.js ===
46+
class C3 { }
47+
>C3 : C3
48+
49+
C3.staticProp = 0;
50+
>C3.staticProp = 0 : 0
51+
>C3.staticProp : number
52+
>C3 : typeof C3
53+
>staticProp : number
54+
>0 : 0
55+
56+
function F3() { }
57+
>F3 : { (): void; staticProp: number; }
58+
59+
F3.staticProp = 0;
60+
>F3.staticProp = 0 : 0
61+
>F3.staticProp : number
62+
>F3 : { (): void; staticProp: number; }
63+
>staticProp : number
64+
>0 : 0
65+
66+
var C4 = class { };
67+
>C4 : typeof C4
68+
>class { } : typeof C4
69+
70+
C4.staticProp = 0;
71+
>C4.staticProp = 0 : 0
72+
>C4.staticProp : number
73+
>C4 : typeof C4
74+
>staticProp : number
75+
>0 : 0
76+
77+
let F4 = function () { };
78+
>F4 : { (): void; staticProp: number; }
79+
>function () { } : { (): void; staticProp: number; }
80+
81+
F4.staticProp = 0;
82+
>F4.staticProp = 0 : 0
83+
>F4.staticProp : number
84+
>F4 : { (): void; staticProp: number; }
85+
>staticProp : number
86+
>0 : 0
87+
88+
=== tests/cases/conformance/salsa/b.ts ===
89+
import * as a from "./a";
90+
>a : typeof a
91+
92+
var n: number;
93+
>n : number
94+
95+
var n = a.C1.staticProp;
96+
>n : number
97+
>a.C1.staticProp : number
98+
>a.C1 : typeof a.C1
99+
>a : typeof a
100+
>C1 : typeof a.C1
101+
>staticProp : number
102+
103+
var n = a.C2.staticProp;
104+
>n : number
105+
>a.C2.staticProp : number
106+
>a.C2 : typeof C2
107+
>a : typeof a
108+
>C2 : typeof C2
109+
>staticProp : number
110+
111+
var n = a.F1.staticProp;
112+
>n : number
113+
>a.F1.staticProp : number
114+
>a.F1 : { (): void; staticProp: number; }
115+
>a : typeof a
116+
>F1 : { (): void; staticProp: number; }
117+
>staticProp : number
118+
119+
var n = a.F2.staticProp;
120+
>n : number
121+
>a.F2.staticProp : number
122+
>a.F2 : { (): void; staticProp: number; }
123+
>a : typeof a
124+
>F2 : { (): void; staticProp: number; }
125+
>staticProp : number
126+
127+
128+
var n = C3.staticProp;
129+
>n : number
130+
>C3.staticProp : number
131+
>C3 : typeof C3
132+
>staticProp : number
133+
134+
var n = C4.staticProp;
135+
>n : number
136+
>C4.staticProp : number
137+
>C4 : typeof C4
138+
>staticProp : number
139+
140+
var n = F3.staticProp;
141+
>n : number
142+
>F3.staticProp : number
143+
>F3 : { (): void; staticProp: number; }
144+
>staticProp : number
145+
146+
var n = F4.staticProp;
147+
>n : number
148+
>F4.staticProp : number
149+
>F4 : { (): void; staticProp: number; }
150+
>staticProp : number
151+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// @noEmit: true
2+
// @allowJs: true
3+
4+
// @filename: a.js
5+
export class C1 { }
6+
C1.staticProp = 0;
7+
8+
export function F1() { }
9+
F1.staticProp = 0;
10+
11+
export var C2 = class { };
12+
C2.staticProp = 0;
13+
14+
export let F2 = function () { };
15+
F2.staticProp = 0;
16+
17+
//@filename: global.js
18+
class C3 { }
19+
C3.staticProp = 0;
20+
21+
function F3() { }
22+
F3.staticProp = 0;
23+
24+
var C4 = class { };
25+
C4.staticProp = 0;
26+
27+
let F4 = function () { };
28+
F4.staticProp = 0;
29+
30+
// @filename: b.ts
31+
import * as a from "./a";
32+
var n: number;
33+
34+
var n = a.C1.staticProp;
35+
var n = a.C2.staticProp;
36+
var n = a.F1.staticProp;
37+
var n = a.F2.staticProp;
38+
39+
40+
var n = C3.staticProp;
41+
var n = C4.staticProp;
42+
var n = F3.staticProp;
43+
var n = F4.staticProp;

0 commit comments

Comments
 (0)