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
This commit is contained in:
Yui 2016-06-24 17:40:07 -07:00 committed by GitHub
parent e182ecf2c9
commit be2ca35b00
13 changed files with 283 additions and 30 deletions

View File

@ -1673,6 +1673,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
return false;
}
function getClassExpressionInPropertyAccessInStaticPropertyDeclaration(node: Identifier) {
if (languageVersion >= ScriptTarget.ES6) {
let parent = node.parent;
if (parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>parent).expression === node) {
parent = parent.parent;
while (parent && parent.kind !== SyntaxKind.PropertyDeclaration) {
parent = parent.parent;
}
return parent && parent.kind === SyntaxKind.PropertyDeclaration && (parent.flags & NodeFlags.Static) !== 0 &&
parent.parent.kind === SyntaxKind.ClassExpression ? parent.parent : undefined;
}
}
return undefined;
}
function emitIdentifier(node: Identifier) {
if (convertedLoopState) {
if (node.text == "arguments" && resolver.isArgumentsLocalBinding(node)) {
@ -1687,6 +1702,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
write(node.text);
}
else if (isExpressionIdentifier(node)) {
const classExpression = getClassExpressionInPropertyAccessInStaticPropertyDeclaration(node);
if (classExpression) {
const declaration = resolver.getReferencedValueDeclaration(node);
if (declaration === classExpression) {
write(getGeneratedNameForNode(declaration.name));
return;
}
}
emitExpressionIdentifier(node);
}
else if (isNameOfNestedBlockScopedRedeclarationOrCapturedBinding(node)) {
@ -5086,13 +5109,13 @@ const _super = (function (geti, seti) {
}
}
function emitPropertyDeclaration(node: ClassLikeDeclaration, property: PropertyDeclaration, receiver?: Identifier, isExpression?: boolean) {
function emitPropertyDeclaration(node: ClassLikeDeclaration, property: PropertyDeclaration, receiver?: string, isExpression?: boolean) {
writeLine();
emitLeadingComments(property);
emitStart(property);
emitStart(property.name);
if (receiver) {
emit(receiver);
write(receiver);
}
else {
if (property.flags & NodeFlags.Static) {
@ -5511,13 +5534,16 @@ const _super = (function (geti, seti) {
// of it have been initialized by the time it is used.
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
const isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
let tempVariable: Identifier;
let generatedName: string;
if (isClassExpressionWithStaticProperties) {
tempVariable = createAndRecordTempVariable(TempFlags.Auto);
generatedName = getGeneratedNameForNode(node.name);
const synthesizedNode = <Identifier>createSynthesizedNode(SyntaxKind.Identifier);
synthesizedNode.text = generatedName;
recordTempDeclaration(synthesizedNode);
write("(");
increaseIndent();
emit(tempVariable);
emit(synthesizedNode);
write(" = ");
}
@ -5571,11 +5597,11 @@ const _super = (function (geti, seti) {
for (const property of staticProperties) {
write(",");
writeLine();
emitPropertyDeclaration(node, property, /*receiver*/ tempVariable, /*isExpression*/ true);
emitPropertyDeclaration(node, property, /*receiver*/ generatedName, /*isExpression*/ true);
}
write(",");
writeLine();
emit(tempVariable);
write(generatedName);
decreaseIndent();
write(")");
}

View File

@ -1,10 +1,15 @@
//// [classExpressionWithStaticPropertiesES61.ts]
var v = class C { static a = 1; static b = 2 };
var v = class C {
static a = 1;
static b = 2;
static c = C.a + 3;
};
//// [classExpressionWithStaticPropertiesES61.js]
var v = (_a = class C {
var v = (C_1 = class C {
},
_a.a = 1,
_a.b = 2,
_a);
var _a;
C_1.a = 1,
C_1.b = 2,
C_1.c = C_1.a + 3,
C_1);
var C_1;

View File

@ -1,7 +1,18 @@
=== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts ===
var v = class C { static a = 1; static b = 2 };
var v = class C {
>v : Symbol(v, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 3))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 7))
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 31))
static a = 1;
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
static b = 2;
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES61.ts, 1, 17))
static c = C.a + 3;
>c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES61.ts, 2, 17))
>C.a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 7))
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES61.ts, 0, 17))
};

View File

@ -1,10 +1,23 @@
=== tests/cases/compiler/classExpressionWithStaticPropertiesES61.ts ===
var v = class C { static a = 1; static b = 2 };
var v = class C {
>v : typeof C
>class C { static a = 1; static b = 2 } : typeof C
>class C { static a = 1; static b = 2; static c = C.a + 3;} : typeof C
>C : typeof C
static a = 1;
>a : number
>1 : number
static b = 2;
>b : number
>2 : number
static c = C.a + 3;
>c : number
>C.a + 3 : number
>C.a : number
>C : typeof C
>a : number
>3 : number
};

View File

@ -1,9 +1,20 @@
//// [classExpressionWithStaticPropertiesES62.ts]
var v = class C { static a = 1; static b };
var v = class C {
static a = 1;
static b
static c = {
x: "hi"
}
static d = C.c.x + " world";
};
//// [classExpressionWithStaticPropertiesES62.js]
var v = (_a = class C {
var v = (C_1 = class C {
},
_a.a = 1,
_a);
var _a;
C_1.a = 1,
C_1.c = {
x: "hi"
},
C_1.d = C_1.c.x + " world",
C_1);
var C_1;

View File

@ -1,7 +1,26 @@
=== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts ===
var v = class C { static a = 1; static b };
var v = class C {
>v : Symbol(v, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 3))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 7))
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 17))
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 31))
static a = 1;
>a : Symbol(C.a, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 17))
static b
>b : Symbol(C.b, Decl(classExpressionWithStaticPropertiesES62.ts, 1, 17))
static c = {
>c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES62.ts, 2, 12))
x: "hi"
>x : Symbol(x, Decl(classExpressionWithStaticPropertiesES62.ts, 3, 16))
}
static d = C.c.x + " world";
>d : Symbol(C.d, Decl(classExpressionWithStaticPropertiesES62.ts, 5, 5))
>C.c.x : Symbol(x, Decl(classExpressionWithStaticPropertiesES62.ts, 3, 16))
>C.c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES62.ts, 2, 12))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES62.ts, 0, 7))
>c : Symbol(C.c, Decl(classExpressionWithStaticPropertiesES62.ts, 2, 12))
>x : Symbol(x, Decl(classExpressionWithStaticPropertiesES62.ts, 3, 16))
};

View File

@ -1,9 +1,32 @@
=== tests/cases/compiler/classExpressionWithStaticPropertiesES62.ts ===
var v = class C { static a = 1; static b };
var v = class C {
>v : typeof C
>class C { static a = 1; static b } : typeof C
>class C { static a = 1; static b static c = { x: "hi" } static d = C.c.x + " world"; } : typeof C
>C : typeof C
static a = 1;
>a : number
>1 : number
static b
>b : any
static c = {
>c : { x: string; }
>{ x: "hi" } : { x: string; }
x: "hi"
>x : string
>"hi" : string
}
static d = C.c.x + " world";
>d : string
>C.c.x + " world" : string
>C.c.x : string
>C.c : { x: string; }
>C : typeof C
>c : { x: string; }
>x : string
>" world" : string
};

View File

@ -0,0 +1,23 @@
//// [classExpressionWithStaticPropertiesES63.ts]
declare var console: any;
const arr: {y(): number}[] = [];
for (let i = 0; i < 3; i++) {
arr.push(class C {
static x = i;
static y = () => C.x * 2;
});
}
arr.forEach(C => console.log(C.y()));
//// [classExpressionWithStaticPropertiesES63.js]
const arr = [];
for (let i = 0; i < 3; i++) {
arr.push((C_1 = class C {
},
C_1.x = i,
C_1.y = () => C_1.x * 2,
C_1));
}
arr.forEach(C => console.log(C.y()));
var C_1;

View File

@ -0,0 +1,42 @@
=== tests/cases/compiler/classExpressionWithStaticPropertiesES63.ts ===
declare var console: any;
>console : Symbol(console, Decl(classExpressionWithStaticPropertiesES63.ts, 1, 11))
const arr: {y(): number}[] = [];
>arr : Symbol(arr, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 5))
>y : Symbol(y, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 12))
for (let i = 0; i < 3; i++) {
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
arr.push(class C {
>arr.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 5))
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 13))
static x = i;
>x : Symbol(C.x, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 22))
>i : Symbol(i, Decl(classExpressionWithStaticPropertiesES63.ts, 3, 8))
static y = () => C.x * 2;
>y : Symbol(C.y, Decl(classExpressionWithStaticPropertiesES63.ts, 5, 21))
>C.x : Symbol(C.x, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 22))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 13))
>x : Symbol(C.x, Decl(classExpressionWithStaticPropertiesES63.ts, 4, 22))
});
}
arr.forEach(C => console.log(C.y()));
>arr.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --))
>arr : Symbol(arr, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 5))
>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 9, 12))
>console : Symbol(console, Decl(classExpressionWithStaticPropertiesES63.ts, 1, 11))
>C.y : Symbol(y, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 12))
>C : Symbol(C, Decl(classExpressionWithStaticPropertiesES63.ts, 9, 12))
>y : Symbol(y, Decl(classExpressionWithStaticPropertiesES63.ts, 2, 12))

View File

@ -0,0 +1,58 @@
=== tests/cases/compiler/classExpressionWithStaticPropertiesES63.ts ===
declare var console: any;
>console : any
const arr: {y(): number}[] = [];
>arr : { y(): number; }[]
>y : () => number
>[] : undefined[]
for (let i = 0; i < 3; i++) {
>i : number
>0 : number
>i < 3 : boolean
>i : number
>3 : number
>i++ : number
>i : number
arr.push(class C {
>arr.push(class C { static x = i; static y = () => C.x * 2; }) : number
>arr.push : (...items: { y(): number; }[]) => number
>arr : { y(): number; }[]
>push : (...items: { y(): number; }[]) => number
>class C { static x = i; static y = () => C.x * 2; } : typeof C
>C : typeof C
static x = i;
>x : number
>i : number
static y = () => C.x * 2;
>y : () => number
>() => C.x * 2 : () => number
>C.x * 2 : number
>C.x : number
>C : typeof C
>x : number
>2 : number
});
}
arr.forEach(C => console.log(C.y()));
>arr.forEach(C => console.log(C.y())) : void
>arr.forEach : (callbackfn: (value: { y(): number; }, index: number, array: { y(): number; }[]) => void, thisArg?: any) => void
>arr : { y(): number; }[]
>forEach : (callbackfn: (value: { y(): number; }, index: number, array: { y(): number; }[]) => void, thisArg?: any) => void
>C => console.log(C.y()) : (C: { y(): number; }) => any
>C : { y(): number; }
>console.log(C.y()) : any
>console.log : any
>console : any
>log : any
>C.y() : number
>C.y : () => number
>C : { y(): number; }
>y : () => number

View File

@ -1,2 +1,6 @@
//@target: es6
var v = class C { static a = 1; static b = 2 };
var v = class C {
static a = 1;
static b = 2;
static c = C.a + 3;
};

View File

@ -1,2 +1,9 @@
//@target: es6
var v = class C { static a = 1; static b };
var v = class C {
static a = 1;
static b
static c = {
x: "hi"
}
static d = C.c.x + " world";
};

View File

@ -0,0 +1,11 @@
//@target: es6
declare var console: any;
const arr: {y(): number}[] = [];
for (let i = 0; i < 3; i++) {
arr.push(class C {
static x = i;
static y = () => C.x * 2;
});
}
arr.forEach(C => console.log(C.y()));