Skip to content

Commit be2ca35

Browse files
authored
Fix 8467: Fix incorrect emit for accessing static property in static propertyDeclaration (#8551)
* Fix incorrect emit for accessing static property in static propertyDeclaration * Update tests and baselines * Update function name * Fix when accessing static property inside arrow function * Add tests and baselines
1 parent e182ecf commit be2ca35

13 files changed

+281
-28
lines changed

src/compiler/emitter.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16731673
return false;
16741674
}
16751675

1676+
function getClassExpressionInPropertyAccessInStaticPropertyDeclaration(node: Identifier) {
1677+
if (languageVersion >= ScriptTarget.ES6) {
1678+
let parent = node.parent;
1679+
if (parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>parent).expression === node) {
1680+
parent = parent.parent;
1681+
while (parent && parent.kind !== SyntaxKind.PropertyDeclaration) {
1682+
parent = parent.parent;
1683+
}
1684+
return parent && parent.kind === SyntaxKind.PropertyDeclaration && (parent.flags & NodeFlags.Static) !== 0 &&
1685+
parent.parent.kind === SyntaxKind.ClassExpression ? parent.parent : undefined;
1686+
}
1687+
}
1688+
return undefined;
1689+
}
1690+
16761691
function emitIdentifier(node: Identifier) {
16771692
if (convertedLoopState) {
16781693
if (node.text == "arguments" && resolver.isArgumentsLocalBinding(node)) {
@@ -1687,6 +1702,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16871702
write(node.text);
16881703
}
16891704
else if (isExpressionIdentifier(node)) {
1705+
const classExpression = getClassExpressionInPropertyAccessInStaticPropertyDeclaration(node);
1706+
if (classExpression) {
1707+
const declaration = resolver.getReferencedValueDeclaration(node);
1708+
if (declaration === classExpression) {
1709+
write(getGeneratedNameForNode(declaration.name));
1710+
return;
1711+
}
1712+
}
16901713
emitExpressionIdentifier(node);
16911714
}
16921715
else if (isNameOfNestedBlockScopedRedeclarationOrCapturedBinding(node)) {
@@ -5086,13 +5109,13 @@ const _super = (function (geti, seti) {
50865109
}
50875110
}
50885111

5089-
function emitPropertyDeclaration(node: ClassLikeDeclaration, property: PropertyDeclaration, receiver?: Identifier, isExpression?: boolean) {
5112+
function emitPropertyDeclaration(node: ClassLikeDeclaration, property: PropertyDeclaration, receiver?: string, isExpression?: boolean) {
50905113
writeLine();
50915114
emitLeadingComments(property);
50925115
emitStart(property);
50935116
emitStart(property.name);
50945117
if (receiver) {
5095-
emit(receiver);
5118+
write(receiver);
50965119
}
50975120
else {
50985121
if (property.flags & NodeFlags.Static) {
@@ -5511,13 +5534,16 @@ const _super = (function (geti, seti) {
55115534
// of it have been initialized by the time it is used.
55125535
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
55135536
const isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
5514-
let tempVariable: Identifier;
5537+
let generatedName: string;
55155538

55165539
if (isClassExpressionWithStaticProperties) {
5517-
tempVariable = createAndRecordTempVariable(TempFlags.Auto);
5540+
generatedName = getGeneratedNameForNode(node.name);
5541+
const synthesizedNode = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
5542+
synthesizedNode.text = generatedName;
5543+
recordTempDeclaration(synthesizedNode);
55185544
write("(");
55195545
increaseIndent();
5520-
emit(tempVariable);
5546+
emit(synthesizedNode);
55215547
write(" = ");
55225548
}
55235549

@@ -5571,11 +5597,11 @@ const _super = (function (geti, seti) {
55715597
for (const property of staticProperties) {
55725598
write(",");
55735599
writeLine();
5574-
emitPropertyDeclaration(node, property, /*receiver*/ tempVariable, /*isExpression*/ true);
5600+
emitPropertyDeclaration(node, property, /*receiver*/ generatedName, /*isExpression*/ true);
55755601
}
55765602
write(",");
55775603
writeLine();
5578-
emit(tempVariable);
5604+
write(generatedName);
55795605
decreaseIndent();
55805606
write(")");
55815607
}
Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
//// [classExpressionWithStaticPropertiesES61.ts]
2-
var v = class C { static a = 1; static b = 2 };
2+
var v = class C {
3+
static a = 1;
4+
static b = 2;
5+
static c = C.a + 3;
6+
};
37

48
//// [classExpressionWithStaticPropertiesES61.js]
5-
var v = (_a = class C {
9+
var v = (C_1 = class C {
610
},
7-
_a.a = 1,
8-
_a.b = 2,
9-
_a);
10-
var _a;
11+
C_1.a = 1,
12+
C_1.b = 2,
13+
C_1.c = C_1.a + 3,
14+
C_1);
15+
var C_1;
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
=== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts ===
2-
var v = class C { static a = 1; static b = 2 };
2+
var v = class C {
33
>v : Symbol(v, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 3))
4+
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 7))
5+
6+
static a = 1;
7+
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
8+
9+
static b = 2;
10+
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES61.ts, 1, 17))
11+
12+
static c = C.a + 3;
13+
>c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES61.ts, 2, 17))
14+
>C.a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
415
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 7))
516
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
6-
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 31))
717

18+
};
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
=== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts ===
2-
var v = class C { static a = 1; static b = 2 };
2+
var v = class C {
33
>v : typeof C
4-
>class C { static a = 1; static b = 2 } : typeof C
4+
>class C { static a = 1; static b = 2; static c = C.a + 3;} : typeof C
55
>C : typeof C
6+
7+
static a = 1;
68
>a : number
79
>1 : number
10+
11+
static b = 2;
812
>b : number
913
>2 : number
1014

15+
static c = C.a + 3;
16+
>c : number
17+
>C.a + 3 : number
18+
>C.a : number
19+
>C : typeof C
20+
>a : number
21+
>3 : number
22+
23+
};
Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
//// [classExpressionWithStaticPropertiesES62.ts]
2-
var v = class C { static a = 1; static b };
2+
var v = class C {
3+
static a = 1;
4+
static b
5+
static c = {
6+
x: "hi"
7+
}
8+
static d = C.c.x + " world";
9+
};
310

411
//// [classExpressionWithStaticPropertiesES62.js]
5-
var v = (_a = class C {
12+
var v = (C_1 = class C {
613
},
7-
_a.a = 1,
8-
_a);
9-
var _a;
14+
C_1.a = 1,
15+
C_1.c = {
16+
x: "hi"
17+
},
18+
C_1.d = C_1.c.x + " world",
19+
C_1);
20+
var C_1;
Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
11
=== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts ===
2-
var v = class C { static a = 1; static b };
2+
var v = class C {
33
>v : Symbol(v, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 3))
44
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 7))
5+
6+
static a = 1;
57
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 17))
6-
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 31))
78

9+
static b
10+
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES62.ts, 1, 17))
11+
12+
static c = {
13+
>c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES62.ts, 2, 12))
14+
15+
x: "hi"
16+
>x : Symbol(x, Decl(classExpressionWithStaticPropertiesES62.ts, 3, 16))
17+
}
18+
static d = C.c.x + " world";
19+
>d : Symbol(C.d, Decl(classExpressionWithStaticPropertiesES62.ts, 5, 5))
20+
>C.c.x : Symbol(x, Decl(classExpressionWithStaticPropertiesES62.ts, 3, 16))
21+
>C.c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES62.ts, 2, 12))
22+
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 7))
23+
>c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES62.ts, 2, 12))
24+
>x : Symbol(x, Decl(classExpressionWithStaticPropertiesES62.ts, 3, 16))
25+
26+
};
Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,32 @@
11
=== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts ===
2-
var v = class C { static a = 1; static b };
2+
var v = class C {
33
>v : typeof C
4-
>class C { static a = 1; static b } : typeof C
4+
>class C { static a = 1; static b static c = { x: "hi" } static d = C.c.x + " world"; } : typeof C
55
>C : typeof C
6+
7+
static a = 1;
68
>a : number
79
>1 : number
10+
11+
static b
812
>b : any
913

14+
static c = {
15+
>c : { x: string; }
16+
>{ x: "hi" } : { x: string; }
17+
18+
x: "hi"
19+
>x : string
20+
>"hi" : string
21+
}
22+
static d = C.c.x + " world";
23+
>d : string
24+
>C.c.x + " world" : string
25+
>C.c.x : string
26+
>C.c : { x: string; }
27+
>C : typeof C
28+
>c : { x: string; }
29+
>x : string
30+
>" world" : string
31+
32+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [classExpressionWithStaticPropertiesES63.ts]
2+
3+
declare var console: any;
4+
const arr: {y(): number}[] = [];
5+
for (let i = 0; i < 3; i++) {
6+
arr.push(class C {
7+
static x = i;
8+
static y = () => C.x * 2;
9+
});
10+
}
11+
arr.forEach(C => console.log(C.y()));
12+
13+
//// [classExpressionWithStaticPropertiesES63.js]
14+
const arr = [];
15+
for (let i = 0; i < 3; i++) {
16+
arr.push((C_1 = class C {
17+
},
18+
C_1.x = i,
19+
C_1.y = () => C_1.x * 2,
20+
C_1));
21+
}
22+
arr.forEach(C => console.log(C.y()));
23+
var C_1;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
=== tests/cases/compiler/classExpressionWithStaticPropertiesES63.ts ===
2+
3+
declare var console: any;
4+
>console : Symbol(console, Decl(classExpressionWithStaticPropertiesES63.ts, 1, 11))
5+
6+
const arr: {y(): number}[] = [];
7+
>arr : Symbol(arr, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 5))
8+
>y : Symbol(y, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 12))
9+
10+
for (let i = 0; i < 3; i++) {
11+
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
12+
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
13+
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
14+
15+
arr.push(class C {
16+
>arr.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
17+
>arr : Symbol(arr, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 5))
18+
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
19+
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 13))
20+
21+
static x = i;
22+
>x : Symbol(C.x, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 22))
23+
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
24+
25+
static y = () => C.x * 2;
26+
>y : Symbol(C.y, Decl(classExpressionWithStaticPropertiesES63.ts, 5, 21))
27+
>C.x : Symbol(C.x, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 22))
28+
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 13))
29+
>x : Symbol(C.x, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 22))
30+
31+
});
32+
}
33+
arr.forEach(C => console.log(C.y()));
34+
>arr.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --))
35+
>arr : Symbol(arr, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 5))
36+
>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --))
37+
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 9, 12))
38+
>console : Symbol(console, Decl(classExpressionWithStaticPropertiesES63.ts, 1, 11))
39+
>C.y : Symbol(y, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 12))
40+
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 9, 12))
41+
>y : Symbol(y, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 12))
42+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== tests/cases/compiler/classExpressionWithStaticPropertiesES63.ts ===
2+
3+
declare var console: any;
4+
>console : any
5+
6+
const arr: {y(): number}[] = [];
7+
>arr : { y(): number; }[]
8+
>y : () => number
9+
>[] : undefined[]
10+
11+
for (let i = 0; i < 3; i++) {
12+
>i : number
13+
>0 : number
14+
>i < 3 : boolean
15+
>i : number
16+
>3 : number
17+
>i++ : number
18+
>i : number
19+
20+
arr.push(class C {
21+
>arr.push(class C { static x = i; static y = () => C.x * 2; }) : number
22+
>arr.push : (...items: { y(): number; }[]) => number
23+
>arr : { y(): number; }[]
24+
>push : (...items: { y(): number; }[]) => number
25+
>class C { static x = i; static y = () => C.x * 2; } : typeof C
26+
>C : typeof C
27+
28+
static x = i;
29+
>x : number
30+
>i : number
31+
32+
static y = () => C.x * 2;
33+
>y : () => number
34+
>() => C.x * 2 : () => number
35+
>C.x * 2 : number
36+
>C.x : number
37+
>C : typeof C
38+
>x : number
39+
>2 : number
40+
41+
});
42+
}
43+
arr.forEach(C => console.log(C.y()));
44+
>arr.forEach(C => console.log(C.y())) : void
45+
>arr.forEach : (callbackfn: (value: { y(): number; }, index: number, array: { y(): number; }[]) => void, thisArg?: any) => void
46+
>arr : { y(): number; }[]
47+
>forEach : (callbackfn: (value: { y(): number; }, index: number, array: { y(): number; }[]) => void, thisArg?: any) => void
48+
>C => console.log(C.y()) : (C: { y(): number; }) => any
49+
>C : { y(): number; }
50+
>console.log(C.y()) : any
51+
>console.log : any
52+
>console : any
53+
>log : any
54+
>C.y() : number
55+
>C.y : () => number
56+
>C : { y(): number; }
57+
>y : () => number
58+
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
//@target: es6
2-
var v = class C { static a = 1; static b = 2 };
2+
var v = class C {
3+
static a = 1;
4+
static b = 2;
5+
static c = C.a + 3;
6+
};
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
//@target: es6
2-
var v = class C { static a = 1; static b };
2+
var v = class C {
3+
static a = 1;
4+
static b
5+
static c = {
6+
x: "hi"
7+
}
8+
static d = C.c.x + " world";
9+
};

0 commit comments

Comments
 (0)