Skip to content

Commit 8324244

Browse files
authored
Merge pull request #14823 from Microsoft/fix14620
Fix #14620: Lookup names in exports as well as locals when binding special properties
2 parents 271a8fa + c83a3d0 commit 8324244

File tree

4 files changed

+329
-2
lines changed

4 files changed

+329
-2
lines changed

src/compiler/binder.ts

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

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

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

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