diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 265300adbd9..da4a5b08a0a 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 d413a835d0d..9b0823a46f2 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 1d1ec488cdc..5f51ef5bc4e 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 4fad0556075..82eaadd9b36 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 6beb7516bcd..88c322d532d 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 56c7ce36f68..31c0d269310 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 adc8913c085..93c82a879fd 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 1473a5fc1e6..34fdac71ed4 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 f470e8c28d4..33289ffb4d3 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 f95ad06c772..7b10a683686 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 }