From 8ae5a8cfcedaa840f8764ad1d3e58522115837a5 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 12 Nov 2019 10:15:30 -0800 Subject: [PATCH 1/3] useDefineForClassFields skips emit of ambient properties Previously: ```ts class C { declare p } ``` would incorrectly emit ```js class C { constructor() { Object.defineProperty(this, "p", { enumerable: true, configurable: true, writable: true, value: void 0 }); } } ``` when useDefineForClassFields was turned on (for targets m : Symbol(A.m, Decl(definePropertyES5.ts, 5, 13)) + + declare notEmitted: boolean; +>notEmitted : Symbol(A.notEmitted, Decl(definePropertyES5.ts, 6, 11)) } diff --git a/tests/baselines/reference/definePropertyES5.types b/tests/baselines/reference/definePropertyES5.types index 3f82787c13a34..7fffb77b74c45 100644 --- a/tests/baselines/reference/definePropertyES5.types +++ b/tests/baselines/reference/definePropertyES5.types @@ -25,5 +25,8 @@ class A { m() { } >m : () => void + + declare notEmitted: boolean; +>notEmitted : boolean } diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts index 73e1ee515d1d8..a2338889134ca 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts @@ -7,4 +7,5 @@ class A { ["computed"] = 13 ;[x] = 14 m() { } + declare notEmitted: boolean; } From 0ec9c048968d9eca0921939a165d229474ad5f45 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 12 Nov 2019 13:48:46 -0800 Subject: [PATCH 2/3] Fix bug for ESNext as well This moves the check earlier in the pipeline. --- src/compiler/transformers/ts.ts | 3 + src/compiler/transformers/utilities.ts | 2 +- .../reference/definePropertyESNext.js | 46 ++++++++++++++ .../reference/definePropertyESNext.symbols | 56 +++++++++++++++++ .../reference/definePropertyESNext.types | 61 +++++++++++++++++++ .../definePropertyESNext.ts | 21 +++++++ 6 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/definePropertyESNext.js create mode 100644 tests/baselines/reference/definePropertyESNext.symbols create mode 100644 tests/baselines/reference/definePropertyESNext.types create mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index d413a835d0d86..cc8481538da93 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1873,6 +1873,9 @@ namespace ts { } function visitPropertyDeclaration(node: PropertyDeclaration) { + if (node.flags & NodeFlags.Ambient) { + return undefined; + } const updated = updateProperty( node, /*decorators*/ undefined, diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 3cd246c90943b..e2029ff7b602e 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -314,7 +314,7 @@ namespace ts { */ function isInitializedOrStaticProperty(member: ClassElement, requireInitializer: boolean, isStatic: boolean) { return isPropertyDeclaration(member) - && (!!member.initializer || !requireInitializer && !(getOriginalNode(member).flags & NodeFlags.Ambient)) + && (!!member.initializer || !requireInitializer) && hasStaticModifier(member) === isStatic; } diff --git a/tests/baselines/reference/definePropertyESNext.js b/tests/baselines/reference/definePropertyESNext.js new file mode 100644 index 0000000000000..5fbd2fad7a93f --- /dev/null +++ b/tests/baselines/reference/definePropertyESNext.js @@ -0,0 +1,46 @@ +//// [definePropertyESNext.ts] +var x: "p" = "p" +class A { + a = 12 + b + ["computed"] = 13 + ;[x] = 14 + m() { } + constructor(public readonly y: number) { } + declare notEmitted; +} +class B { +} +class C extends B { + z = this.ka + constructor(public ka: number) { + super() + } + ki = this.ka +} + + +//// [definePropertyESNext.js] +var x = "p"; +class A { + y; + a = 12; + b; + ["computed"] = 13; + [x] = 14; + m() { } + constructor(y) { + this.y = y; + } +} +class B { +} +class C extends B { + ka; + z = this.ka; + constructor(ka) { + super(); + this.ka = ka; + } + ki = this.ka; +} diff --git a/tests/baselines/reference/definePropertyESNext.symbols b/tests/baselines/reference/definePropertyESNext.symbols new file mode 100644 index 0000000000000..56463362d4ed3 --- /dev/null +++ b/tests/baselines/reference/definePropertyESNext.symbols @@ -0,0 +1,56 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts === +var x: "p" = "p" +>x : Symbol(x, Decl(definePropertyESNext.ts, 0, 3)) + +class A { +>A : Symbol(A, Decl(definePropertyESNext.ts, 0, 16)) + + a = 12 +>a : Symbol(A.a, Decl(definePropertyESNext.ts, 1, 9)) + + b +>b : Symbol(A.b, Decl(definePropertyESNext.ts, 2, 10)) + + ["computed"] = 13 +>["computed"] : Symbol(A["computed"], Decl(definePropertyESNext.ts, 3, 5)) +>"computed" : Symbol(A["computed"], Decl(definePropertyESNext.ts, 3, 5)) + + ;[x] = 14 +>[x] : Symbol(A[x], Decl(definePropertyESNext.ts, 5, 5)) +>x : Symbol(x, Decl(definePropertyESNext.ts, 0, 3)) + + m() { } +>m : Symbol(A.m, Decl(definePropertyESNext.ts, 5, 13)) + + constructor(public readonly y: number) { } +>y : Symbol(A.y, Decl(definePropertyESNext.ts, 7, 16)) + + declare notEmitted; +>notEmitted : Symbol(A.notEmitted, Decl(definePropertyESNext.ts, 7, 46)) +} +class B { +>B : Symbol(B, Decl(definePropertyESNext.ts, 9, 1)) +} +class C extends B { +>C : Symbol(C, Decl(definePropertyESNext.ts, 11, 1)) +>B : Symbol(B, Decl(definePropertyESNext.ts, 9, 1)) + + z = this.ka +>z : Symbol(C.z, Decl(definePropertyESNext.ts, 12, 19)) +>this.ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 14, 16)) +>this : Symbol(C, Decl(definePropertyESNext.ts, 11, 1)) +>ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 14, 16)) + + constructor(public ka: number) { +>ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 14, 16)) + + super() +>super : Symbol(B, Decl(definePropertyESNext.ts, 9, 1)) + } + ki = this.ka +>ki : Symbol(C.ki, Decl(definePropertyESNext.ts, 16, 5)) +>this.ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 14, 16)) +>this : Symbol(C, Decl(definePropertyESNext.ts, 11, 1)) +>ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 14, 16)) +} + diff --git a/tests/baselines/reference/definePropertyESNext.types b/tests/baselines/reference/definePropertyESNext.types new file mode 100644 index 0000000000000..303387461a5af --- /dev/null +++ b/tests/baselines/reference/definePropertyESNext.types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts === +var x: "p" = "p" +>x : "p" +>"p" : "p" + +class A { +>A : A + + a = 12 +>a : number +>12 : 12 + + b +>b : any + + ["computed"] = 13 +>["computed"] : number +>"computed" : "computed" +>13 : 13 + + ;[x] = 14 +>[x] : number +>x : "p" +>14 : 14 + + m() { } +>m : () => void + + constructor(public readonly y: number) { } +>y : number + + declare notEmitted; +>notEmitted : any +} +class B { +>B : B +} +class C extends B { +>C : C +>B : B + + z = this.ka +>z : number +>this.ka : number +>this : this +>ka : number + + constructor(public ka: number) { +>ka : number + + super() +>super() : void +>super : typeof B + } + ki = this.ka +>ki : number +>this.ka : number +>this : this +>ka : number +} + diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts new file mode 100644 index 0000000000000..4bfd516229f05 --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts @@ -0,0 +1,21 @@ +// @target: esnext +// @useDefineForClassFields: true +var x: "p" = "p" +class A { + a = 12 + b + ["computed"] = 13 + ;[x] = 14 + m() { } + constructor(public readonly y: number) { } + declare notEmitted; +} +class B { +} +class C extends B { + z = this.ka + constructor(public ka: number) { + super() + } + ki = this.ka +} From e1aa034a7a94b7f2e7e0888d03941f5212bb4714 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 12 Nov 2019 15:08:42 -0800 Subject: [PATCH 3/3] update baselines --- .../reference/derivedUninitializedPropertyDeclaration.js | 4 +--- tests/baselines/reference/illegalModifiersOnClassElements.js | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/baselines/reference/derivedUninitializedPropertyDeclaration.js b/tests/baselines/reference/derivedUninitializedPropertyDeclaration.js index 471cd5bbf1d18..48715eefe0c4b 100644 --- a/tests/baselines/reference/derivedUninitializedPropertyDeclaration.js +++ b/tests/baselines/reference/derivedUninitializedPropertyDeclaration.js @@ -113,9 +113,7 @@ var BDBang = /** @class */ (function (_super) { var BOther = /** @class */ (function (_super) { __extends(BOther, _super); function BOther() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.property = 'y'; // initialiser not allowed with declare - return _this; + return _super !== null && _super.apply(this, arguments) || this; } BOther.prototype.m = function () { return 2; }; // not allowed on methods return BOther; diff --git a/tests/baselines/reference/illegalModifiersOnClassElements.js b/tests/baselines/reference/illegalModifiersOnClassElements.js index b87c822738b88..1650d65aa7080 100644 --- a/tests/baselines/reference/illegalModifiersOnClassElements.js +++ b/tests/baselines/reference/illegalModifiersOnClassElements.js @@ -7,7 +7,6 @@ class C { //// [illegalModifiersOnClassElements.js] var C = /** @class */ (function () { function C() { - this.foo = 1; this.bar = 1; } return C;