From dcbaadaa606585c8aedef8565fb284afb2621c0c Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Fri, 20 May 2016 08:54:05 -0700 Subject: [PATCH] Allow assignment to readonly parameter property within the constructor --- src/compiler/checker.ts | 14 ++++++++++++-- .../reference/readonlyConstructorAssignment.js | 16 ++++++++++++++++ .../readonlyConstructorAssignment.symbols | 14 ++++++++++++++ .../readonlyConstructorAssignment.types | 16 ++++++++++++++++ .../readonlyConstructorAssignment.ts | 5 +++++ 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/readonlyConstructorAssignment.js create mode 100644 tests/baselines/reference/readonlyConstructorAssignment.symbols create mode 100644 tests/baselines/reference/readonlyConstructorAssignment.types create mode 100644 tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 476695e3ec..8b15d7291b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11882,8 +11882,18 @@ namespace ts { if (symbol.flags & SymbolFlags.Property && (expr.kind === SyntaxKind.PropertyAccessExpression || expr.kind === SyntaxKind.ElementAccessExpression) && (expr as PropertyAccessExpression | ElementAccessExpression).expression.kind === SyntaxKind.ThisKeyword) { - const func = getContainingFunction(expr); - return !(func && func.kind === SyntaxKind.Constructor && func.parent === symbol.valueDeclaration.parent); + return !isInConstructor(getContainingFunction(expr)); + function isInConstructor(func: FunctionLikeDeclaration) { + if (!func) + return false; + if (func.kind !== SyntaxKind.Constructor) + return false; + if (func.parent === symbol.valueDeclaration.parent) // If the symbol was declared in the class: + return true; + if (func === symbol.valueDeclaration.parent) // If symbolDecl is a parameter property of the constructor: + return true; + return false; + } } return true; } diff --git a/tests/baselines/reference/readonlyConstructorAssignment.js b/tests/baselines/reference/readonlyConstructorAssignment.js new file mode 100644 index 0000000000..3d00f829a7 --- /dev/null +++ b/tests/baselines/reference/readonlyConstructorAssignment.js @@ -0,0 +1,16 @@ +//// [readonlyConstructorAssignment.ts] +class A { + constructor(readonly x: number) { + this.x = 7; + } +} + + +//// [readonlyConstructorAssignment.js] +var A = (function () { + function A(x) { + this.x = x; + this.x = 7; + } + return A; +}()); diff --git a/tests/baselines/reference/readonlyConstructorAssignment.symbols b/tests/baselines/reference/readonlyConstructorAssignment.symbols new file mode 100644 index 0000000000..594f9e02b6 --- /dev/null +++ b/tests/baselines/reference/readonlyConstructorAssignment.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts === +class A { +>A : Symbol(A, Decl(readonlyConstructorAssignment.ts, 0, 0)) + + constructor(readonly x: number) { +>x : Symbol(A.x, Decl(readonlyConstructorAssignment.ts, 1, 16)) + + this.x = 7; +>this.x : Symbol(A.x, Decl(readonlyConstructorAssignment.ts, 1, 16)) +>this : Symbol(A, Decl(readonlyConstructorAssignment.ts, 0, 0)) +>x : Symbol(A.x, Decl(readonlyConstructorAssignment.ts, 1, 16)) + } +} + diff --git a/tests/baselines/reference/readonlyConstructorAssignment.types b/tests/baselines/reference/readonlyConstructorAssignment.types new file mode 100644 index 0000000000..10f1cd2047 --- /dev/null +++ b/tests/baselines/reference/readonlyConstructorAssignment.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts === +class A { +>A : A + + constructor(readonly x: number) { +>x : number + + this.x = 7; +>this.x = 7 : number +>this.x : number +>this : this +>x : number +>7 : number + } +} + diff --git a/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts b/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts new file mode 100644 index 0000000000..a81bf69249 --- /dev/null +++ b/tests/cases/conformance/classes/constructorDeclarations/constructorParameters/readonlyConstructorAssignment.ts @@ -0,0 +1,5 @@ +class A { + constructor(readonly x: number) { + this.x = 7; + } +}