From 58107652593b175168f7db7a52360c3f0d33eb5f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 7 Nov 2019 15:18:35 -0800 Subject: [PATCH 1/3] Emit defineProperty calls before param prop assignments Note that I restricted this to --useDefineForClassFields is true. Nothing changes when it's off. I think this is the correct fix for a patch release. However, in principal there's nothing wrong with moving parameter property initialisation after property declaration initialisation. It would be Extremely Bad and Wrong to rely on this working: ```ts class C { p = this.q // what is q? constructor(public q: number) { } } ``` But today it does, and probably somebody relies on it without knowing. --- src/compiler/transformers/classFields.ts | 18 ++++--- .../baselines/reference/definePropertyES5.js | 10 +++- .../reference/definePropertyES5.symbols | 3 ++ .../reference/definePropertyES5.types | 3 ++ .../reference/definePropertyESNext.js | 43 ++++++++++++++++ .../reference/definePropertyESNext.symbols | 45 ++++++++++++++++ .../reference/definePropertyESNext.types | 51 +++++++++++++++++++ .../definePropertyES5.ts | 1 + .../definePropertyESNext.ts | 19 +++++++ 9 files changed, 186 insertions(+), 7 deletions(-) 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/classFields.ts b/src/compiler/transformers/classFields.ts index b3e598608884a..265300adbd927 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -10,9 +10,9 @@ namespace ts { /** * Transforms ECMAScript Class Syntax. * TypeScript parameter property syntax is transformed in the TypeScript transformer. - * For now, this transforms public field declarations using TypeScript class semantics - * (where the declarations get elided and initializers are transformed as assignments in the constructor). - * Eventually, this transform will change to the ECMAScript semantics (with Object.defineProperty). + * For now, this transforms public field declarations using TypeScript class semantics, + * where declarations are elided and initializers are transformed as assignments in the constructor. + * When --useDefineForClassFields is on, this transforms to ECMAScript semantics, with Object.defineProperty. */ export function transformClassFields(context: TransformationContext) { const { @@ -294,7 +294,8 @@ namespace ts { } function transformConstructorBody(node: ClassDeclaration | ClassExpression, constructor: ConstructorDeclaration | undefined, isDerivedClass: boolean) { - const properties = getProperties(node, /*requireInitializer*/ !context.getCompilerOptions().useDefineForClassFields, /*isStatic*/ false); + const useDefineForClassFields = context.getCompilerOptions().useDefineForClassFields; + const properties = getProperties(node, /*requireInitializer*/ !useDefineForClassFields, /*isStatic*/ false); // Only generate synthetic constructor when there are property initializers to move. if (!constructor && !some(properties)) { @@ -325,6 +326,9 @@ namespace ts { if (constructor) { indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor); } + if (useDefineForClassFields) { + addPropertyStatements(statements, properties, createThis()); + } // Add the property initializers. Transforms this: // @@ -336,7 +340,7 @@ namespace ts { // this.x = 1; // } // - if (constructor && constructor.body) { + if (constructor?.body) { let parameterPropertyDeclarationCount = 0; for (let i = indexOfFirstStatement; i < constructor.body.statements.length; i++) { if (isParameterPropertyDeclaration(getOriginalNode(constructor.body.statements[i]), constructor)) { @@ -351,7 +355,9 @@ namespace ts { indexOfFirstStatement += parameterPropertyDeclarationCount; } } - addPropertyStatements(statements, properties, createThis()); + if (!useDefineForClassFields) { + addPropertyStatements(statements, properties, createThis()); + } // Add existing statements, skipping the initial super call. if (constructor) { diff --git a/tests/baselines/reference/definePropertyES5.js b/tests/baselines/reference/definePropertyES5.js index a0bc4a64db48a..1d1ec488cdca0 100644 --- a/tests/baselines/reference/definePropertyES5.js +++ b/tests/baselines/reference/definePropertyES5.js @@ -6,6 +6,7 @@ class A { ["computed"] = 13 ;[x] = 14 m() { } + constructor(public readonly y: number) { } } @@ -13,7 +14,13 @@ class A { var _a; var x = "p"; var A = /** @class */ (function () { - function A() { + function A(y) { + Object.defineProperty(this, "y", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); Object.defineProperty(this, "a", { enumerable: true, configurable: true, @@ -38,6 +45,7 @@ var A = /** @class */ (function () { writable: true, value: 14 }); + this.y = y; } Object.defineProperty(A.prototype, "m", { enumerable: false, diff --git a/tests/baselines/reference/definePropertyES5.symbols b/tests/baselines/reference/definePropertyES5.symbols index f9afa02868793..4fad055607585 100644 --- a/tests/baselines/reference/definePropertyES5.symbols +++ b/tests/baselines/reference/definePropertyES5.symbols @@ -21,5 +21,8 @@ class A { m() { } >m : Symbol(A.m, Decl(definePropertyES5.ts, 5, 13)) + + constructor(public readonly y: number) { } +>y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) } diff --git a/tests/baselines/reference/definePropertyES5.types b/tests/baselines/reference/definePropertyES5.types index 3f82787c13a34..6beb7516bcdb2 100644 --- a/tests/baselines/reference/definePropertyES5.types +++ b/tests/baselines/reference/definePropertyES5.types @@ -25,5 +25,8 @@ class A { m() { } >m : () => void + + constructor(public readonly y: number) { } +>y : number } diff --git a/tests/baselines/reference/definePropertyESNext.js b/tests/baselines/reference/definePropertyESNext.js new file mode 100644 index 0000000000000..56c7ce36f68a0 --- /dev/null +++ b/tests/baselines/reference/definePropertyESNext.js @@ -0,0 +1,43 @@ +//// [definePropertyESNext.ts] +var x: "p" = "p" +class A { + a = 12 + b + ["computed"] = 13 + ;[x] = 14 + m() { } + constructor(public readonly y: number) { } +} +class B { +} +class C extends B { + z = 1 + constructor(public ka: number) { + super() + } +} + + +//// [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 = 1; + constructor(ka) { + super(); + this.ka = ka; + } +} diff --git a/tests/baselines/reference/definePropertyESNext.symbols b/tests/baselines/reference/definePropertyESNext.symbols new file mode 100644 index 0000000000000..adc8913c0850e --- /dev/null +++ b/tests/baselines/reference/definePropertyESNext.symbols @@ -0,0 +1,45 @@ +=== 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)) +} +class B { +>B : Symbol(B, Decl(definePropertyESNext.ts, 8, 1)) +} +class C extends B { +>C : Symbol(C, Decl(definePropertyESNext.ts, 10, 1)) +>B : Symbol(B, Decl(definePropertyESNext.ts, 8, 1)) + + z = 1 +>z : Symbol(C.z, Decl(definePropertyESNext.ts, 11, 19)) + + constructor(public ka: number) { +>ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 13, 16)) + + super() +>super : Symbol(B, Decl(definePropertyESNext.ts, 8, 1)) + } +} + diff --git a/tests/baselines/reference/definePropertyESNext.types b/tests/baselines/reference/definePropertyESNext.types new file mode 100644 index 0000000000000..1473a5fc1e60c --- /dev/null +++ b/tests/baselines/reference/definePropertyESNext.types @@ -0,0 +1,51 @@ +=== 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 +} +class B { +>B : B +} +class C extends B { +>C : C +>B : B + + z = 1 +>z : number +>1 : 1 + + constructor(public ka: number) { +>ka : number + + super() +>super() : void +>super : typeof B + } +} + diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts index 73e1ee515d1d8..f470e8c28d4fa 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() { } + constructor(public readonly y: 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..f95ad06c77263 --- /dev/null +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts @@ -0,0 +1,19 @@ +// @target: esnext +// @useDefineForClassFields: true +var x: "p" = "p" +class A { + a = 12 + b + ["computed"] = 13 + ;[x] = 14 + m() { } + constructor(public readonly y: number) { } +} +class B { +} +class C extends B { + z = 1 + constructor(public ka: number) { + super() + } +} From ec7959091ad923643e9cef0924e83bc5b67a3a2c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 11 Nov 2019 14:38:28 -0800 Subject: [PATCH 2/3] Put parameter property initialiser into defineProperty's value --- src/compiler/transformers/classFields.ts | 31 +++++++------------ src/compiler/transformers/ts.ts | 4 +-- .../baselines/reference/definePropertyES5.js | 14 ++++++--- .../reference/definePropertyES5.symbols | 13 ++++++-- .../reference/definePropertyES5.types | 12 +++++-- .../reference/definePropertyESNext.js | 6 ++-- .../reference/definePropertyESNext.symbols | 10 +++++- .../reference/definePropertyESNext.types | 11 +++++-- .../definePropertyES5.ts | 3 +- .../definePropertyESNext.ts | 3 +- 10 files changed, 71 insertions(+), 36 deletions(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 265300adbd927..da4a5b08a0a4b 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -326,10 +326,6 @@ namespace ts { if (constructor) { indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements, visitor); } - if (useDefineForClassFields) { - addPropertyStatements(statements, properties, createThis()); - } - // Add the property initializers. Transforms this: // // public x = 1; @@ -341,23 +337,18 @@ namespace ts { // } // if (constructor?.body) { - let parameterPropertyDeclarationCount = 0; - for (let i = indexOfFirstStatement; i < constructor.body.statements.length; i++) { - if (isParameterPropertyDeclaration(getOriginalNode(constructor.body.statements[i]), constructor)) { - parameterPropertyDeclarationCount++; - } - else { - break; - } + let afterParameterProperties = findIndex(constructor.body.statements, s => !isParameterPropertyDeclaration(getOriginalNode(s), constructor), indexOfFirstStatement); + if (afterParameterProperties === -1) { + afterParameterProperties = constructor.body.statements.length; } - if (parameterPropertyDeclarationCount > 0) { - addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement, parameterPropertyDeclarationCount)); - indexOfFirstStatement += parameterPropertyDeclarationCount; + if (afterParameterProperties > indexOfFirstStatement) { + if (!useDefineForClassFields) { + addRange(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement, afterParameterProperties - indexOfFirstStatement)); + } + indexOfFirstStatement = afterParameterProperties; } } - if (!useDefineForClassFields) { - addPropertyStatements(statements, properties, createThis()); - } + addPropertyStatements(statements, properties, createThis()); // Add existing statements, skipping the initial super call. if (constructor) { @@ -427,7 +418,9 @@ namespace ts { ? updateComputedPropertyName(property.name, getGeneratedNameForNode(property.name)) : property.name; - const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) : createVoidZero(); + const initializer = property.initializer || emitAssignment ? visitNode(property.initializer, visitor, isExpression) + : hasModifier(getOriginalNode(property), ModifierFlags.ParameterPropertyModifier) && isIdentifier(propertyName) ? propertyName + : createVoidZero(); if (emitAssignment) { const memberAccess = createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); return createAssignment(memberAccess, initializer); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index d413a835d0d86..9b0823a46f22f 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -900,13 +900,13 @@ namespace ts { if (parametersWithPropertyAssignments) { for (const parameter of parametersWithPropertyAssignments) { if (isIdentifier(parameter.name)) { - members.push(aggregateTransformFlags(createProperty( + members.push(setOriginalNode(aggregateTransformFlags(createProperty( /*decorators*/ undefined, /*modifiers*/ undefined, parameter.name, /*questionOrExclamationToken*/ undefined, /*type*/ undefined, - /*initializer*/ undefined))); + /*initializer*/ undefined)), parameter)); } } } diff --git a/tests/baselines/reference/definePropertyES5.js b/tests/baselines/reference/definePropertyES5.js index 1d1ec488cdca0..5f51ef5bc4e97 100644 --- a/tests/baselines/reference/definePropertyES5.js +++ b/tests/baselines/reference/definePropertyES5.js @@ -1,12 +1,13 @@ //// [definePropertyES5.ts] var x: "p" = "p" class A { - a = 12 + a = this.y b ["computed"] = 13 ;[x] = 14 m() { } constructor(public readonly y: number) { } + z = this.y } @@ -19,13 +20,13 @@ var A = /** @class */ (function () { enumerable: true, configurable: true, writable: true, - value: void 0 + value: y }); Object.defineProperty(this, "a", { enumerable: true, configurable: true, writable: true, - value: 12 + value: this.y }); Object.defineProperty(this, "b", { enumerable: true, @@ -45,7 +46,12 @@ var A = /** @class */ (function () { writable: true, value: 14 }); - this.y = y; + Object.defineProperty(this, "z", { + enumerable: true, + configurable: true, + writable: true, + value: this.y + }); } Object.defineProperty(A.prototype, "m", { enumerable: false, diff --git a/tests/baselines/reference/definePropertyES5.symbols b/tests/baselines/reference/definePropertyES5.symbols index 4fad055607585..82eaadd9b3629 100644 --- a/tests/baselines/reference/definePropertyES5.symbols +++ b/tests/baselines/reference/definePropertyES5.symbols @@ -5,11 +5,14 @@ var x: "p" = "p" class A { >A : Symbol(A, Decl(definePropertyES5.ts, 0, 16)) - a = 12 + a = this.y >a : Symbol(A.a, Decl(definePropertyES5.ts, 1, 9)) +>this.y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) +>this : Symbol(A, Decl(definePropertyES5.ts, 0, 16)) +>y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) b ->b : Symbol(A.b, Decl(definePropertyES5.ts, 2, 10)) +>b : Symbol(A.b, Decl(definePropertyES5.ts, 2, 14)) ["computed"] = 13 >["computed"] : Symbol(A["computed"], Decl(definePropertyES5.ts, 3, 5)) @@ -23,6 +26,12 @@ class A { >m : Symbol(A.m, Decl(definePropertyES5.ts, 5, 13)) constructor(public readonly y: number) { } +>y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) + + z = this.y +>z : Symbol(A.z, Decl(definePropertyES5.ts, 7, 46)) +>this.y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) +>this : Symbol(A, Decl(definePropertyES5.ts, 0, 16)) >y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) } diff --git a/tests/baselines/reference/definePropertyES5.types b/tests/baselines/reference/definePropertyES5.types index 6beb7516bcdb2..88c322d532dbf 100644 --- a/tests/baselines/reference/definePropertyES5.types +++ b/tests/baselines/reference/definePropertyES5.types @@ -6,9 +6,11 @@ var x: "p" = "p" class A { >A : A - a = 12 + a = this.y >a : number ->12 : 12 +>this.y : number +>this : this +>y : number b >b : any @@ -27,6 +29,12 @@ class A { >m : () => void constructor(public readonly y: number) { } +>y : number + + z = this.y +>z : number +>this.y : number +>this : this >y : number } diff --git a/tests/baselines/reference/definePropertyESNext.js b/tests/baselines/reference/definePropertyESNext.js index 56c7ce36f68a0..31c0d269310bd 100644 --- a/tests/baselines/reference/definePropertyESNext.js +++ b/tests/baselines/reference/definePropertyESNext.js @@ -11,10 +11,11 @@ class A { class B { } class C extends B { - z = 1 + z = this.ka constructor(public ka: number) { super() } + ki = this.ka } @@ -35,9 +36,10 @@ class B { } class C extends B { ka; - z = 1; + 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 index adc8913c0850e..93c82a879fdde 100644 --- a/tests/baselines/reference/definePropertyESNext.symbols +++ b/tests/baselines/reference/definePropertyESNext.symbols @@ -32,8 +32,11 @@ class C extends B { >C : Symbol(C, Decl(definePropertyESNext.ts, 10, 1)) >B : Symbol(B, Decl(definePropertyESNext.ts, 8, 1)) - z = 1 + z = this.ka >z : Symbol(C.z, Decl(definePropertyESNext.ts, 11, 19)) +>this.ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 13, 16)) +>this : Symbol(C, Decl(definePropertyESNext.ts, 10, 1)) +>ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 13, 16)) constructor(public ka: number) { >ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 13, 16)) @@ -41,5 +44,10 @@ class C extends B { super() >super : Symbol(B, Decl(definePropertyESNext.ts, 8, 1)) } + ki = this.ka +>ki : Symbol(C.ki, Decl(definePropertyESNext.ts, 15, 5)) +>this.ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 13, 16)) +>this : Symbol(C, Decl(definePropertyESNext.ts, 10, 1)) +>ka : Symbol(C.ka, Decl(definePropertyESNext.ts, 13, 16)) } diff --git a/tests/baselines/reference/definePropertyESNext.types b/tests/baselines/reference/definePropertyESNext.types index 1473a5fc1e60c..34fdac71ed429 100644 --- a/tests/baselines/reference/definePropertyESNext.types +++ b/tests/baselines/reference/definePropertyESNext.types @@ -36,9 +36,11 @@ class C extends B { >C : C >B : B - z = 1 + z = this.ka >z : number ->1 : 1 +>this.ka : number +>this : this +>ka : number constructor(public ka: number) { >ka : number @@ -47,5 +49,10 @@ class C extends B { >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/definePropertyES5.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts index f470e8c28d4fa..33289ffb4d3aa 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts @@ -2,10 +2,11 @@ // @useDefineForClassFields: true var x: "p" = "p" class A { - a = 12 + a = this.y b ["computed"] = 13 ;[x] = 14 m() { } constructor(public readonly y: number) { } + z = this.y } diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts index f95ad06c77263..7b10a68368628 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts @@ -12,8 +12,9 @@ class A { class B { } class C extends B { - z = 1 + z = this.ka constructor(public ka: number) { super() } + ki = this.ka } From 8ff59b98b8670a303b038e1755caf3d02150a43f Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 22 Nov 2019 15:10:12 -0800 Subject: [PATCH 3/3] Combine ES5/ESNext into one test --- .../reference/defineProperty(target=es5).js | 118 ++++++++++++++++++ .../defineProperty(target=es5).symbols | 65 ++++++++++ ...types => defineProperty(target=es5).types} | 14 ++- ...xt.js => defineProperty(target=esnext).js} | 10 +- .../defineProperty(target=esnext).symbols | 65 ++++++++++ ...es => defineProperty(target=esnext).types} | 32 ++++- .../baselines/reference/definePropertyES5.js | 65 ---------- .../reference/definePropertyES5.symbols | 40 ------ .../reference/definePropertyESNext.symbols | 56 --------- ...inePropertyESNext.ts => defineProperty.ts} | 5 +- .../definePropertyES5.ts | 13 -- 11 files changed, 297 insertions(+), 186 deletions(-) create mode 100644 tests/baselines/reference/defineProperty(target=es5).js create mode 100644 tests/baselines/reference/defineProperty(target=es5).symbols rename tests/baselines/reference/{definePropertyESNext.types => defineProperty(target=es5).types} (76%) rename tests/baselines/reference/{definePropertyESNext.js => defineProperty(target=esnext).js} (80%) create mode 100644 tests/baselines/reference/defineProperty(target=esnext).symbols rename tests/baselines/reference/{definePropertyES5.types => defineProperty(target=esnext).types} (52%) delete mode 100644 tests/baselines/reference/definePropertyES5.js delete mode 100644 tests/baselines/reference/definePropertyES5.symbols delete mode 100644 tests/baselines/reference/definePropertyESNext.symbols rename tests/cases/conformance/classes/propertyMemberDeclarations/{definePropertyESNext.ts => defineProperty.ts} (85%) delete mode 100644 tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts diff --git a/tests/baselines/reference/defineProperty(target=es5).js b/tests/baselines/reference/defineProperty(target=es5).js new file mode 100644 index 0000000000000..85a644e0f6529 --- /dev/null +++ b/tests/baselines/reference/defineProperty(target=es5).js @@ -0,0 +1,118 @@ +//// [defineProperty.ts] +var x: "p" = "p" +class A { + a = this.y + b + ["computed"] = 13 + ;[x] = 14 + m() { } + constructor(public readonly y: number) { } + z = this.y + declare notEmitted; +} +class B { +} +class C extends B { + z = this.ka + constructor(public ka: number) { + super() + } + ki = this.ka +} + + +//// [defineProperty.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var _a; +var x = "p"; +var A = /** @class */ (function () { + function A(y) { + Object.defineProperty(this, "y", { + enumerable: true, + configurable: true, + writable: true, + value: y + }); + Object.defineProperty(this, "a", { + enumerable: true, + configurable: true, + writable: true, + value: this.y + }); + Object.defineProperty(this, "b", { + enumerable: true, + configurable: true, + writable: true, + value: void 0 + }); + Object.defineProperty(this, "computed", { + enumerable: true, + configurable: true, + writable: true, + value: 13 + }); + Object.defineProperty(this, _a, { + enumerable: true, + configurable: true, + writable: true, + value: 14 + }); + Object.defineProperty(this, "z", { + enumerable: true, + configurable: true, + writable: true, + value: this.y + }); + } + Object.defineProperty(A.prototype, "m", { + enumerable: false, + configurable: true, + writable: true, + value: function () { } + }); + return A; +}()); +_a = x; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C(ka) { + var _this = _super.call(this) || this; + Object.defineProperty(_this, "ka", { + enumerable: true, + configurable: true, + writable: true, + value: ka + }); + Object.defineProperty(_this, "z", { + enumerable: true, + configurable: true, + writable: true, + value: _this.ka + }); + Object.defineProperty(_this, "ki", { + enumerable: true, + configurable: true, + writable: true, + value: _this.ka + }); + return _this; + } + return C; +}(B)); diff --git a/tests/baselines/reference/defineProperty(target=es5).symbols b/tests/baselines/reference/defineProperty(target=es5).symbols new file mode 100644 index 0000000000000..35d3be47665cc --- /dev/null +++ b/tests/baselines/reference/defineProperty(target=es5).symbols @@ -0,0 +1,65 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts === +var x: "p" = "p" +>x : Symbol(x, Decl(defineProperty.ts, 0, 3)) + +class A { +>A : Symbol(A, Decl(defineProperty.ts, 0, 16)) + + a = this.y +>a : Symbol(A.a, Decl(defineProperty.ts, 1, 9)) +>this.y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) +>this : Symbol(A, Decl(defineProperty.ts, 0, 16)) +>y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) + + b +>b : Symbol(A.b, Decl(defineProperty.ts, 2, 14)) + + ["computed"] = 13 +>["computed"] : Symbol(A["computed"], Decl(defineProperty.ts, 3, 5)) +>"computed" : Symbol(A["computed"], Decl(defineProperty.ts, 3, 5)) + + ;[x] = 14 +>[x] : Symbol(A[x], Decl(defineProperty.ts, 5, 5)) +>x : Symbol(x, Decl(defineProperty.ts, 0, 3)) + + m() { } +>m : Symbol(A.m, Decl(defineProperty.ts, 5, 13)) + + constructor(public readonly y: number) { } +>y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) + + z = this.y +>z : Symbol(A.z, Decl(defineProperty.ts, 7, 46)) +>this.y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) +>this : Symbol(A, Decl(defineProperty.ts, 0, 16)) +>y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) + + declare notEmitted; +>notEmitted : Symbol(A.notEmitted, Decl(defineProperty.ts, 8, 14)) +} +class B { +>B : Symbol(B, Decl(defineProperty.ts, 10, 1)) +} +class C extends B { +>C : Symbol(C, Decl(defineProperty.ts, 12, 1)) +>B : Symbol(B, Decl(defineProperty.ts, 10, 1)) + + z = this.ka +>z : Symbol(C.z, Decl(defineProperty.ts, 13, 19)) +>this.ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) +>this : Symbol(C, Decl(defineProperty.ts, 12, 1)) +>ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) + + constructor(public ka: number) { +>ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) + + super() +>super : Symbol(B, Decl(defineProperty.ts, 10, 1)) + } + ki = this.ka +>ki : Symbol(C.ki, Decl(defineProperty.ts, 17, 5)) +>this.ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) +>this : Symbol(C, Decl(defineProperty.ts, 12, 1)) +>ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) +} + diff --git a/tests/baselines/reference/definePropertyESNext.types b/tests/baselines/reference/defineProperty(target=es5).types similarity index 76% rename from tests/baselines/reference/definePropertyESNext.types rename to tests/baselines/reference/defineProperty(target=es5).types index 303387461a5af..6bd6c74559916 100644 --- a/tests/baselines/reference/definePropertyESNext.types +++ b/tests/baselines/reference/defineProperty(target=es5).types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts === +=== tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts === var x: "p" = "p" >x : "p" >"p" : "p" @@ -6,9 +6,11 @@ var x: "p" = "p" class A { >A : A - a = 12 + a = this.y >a : number ->12 : 12 +>this.y : number +>this : this +>y : number b >b : any @@ -29,6 +31,12 @@ class A { constructor(public readonly y: number) { } >y : number + z = this.y +>z : number +>this.y : number +>this : this +>y : number + declare notEmitted; >notEmitted : any } diff --git a/tests/baselines/reference/definePropertyESNext.js b/tests/baselines/reference/defineProperty(target=esnext).js similarity index 80% rename from tests/baselines/reference/definePropertyESNext.js rename to tests/baselines/reference/defineProperty(target=esnext).js index 5fbd2fad7a93f..53d78aa558759 100644 --- a/tests/baselines/reference/definePropertyESNext.js +++ b/tests/baselines/reference/defineProperty(target=esnext).js @@ -1,12 +1,13 @@ -//// [definePropertyESNext.ts] +//// [defineProperty.ts] var x: "p" = "p" class A { - a = 12 + a = this.y b ["computed"] = 13 ;[x] = 14 m() { } constructor(public readonly y: number) { } + z = this.y declare notEmitted; } class B { @@ -20,11 +21,11 @@ class C extends B { } -//// [definePropertyESNext.js] +//// [defineProperty.js] var x = "p"; class A { y; - a = 12; + a = this.y; b; ["computed"] = 13; [x] = 14; @@ -32,6 +33,7 @@ class A { constructor(y) { this.y = y; } + z = this.y; } class B { } diff --git a/tests/baselines/reference/defineProperty(target=esnext).symbols b/tests/baselines/reference/defineProperty(target=esnext).symbols new file mode 100644 index 0000000000000..35d3be47665cc --- /dev/null +++ b/tests/baselines/reference/defineProperty(target=esnext).symbols @@ -0,0 +1,65 @@ +=== tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts === +var x: "p" = "p" +>x : Symbol(x, Decl(defineProperty.ts, 0, 3)) + +class A { +>A : Symbol(A, Decl(defineProperty.ts, 0, 16)) + + a = this.y +>a : Symbol(A.a, Decl(defineProperty.ts, 1, 9)) +>this.y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) +>this : Symbol(A, Decl(defineProperty.ts, 0, 16)) +>y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) + + b +>b : Symbol(A.b, Decl(defineProperty.ts, 2, 14)) + + ["computed"] = 13 +>["computed"] : Symbol(A["computed"], Decl(defineProperty.ts, 3, 5)) +>"computed" : Symbol(A["computed"], Decl(defineProperty.ts, 3, 5)) + + ;[x] = 14 +>[x] : Symbol(A[x], Decl(defineProperty.ts, 5, 5)) +>x : Symbol(x, Decl(defineProperty.ts, 0, 3)) + + m() { } +>m : Symbol(A.m, Decl(defineProperty.ts, 5, 13)) + + constructor(public readonly y: number) { } +>y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) + + z = this.y +>z : Symbol(A.z, Decl(defineProperty.ts, 7, 46)) +>this.y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) +>this : Symbol(A, Decl(defineProperty.ts, 0, 16)) +>y : Symbol(A.y, Decl(defineProperty.ts, 7, 16)) + + declare notEmitted; +>notEmitted : Symbol(A.notEmitted, Decl(defineProperty.ts, 8, 14)) +} +class B { +>B : Symbol(B, Decl(defineProperty.ts, 10, 1)) +} +class C extends B { +>C : Symbol(C, Decl(defineProperty.ts, 12, 1)) +>B : Symbol(B, Decl(defineProperty.ts, 10, 1)) + + z = this.ka +>z : Symbol(C.z, Decl(defineProperty.ts, 13, 19)) +>this.ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) +>this : Symbol(C, Decl(defineProperty.ts, 12, 1)) +>ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) + + constructor(public ka: number) { +>ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) + + super() +>super : Symbol(B, Decl(defineProperty.ts, 10, 1)) + } + ki = this.ka +>ki : Symbol(C.ki, Decl(defineProperty.ts, 17, 5)) +>this.ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) +>this : Symbol(C, Decl(defineProperty.ts, 12, 1)) +>ka : Symbol(C.ka, Decl(defineProperty.ts, 15, 16)) +} + diff --git a/tests/baselines/reference/definePropertyES5.types b/tests/baselines/reference/defineProperty(target=esnext).types similarity index 52% rename from tests/baselines/reference/definePropertyES5.types rename to tests/baselines/reference/defineProperty(target=esnext).types index 7de77a242691b..6bd6c74559916 100644 --- a/tests/baselines/reference/definePropertyES5.types +++ b/tests/baselines/reference/defineProperty(target=esnext).types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts === +=== tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts === var x: "p" = "p" >x : "p" >"p" : "p" @@ -37,7 +37,33 @@ class A { >this : this >y : number - declare notEmitted: boolean; ->notEmitted : boolean + 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/baselines/reference/definePropertyES5.js b/tests/baselines/reference/definePropertyES5.js deleted file mode 100644 index 300222fa35be2..0000000000000 --- a/tests/baselines/reference/definePropertyES5.js +++ /dev/null @@ -1,65 +0,0 @@ -//// [definePropertyES5.ts] -var x: "p" = "p" -class A { - a = this.y - b - ["computed"] = 13 - ;[x] = 14 - m() { } - constructor(public readonly y: number) { } - z = this.y - declare notEmitted: boolean; -} - - -//// [definePropertyES5.js] -var _a; -var x = "p"; -var A = /** @class */ (function () { - function A(y) { - Object.defineProperty(this, "y", { - enumerable: true, - configurable: true, - writable: true, - value: y - }); - Object.defineProperty(this, "a", { - enumerable: true, - configurable: true, - writable: true, - value: this.y - }); - Object.defineProperty(this, "b", { - enumerable: true, - configurable: true, - writable: true, - value: void 0 - }); - Object.defineProperty(this, "computed", { - enumerable: true, - configurable: true, - writable: true, - value: 13 - }); - Object.defineProperty(this, _a, { - enumerable: true, - configurable: true, - writable: true, - value: 14 - }); - Object.defineProperty(this, "z", { - enumerable: true, - configurable: true, - writable: true, - value: this.y - }); - } - Object.defineProperty(A.prototype, "m", { - enumerable: false, - configurable: true, - writable: true, - value: function () { } - }); - return A; -}()); -_a = x; diff --git a/tests/baselines/reference/definePropertyES5.symbols b/tests/baselines/reference/definePropertyES5.symbols deleted file mode 100644 index a77224c5cf854..0000000000000 --- a/tests/baselines/reference/definePropertyES5.symbols +++ /dev/null @@ -1,40 +0,0 @@ -=== tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts === -var x: "p" = "p" ->x : Symbol(x, Decl(definePropertyES5.ts, 0, 3)) - -class A { ->A : Symbol(A, Decl(definePropertyES5.ts, 0, 16)) - - a = this.y ->a : Symbol(A.a, Decl(definePropertyES5.ts, 1, 9)) ->this.y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) ->this : Symbol(A, Decl(definePropertyES5.ts, 0, 16)) ->y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) - - b ->b : Symbol(A.b, Decl(definePropertyES5.ts, 2, 14)) - - ["computed"] = 13 ->["computed"] : Symbol(A["computed"], Decl(definePropertyES5.ts, 3, 5)) ->"computed" : Symbol(A["computed"], Decl(definePropertyES5.ts, 3, 5)) - - ;[x] = 14 ->[x] : Symbol(A[x], Decl(definePropertyES5.ts, 5, 5)) ->x : Symbol(x, Decl(definePropertyES5.ts, 0, 3)) - - m() { } ->m : Symbol(A.m, Decl(definePropertyES5.ts, 5, 13)) - - constructor(public readonly y: number) { } ->y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) - - z = this.y ->z : Symbol(A.z, Decl(definePropertyES5.ts, 7, 46)) ->this.y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) ->this : Symbol(A, Decl(definePropertyES5.ts, 0, 16)) ->y : Symbol(A.y, Decl(definePropertyES5.ts, 7, 16)) - - declare notEmitted: boolean; ->notEmitted : Symbol(A.notEmitted, Decl(definePropertyES5.ts, 8, 14)) -} - diff --git a/tests/baselines/reference/definePropertyESNext.symbols b/tests/baselines/reference/definePropertyESNext.symbols deleted file mode 100644 index 56463362d4ed3..0000000000000 --- a/tests/baselines/reference/definePropertyESNext.symbols +++ /dev/null @@ -1,56 +0,0 @@ -=== 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/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts similarity index 85% rename from tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts rename to tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts index 4bfd516229f05..19fb68f10d993 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyESNext.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/defineProperty.ts @@ -1,13 +1,14 @@ -// @target: esnext +// @target: es5, esnext // @useDefineForClassFields: true var x: "p" = "p" class A { - a = 12 + a = this.y b ["computed"] = 13 ;[x] = 14 m() { } constructor(public readonly y: number) { } + z = this.y declare notEmitted; } class B { diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts deleted file mode 100644 index b9567cb4d6abb..0000000000000 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/definePropertyES5.ts +++ /dev/null @@ -1,13 +0,0 @@ -// @target: es5 -// @useDefineForClassFields: true -var x: "p" = "p" -class A { - a = this.y - b - ["computed"] = 13 - ;[x] = 14 - m() { } - constructor(public readonly y: number) { } - z = this.y - declare notEmitted: boolean; -}