diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ed4cd7b03f75a..3d3f908d82c79 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -39082,7 +39082,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { expr.expression.kind === SyntaxKind.ThisKeyword ) { // Look for if this is the constructor for the class that `symbol` is a property of. - const ctor = getContainingFunction(expr); + const ctor = getControlFlowContainer(expr); if (!(ctor && (ctor.kind === SyntaxKind.Constructor || isJSConstructor(ctor)))) { return true; } diff --git a/tests/baselines/reference/readonlyMembers.errors.txt b/tests/baselines/reference/readonlyMembers.errors.txt index 565b38257733d..c3ac0ac353e01 100644 --- a/tests/baselines/reference/readonlyMembers.errors.txt +++ b/tests/baselines/reference/readonlyMembers.errors.txt @@ -4,18 +4,19 @@ readonlyMembers.ts(16,14): error TS2540: Cannot assign to 'c' because it is a re readonlyMembers.ts(18,18): error TS2540: Cannot assign to 'a' because it is a read-only property. readonlyMembers.ts(19,18): error TS2540: Cannot assign to 'b' because it is a read-only property. readonlyMembers.ts(20,18): error TS2540: Cannot assign to 'c' because it is a read-only property. -readonlyMembers.ts(24,14): error TS2540: Cannot assign to 'a' because it is a read-only property. -readonlyMembers.ts(25,14): error TS2540: Cannot assign to 'b' because it is a read-only property. -readonlyMembers.ts(26,14): error TS2540: Cannot assign to 'c' because it is a read-only property. -readonlyMembers.ts(35,3): error TS2540: Cannot assign to 'a' because it is a read-only property. -readonlyMembers.ts(39,3): error TS2540: Cannot assign to 'a' because it is a read-only property. -readonlyMembers.ts(48,3): error TS2540: Cannot assign to 'A' because it is a read-only property. -readonlyMembers.ts(55,3): error TS2540: Cannot assign to 'a' because it is a read-only property. -readonlyMembers.ts(61,1): error TS2542: Index signature in type '{ readonly [x: string]: string; }' only permits reading. -readonlyMembers.ts(64,1): error TS2542: Index signature in type '{ readonly [x: number]: string; [x: string]: string; }' only permits reading. +readonlyMembers.ts(25,18): error TS2540: Cannot assign to 'c' because it is a read-only property. +readonlyMembers.ts(29,14): error TS2540: Cannot assign to 'a' because it is a read-only property. +readonlyMembers.ts(30,14): error TS2540: Cannot assign to 'b' because it is a read-only property. +readonlyMembers.ts(31,14): error TS2540: Cannot assign to 'c' because it is a read-only property. +readonlyMembers.ts(40,3): error TS2540: Cannot assign to 'a' because it is a read-only property. +readonlyMembers.ts(44,3): error TS2540: Cannot assign to 'a' because it is a read-only property. +readonlyMembers.ts(53,3): error TS2540: Cannot assign to 'A' because it is a read-only property. +readonlyMembers.ts(60,3): error TS2540: Cannot assign to 'a' because it is a read-only property. +readonlyMembers.ts(66,1): error TS2542: Index signature in type '{ readonly [x: string]: string; }' only permits reading. +readonlyMembers.ts(69,1): error TS2542: Index signature in type '{ readonly [x: number]: string; [x: string]: string; }' only permits reading. -==== readonlyMembers.ts (15 errors) ==== +==== readonlyMembers.ts (16 errors) ==== interface X { readonly a: number; readonly b?: number; @@ -48,7 +49,14 @@ readonlyMembers.ts(64,1): error TS2542: Index signature in type '{ readonly [x: this.c = 1; // Error ~ !!! error TS2540: Cannot assign to 'c' because it is a read-only property. - } + }; + (() => { + this.a = 1; // Ok + this.b = 1; // Ok + this.c = 1; // Error + ~ +!!! error TS2540: Cannot assign to 'c' because it is a read-only property. + })(); } foo() { this.a = 1; // Error diff --git a/tests/baselines/reference/readonlyMembers.js b/tests/baselines/reference/readonlyMembers.js index 7a3cb40d69a57..d17cc430b7e35 100644 --- a/tests/baselines/reference/readonlyMembers.js +++ b/tests/baselines/reference/readonlyMembers.js @@ -21,7 +21,12 @@ class C { this.a = 1; // Error this.b = 1; // Error this.c = 1; // Error - } + }; + (() => { + this.a = 1; // Ok + this.b = 1; // Ok + this.c = 1; // Error + })(); } foo() { this.a = 1; // Error @@ -83,6 +88,11 @@ var C = /** @class */ (function () { _this.b = 1; // Error _this.c = 1; // Error }; + (function () { + _this.a = 1; // Ok + _this.b = 1; // Ok + _this.c = 1; // Error + })(); } Object.defineProperty(C.prototype, "c", { get: function () { return 1; }, diff --git a/tests/baselines/reference/readonlyMembers.symbols b/tests/baselines/reference/readonlyMembers.symbols index a62200bc2928e..a7e051096527e 100644 --- a/tests/baselines/reference/readonlyMembers.symbols +++ b/tests/baselines/reference/readonlyMembers.symbols @@ -70,10 +70,28 @@ class C { >this.c : Symbol(C.c, Decl(readonlyMembers.ts, 10, 19)) >this : Symbol(C, Decl(readonlyMembers.ts, 6, 8)) >c : Symbol(C.c, Decl(readonlyMembers.ts, 10, 19)) - } + + }; + (() => { + this.a = 1; // Ok +>this.a : Symbol(C.a, Decl(readonlyMembers.ts, 8, 9)) +>this : Symbol(C, Decl(readonlyMembers.ts, 6, 8)) +>a : Symbol(C.a, Decl(readonlyMembers.ts, 8, 9)) + + this.b = 1; // Ok +>this.b : Symbol(C.b, Decl(readonlyMembers.ts, 9, 23)) +>this : Symbol(C, Decl(readonlyMembers.ts, 6, 8)) +>b : Symbol(C.b, Decl(readonlyMembers.ts, 9, 23)) + + this.c = 1; // Error +>this.c : Symbol(C.c, Decl(readonlyMembers.ts, 10, 19)) +>this : Symbol(C, Decl(readonlyMembers.ts, 6, 8)) +>c : Symbol(C.c, Decl(readonlyMembers.ts, 10, 19)) + + })(); } foo() { ->foo : Symbol(C.foo, Decl(readonlyMembers.ts, 21, 5)) +>foo : Symbol(C.foo, Decl(readonlyMembers.ts, 26, 5)) this.a = 1; // Error >this.a : Symbol(C.a, Decl(readonlyMembers.ts, 8, 9)) @@ -93,121 +111,121 @@ class C { } var o = { ->o : Symbol(o, Decl(readonlyMembers.ts, 29, 3)) +>o : Symbol(o, Decl(readonlyMembers.ts, 34, 3)) get a() { return 1 }, ->a : Symbol(a, Decl(readonlyMembers.ts, 29, 9)) +>a : Symbol(a, Decl(readonlyMembers.ts, 34, 9)) get b() { return 1 }, ->b : Symbol(b, Decl(readonlyMembers.ts, 30, 25), Decl(readonlyMembers.ts, 31, 25)) +>b : Symbol(b, Decl(readonlyMembers.ts, 35, 25), Decl(readonlyMembers.ts, 36, 25)) set b(value) { } ->b : Symbol(b, Decl(readonlyMembers.ts, 30, 25), Decl(readonlyMembers.ts, 31, 25)) ->value : Symbol(value, Decl(readonlyMembers.ts, 32, 10)) +>b : Symbol(b, Decl(readonlyMembers.ts, 35, 25), Decl(readonlyMembers.ts, 36, 25)) +>value : Symbol(value, Decl(readonlyMembers.ts, 37, 10)) }; o.a = 1; // Error ->o.a : Symbol(a, Decl(readonlyMembers.ts, 29, 9)) ->o : Symbol(o, Decl(readonlyMembers.ts, 29, 3)) ->a : Symbol(a, Decl(readonlyMembers.ts, 29, 9)) +>o.a : Symbol(a, Decl(readonlyMembers.ts, 34, 9)) +>o : Symbol(o, Decl(readonlyMembers.ts, 34, 3)) +>a : Symbol(a, Decl(readonlyMembers.ts, 34, 9)) o.b = 1; ->o.b : Symbol(b, Decl(readonlyMembers.ts, 30, 25), Decl(readonlyMembers.ts, 31, 25)) ->o : Symbol(o, Decl(readonlyMembers.ts, 29, 3)) ->b : Symbol(b, Decl(readonlyMembers.ts, 30, 25), Decl(readonlyMembers.ts, 31, 25)) +>o.b : Symbol(b, Decl(readonlyMembers.ts, 35, 25), Decl(readonlyMembers.ts, 36, 25)) +>o : Symbol(o, Decl(readonlyMembers.ts, 34, 3)) +>b : Symbol(b, Decl(readonlyMembers.ts, 35, 25), Decl(readonlyMembers.ts, 36, 25)) var p: { readonly a: number, b: number } = { a: 1, b: 1 }; ->p : Symbol(p, Decl(readonlyMembers.ts, 37, 3)) ->a : Symbol(a, Decl(readonlyMembers.ts, 37, 8)) ->b : Symbol(b, Decl(readonlyMembers.ts, 37, 28)) ->a : Symbol(a, Decl(readonlyMembers.ts, 37, 44)) ->b : Symbol(b, Decl(readonlyMembers.ts, 37, 50)) +>p : Symbol(p, Decl(readonlyMembers.ts, 42, 3)) +>a : Symbol(a, Decl(readonlyMembers.ts, 42, 8)) +>b : Symbol(b, Decl(readonlyMembers.ts, 42, 28)) +>a : Symbol(a, Decl(readonlyMembers.ts, 42, 44)) +>b : Symbol(b, Decl(readonlyMembers.ts, 42, 50)) p.a = 1; // Error ->p.a : Symbol(a, Decl(readonlyMembers.ts, 37, 8)) ->p : Symbol(p, Decl(readonlyMembers.ts, 37, 3)) ->a : Symbol(a, Decl(readonlyMembers.ts, 37, 8)) +>p.a : Symbol(a, Decl(readonlyMembers.ts, 42, 8)) +>p : Symbol(p, Decl(readonlyMembers.ts, 42, 3)) +>a : Symbol(a, Decl(readonlyMembers.ts, 42, 8)) p.b = 1; ->p.b : Symbol(b, Decl(readonlyMembers.ts, 37, 28)) ->p : Symbol(p, Decl(readonlyMembers.ts, 37, 3)) ->b : Symbol(b, Decl(readonlyMembers.ts, 37, 28)) +>p.b : Symbol(b, Decl(readonlyMembers.ts, 42, 28)) +>p : Symbol(p, Decl(readonlyMembers.ts, 42, 3)) +>b : Symbol(b, Decl(readonlyMembers.ts, 42, 28)) var q: { a: number, b: number } = p; ->q : Symbol(q, Decl(readonlyMembers.ts, 40, 3)) ->a : Symbol(a, Decl(readonlyMembers.ts, 40, 8)) ->b : Symbol(b, Decl(readonlyMembers.ts, 40, 19)) ->p : Symbol(p, Decl(readonlyMembers.ts, 37, 3)) +>q : Symbol(q, Decl(readonlyMembers.ts, 45, 3)) +>a : Symbol(a, Decl(readonlyMembers.ts, 45, 8)) +>b : Symbol(b, Decl(readonlyMembers.ts, 45, 19)) +>p : Symbol(p, Decl(readonlyMembers.ts, 42, 3)) q.a = 1; ->q.a : Symbol(a, Decl(readonlyMembers.ts, 40, 8)) ->q : Symbol(q, Decl(readonlyMembers.ts, 40, 3)) ->a : Symbol(a, Decl(readonlyMembers.ts, 40, 8)) +>q.a : Symbol(a, Decl(readonlyMembers.ts, 45, 8)) +>q : Symbol(q, Decl(readonlyMembers.ts, 45, 3)) +>a : Symbol(a, Decl(readonlyMembers.ts, 45, 8)) q.b = 1; ->q.b : Symbol(b, Decl(readonlyMembers.ts, 40, 19)) ->q : Symbol(q, Decl(readonlyMembers.ts, 40, 3)) ->b : Symbol(b, Decl(readonlyMembers.ts, 40, 19)) +>q.b : Symbol(b, Decl(readonlyMembers.ts, 45, 19)) +>q : Symbol(q, Decl(readonlyMembers.ts, 45, 3)) +>b : Symbol(b, Decl(readonlyMembers.ts, 45, 19)) enum E { ->E : Symbol(E, Decl(readonlyMembers.ts, 42, 8)) +>E : Symbol(E, Decl(readonlyMembers.ts, 47, 8)) A, B, C ->A : Symbol(E.A, Decl(readonlyMembers.ts, 44, 8)) ->B : Symbol(E.B, Decl(readonlyMembers.ts, 45, 6)) ->C : Symbol(E.C, Decl(readonlyMembers.ts, 45, 9)) +>A : Symbol(E.A, Decl(readonlyMembers.ts, 49, 8)) +>B : Symbol(E.B, Decl(readonlyMembers.ts, 50, 6)) +>C : Symbol(E.C, Decl(readonlyMembers.ts, 50, 9)) } E.A = 1; // Error ->E.A : Symbol(E.A, Decl(readonlyMembers.ts, 44, 8)) ->E : Symbol(E, Decl(readonlyMembers.ts, 42, 8)) ->A : Symbol(E.A, Decl(readonlyMembers.ts, 44, 8)) +>E.A : Symbol(E.A, Decl(readonlyMembers.ts, 49, 8)) +>E : Symbol(E, Decl(readonlyMembers.ts, 47, 8)) +>A : Symbol(E.A, Decl(readonlyMembers.ts, 49, 8)) namespace N { ->N : Symbol(N, Decl(readonlyMembers.ts, 47, 8)) +>N : Symbol(N, Decl(readonlyMembers.ts, 52, 8)) export const a = 1; ->a : Symbol(a, Decl(readonlyMembers.ts, 50, 16)) +>a : Symbol(a, Decl(readonlyMembers.ts, 55, 16)) export let b = 1; ->b : Symbol(b, Decl(readonlyMembers.ts, 51, 14)) +>b : Symbol(b, Decl(readonlyMembers.ts, 56, 14)) export var c = 1; ->c : Symbol(c, Decl(readonlyMembers.ts, 52, 14)) +>c : Symbol(c, Decl(readonlyMembers.ts, 57, 14)) } N.a = 1; // Error ->N.a : Symbol(N.a, Decl(readonlyMembers.ts, 50, 16)) ->N : Symbol(N, Decl(readonlyMembers.ts, 47, 8)) ->a : Symbol(N.a, Decl(readonlyMembers.ts, 50, 16)) +>N.a : Symbol(N.a, Decl(readonlyMembers.ts, 55, 16)) +>N : Symbol(N, Decl(readonlyMembers.ts, 52, 8)) +>a : Symbol(N.a, Decl(readonlyMembers.ts, 55, 16)) N.b = 1; ->N.b : Symbol(N.b, Decl(readonlyMembers.ts, 51, 14)) ->N : Symbol(N, Decl(readonlyMembers.ts, 47, 8)) ->b : Symbol(N.b, Decl(readonlyMembers.ts, 51, 14)) +>N.b : Symbol(N.b, Decl(readonlyMembers.ts, 56, 14)) +>N : Symbol(N, Decl(readonlyMembers.ts, 52, 8)) +>b : Symbol(N.b, Decl(readonlyMembers.ts, 56, 14)) N.c = 1; ->N.c : Symbol(N.c, Decl(readonlyMembers.ts, 52, 14)) ->N : Symbol(N, Decl(readonlyMembers.ts, 47, 8)) ->c : Symbol(N.c, Decl(readonlyMembers.ts, 52, 14)) +>N.c : Symbol(N.c, Decl(readonlyMembers.ts, 57, 14)) +>N : Symbol(N, Decl(readonlyMembers.ts, 52, 8)) +>c : Symbol(N.c, Decl(readonlyMembers.ts, 57, 14)) let xx: { readonly [x: string]: string }; ->xx : Symbol(xx, Decl(readonlyMembers.ts, 58, 3)) ->x : Symbol(x, Decl(readonlyMembers.ts, 58, 20)) +>xx : Symbol(xx, Decl(readonlyMembers.ts, 63, 3)) +>x : Symbol(x, Decl(readonlyMembers.ts, 63, 20)) let s = xx["foo"]; ->s : Symbol(s, Decl(readonlyMembers.ts, 59, 3)) ->xx : Symbol(xx, Decl(readonlyMembers.ts, 58, 3)) +>s : Symbol(s, Decl(readonlyMembers.ts, 64, 3)) +>xx : Symbol(xx, Decl(readonlyMembers.ts, 63, 3)) xx["foo"] = "abc"; // Error ->xx : Symbol(xx, Decl(readonlyMembers.ts, 58, 3)) +>xx : Symbol(xx, Decl(readonlyMembers.ts, 63, 3)) let yy: { readonly [x: number]: string, [x: string]: string }; ->yy : Symbol(yy, Decl(readonlyMembers.ts, 62, 3)) ->x : Symbol(x, Decl(readonlyMembers.ts, 62, 20)) ->x : Symbol(x, Decl(readonlyMembers.ts, 62, 41)) +>yy : Symbol(yy, Decl(readonlyMembers.ts, 67, 3)) +>x : Symbol(x, Decl(readonlyMembers.ts, 67, 20)) +>x : Symbol(x, Decl(readonlyMembers.ts, 67, 41)) yy[1] = "abc"; // Error ->yy : Symbol(yy, Decl(readonlyMembers.ts, 62, 3)) +>yy : Symbol(yy, Decl(readonlyMembers.ts, 67, 3)) yy["foo"] = "abc"; ->yy : Symbol(yy, Decl(readonlyMembers.ts, 62, 3)) +>yy : Symbol(yy, Decl(readonlyMembers.ts, 67, 3)) diff --git a/tests/baselines/reference/readonlyMembers.types b/tests/baselines/reference/readonlyMembers.types index 0566106bdf4a9..852ed3e69251c 100644 --- a/tests/baselines/reference/readonlyMembers.types +++ b/tests/baselines/reference/readonlyMembers.types @@ -142,7 +142,53 @@ class C { > : ^^^ >1 : 1 > : ^ - } + + }; + (() => { +>(() => { this.a = 1; // Ok this.b = 1; // Ok this.c = 1; // Error })() : void +> : ^^^^ +>(() => { this.a = 1; // Ok this.b = 1; // Ok this.c = 1; // Error }) : () => void +> : ^^^^^^^^^^ +>() => { this.a = 1; // Ok this.b = 1; // Ok this.c = 1; // Error } : () => void +> : ^^^^^^^^^^ + + this.a = 1; // Ok +>this.a = 1 : 1 +> : ^ +>this.a : number +> : ^^^^^^ +>this : this +> : ^^^^ +>a : number +> : ^^^^^^ +>1 : 1 +> : ^ + + this.b = 1; // Ok +>this.b = 1 : 1 +> : ^ +>this.b : 1 +> : ^ +>this : this +> : ^^^^ +>b : 1 +> : ^ +>1 : 1 +> : ^ + + this.c = 1; // Error +>this.c = 1 : 1 +> : ^ +>this.c : any +> : ^^^ +>this : this +> : ^^^^ +>c : any +> : ^^^ +>1 : 1 +> : ^ + + })(); } foo() { >foo : () => void diff --git a/tests/cases/compiler/readonlyMembers.ts b/tests/cases/compiler/readonlyMembers.ts index f24b365772755..b625da3b12d09 100644 --- a/tests/cases/compiler/readonlyMembers.ts +++ b/tests/cases/compiler/readonlyMembers.ts @@ -20,7 +20,12 @@ class C { this.a = 1; // Error this.b = 1; // Error this.c = 1; // Error - } + }; + (() => { + this.a = 1; // Ok + this.b = 1; // Ok + this.c = 1; // Error + })(); } foo() { this.a = 1; // Error