From 7d8a2b913e7351a462da2dd89f050fae2f36126e Mon Sep 17 00:00:00 2001 From: Kubilay Kahveci Date: Tue, 23 Mar 2021 15:34:40 +0000 Subject: [PATCH 1/3] produce an error if private field helpers are not up to date --- src/compiler/checker.ts | 22 +++++++++++++++++++--- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 843048f245e41..bb1ac6a715b6f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26791,12 +26791,18 @@ namespace ts { const parentSymbol = getNodeLinks(left).resolvedSymbol; const assignmentKind = getAssignmentTargetKind(node); const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(node) ? getWidenedType(leftType) : leftType); - if (isPrivateIdentifier(right)) { - checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldGet); - } const isAnyLike = isTypeAny(apparentType) || apparentType === silentNeverType; let prop: Symbol | undefined; if (isPrivateIdentifier(right)) { + if (languageVersion < ScriptTarget.ESNext) { + if (assignmentKind !== AssignmentKind.None) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldSet); + } + if (assignmentKind !== AssignmentKind.Definite) { + checkExternalEmitHelpers(node, ExternalEmitHelpers.ClassPrivateFieldGet); + } + } + const lexicallyScopedSymbol = lookupSymbolForPrivateIdentifierDeclaration(right.escapedText, right); if (assignmentKind && lexicallyScopedSymbol && lexicallyScopedSymbol.valueDeclaration && isMethodDeclaration(lexicallyScopedSymbol.valueDeclaration)) { grammarErrorOnNode(right, Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable, idText(right)); @@ -39906,6 +39912,16 @@ namespace ts { if (!symbol) { error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name); } + else if (helper & ExternalEmitHelpers.ClassPrivateFieldGet) { + if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4); + } + } + else if (helper & ExternalEmitHelpers.ClassPrivateFieldSet) { + if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) { + error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5); + } + } } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4a2284effa353..671ce09dc4969 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3300,6 +3300,10 @@ "category": "Error", "code": 2806 }, + "This syntax requires an imported helper named '{1}' with {2} parameters, which is not compatible with the one in '{0}'. Consider upgrading your version of '{0}'.": { + "category": "Error", + "code": 2807 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", From d0d2055142190df0d96e81d21d9ab775755857aa Mon Sep 17 00:00:00 2001 From: Kubilay Kahveci Date: Tue, 23 Mar 2021 15:34:45 +0000 Subject: [PATCH 2/3] add tests --- .../privateNameEmitHelpers.errors.txt | 20 +++++++++ .../reference/privateNameEmitHelpers.js | 25 +++++++++++ .../reference/privateNameEmitHelpers.symbols | 42 +++++++++++++++++++ .../reference/privateNameEmitHelpers.types | 37 ++++++++++++++++ .../privateNameStaticEmitHelpers.errors.txt | 20 +++++++++ .../reference/privateNameStaticEmitHelpers.js | 22 ++++++++++ .../privateNameStaticEmitHelpers.symbols | 40 ++++++++++++++++++ .../privateNameStaticEmitHelpers.types | 35 ++++++++++++++++ .../privateNames/privateNameEmitHelpers.ts | 16 +++++++ .../privateNameStaticEmitHelpers.ts | 16 +++++++ 10 files changed, 273 insertions(+) create mode 100644 tests/baselines/reference/privateNameEmitHelpers.errors.txt create mode 100644 tests/baselines/reference/privateNameEmitHelpers.js create mode 100644 tests/baselines/reference/privateNameEmitHelpers.symbols create mode 100644 tests/baselines/reference/privateNameEmitHelpers.types create mode 100644 tests/baselines/reference/privateNameStaticEmitHelpers.errors.txt create mode 100644 tests/baselines/reference/privateNameStaticEmitHelpers.js create mode 100644 tests/baselines/reference/privateNameStaticEmitHelpers.symbols create mode 100644 tests/baselines/reference/privateNameStaticEmitHelpers.types create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameEmitHelpers.ts create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameStaticEmitHelpers.ts diff --git a/tests/baselines/reference/privateNameEmitHelpers.errors.txt b/tests/baselines/reference/privateNameEmitHelpers.errors.txt new file mode 100644 index 0000000000000..05d5fd4a7e8fb --- /dev/null +++ b/tests/baselines/reference/privateNameEmitHelpers.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/classes/members/privateNames/main.ts(3,12): error TS2807: This syntax requires an imported helper named '__classPrivateFieldSet' with 5 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. +tests/cases/conformance/classes/members/privateNames/main.ts(4,25): error TS2807: This syntax requires an imported helper named '__classPrivateFieldGet' with 4 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. + + +==== tests/cases/conformance/classes/members/privateNames/main.ts (2 errors) ==== + export class C { + #a = 1; + #b() { this.#c = 42; } + ~~~~~~~ +!!! error TS2807: This syntax requires an imported helper named '__classPrivateFieldSet' with 5 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. + set #c(v: number) { this.#a += v; } + ~~~~~~~ +!!! error TS2807: This syntax requires an imported helper named '__classPrivateFieldGet' with 4 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. + } + +==== tests/cases/conformance/classes/members/privateNames/tslib.d.ts (0 errors) ==== + // these are pre-TS4.3 versions of emit helpers, which only supported private instance fields + export declare function __classPrivateFieldGet(receiver: T, state: any): V; + export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameEmitHelpers.js b/tests/baselines/reference/privateNameEmitHelpers.js new file mode 100644 index 0000000000000..1c46c25afa8fe --- /dev/null +++ b/tests/baselines/reference/privateNameEmitHelpers.js @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/classes/members/privateNames/privateNameEmitHelpers.ts] //// + +//// [main.ts] +export class C { + #a = 1; + #b() { this.#c = 42; } + set #c(v: number) { this.#a += v; } +} + +//// [tslib.d.ts] +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; + + +//// [main.js] +var _C_instances, _C_a, _C_b, _C_c_set; +import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; +export class C { + constructor() { + _C_instances.add(this); + _C_a.set(this, 1); + } +} +_C_a = new WeakMap(), _C_instances = new WeakSet(), _C_b = function _C_b() { __classPrivateFieldSet(this, _C_instances, 42, "a", _C_c_set); }, _C_c_set = function _C_c_set(v) { __classPrivateFieldSet(this, _C_a, __classPrivateFieldGet(this, _C_a, "f") + v, "f"); }; diff --git a/tests/baselines/reference/privateNameEmitHelpers.symbols b/tests/baselines/reference/privateNameEmitHelpers.symbols new file mode 100644 index 0000000000000..6b34f80303b77 --- /dev/null +++ b/tests/baselines/reference/privateNameEmitHelpers.symbols @@ -0,0 +1,42 @@ +=== tests/cases/conformance/classes/members/privateNames/main.ts === +export class C { +>C : Symbol(C, Decl(main.ts, 0, 0)) + + #a = 1; +>#a : Symbol(C.#a, Decl(main.ts, 0, 16)) + + #b() { this.#c = 42; } +>#b : Symbol(C.#b, Decl(main.ts, 1, 11)) +>this.#c : Symbol(C.#c, Decl(main.ts, 2, 26)) +>this : Symbol(C, Decl(main.ts, 0, 0)) + + set #c(v: number) { this.#a += v; } +>#c : Symbol(C.#c, Decl(main.ts, 2, 26)) +>v : Symbol(v, Decl(main.ts, 3, 11)) +>this.#a : Symbol(C.#a, Decl(main.ts, 0, 16)) +>this : Symbol(C, Decl(main.ts, 0, 0)) +>v : Symbol(v, Decl(main.ts, 3, 11)) +} + +=== tests/cases/conformance/classes/members/privateNames/tslib.d.ts === +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +>__classPrivateFieldGet : Symbol(__classPrivateFieldGet, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) +>receiver : Symbol(receiver, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>state : Symbol(state, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) + +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; +>__classPrivateFieldSet : Symbol(__classPrivateFieldSet, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) +>receiver : Symbol(receiver, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>state : Symbol(state, Decl(tslib.d.ts, --, --)) +>value : Symbol(value, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) + diff --git a/tests/baselines/reference/privateNameEmitHelpers.types b/tests/baselines/reference/privateNameEmitHelpers.types new file mode 100644 index 0000000000000..e45e6b60df3ce --- /dev/null +++ b/tests/baselines/reference/privateNameEmitHelpers.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/classes/members/privateNames/main.ts === +export class C { +>C : C + + #a = 1; +>#a : number +>1 : 1 + + #b() { this.#c = 42; } +>#b : () => void +>this.#c = 42 : 42 +>this.#c : number +>this : this +>42 : 42 + + set #c(v: number) { this.#a += v; } +>#c : number +>v : number +>this.#a += v : number +>this.#a : number +>this : this +>v : number +} + +=== tests/cases/conformance/classes/members/privateNames/tslib.d.ts === +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +>__classPrivateFieldGet : (receiver: T, state: any) => V +>receiver : T +>state : any + +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; +>__classPrivateFieldSet : (receiver: T, state: any, value: V) => V +>receiver : T +>state : any +>value : V + diff --git a/tests/baselines/reference/privateNameStaticEmitHelpers.errors.txt b/tests/baselines/reference/privateNameStaticEmitHelpers.errors.txt new file mode 100644 index 0000000000000..067e0d4b1a5dc --- /dev/null +++ b/tests/baselines/reference/privateNameStaticEmitHelpers.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/classes/members/privateNames/main.ts(3,19): error TS2807: This syntax requires an imported helper named '__classPrivateFieldSet' with 5 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. +tests/cases/conformance/classes/members/privateNames/main.ts(4,30): error TS2807: This syntax requires an imported helper named '__classPrivateFieldGet' with 4 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. + + +==== tests/cases/conformance/classes/members/privateNames/main.ts (2 errors) ==== + export class S { + static #a = 1; + static #b() { this.#a = 42; } + ~~~~~~~ +!!! error TS2807: This syntax requires an imported helper named '__classPrivateFieldSet' with 5 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. + static get #c() { return S.#b(); } + ~~~~ +!!! error TS2807: This syntax requires an imported helper named '__classPrivateFieldGet' with 4 parameters, which is not compatible with the one in 'tslib'. Consider upgrading your version of 'tslib'. + } + +==== tests/cases/conformance/classes/members/privateNames/tslib.d.ts (0 errors) ==== + // these are pre-TS4.3 versions of emit helpers, which only supported private instance fields + export declare function __classPrivateFieldGet(receiver: T, state: any): V; + export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; + \ No newline at end of file diff --git a/tests/baselines/reference/privateNameStaticEmitHelpers.js b/tests/baselines/reference/privateNameStaticEmitHelpers.js new file mode 100644 index 0000000000000..0e57493d5342d --- /dev/null +++ b/tests/baselines/reference/privateNameStaticEmitHelpers.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/classes/members/privateNames/privateNameStaticEmitHelpers.ts] //// + +//// [main.ts] +export class S { + static #a = 1; + static #b() { this.#a = 42; } + static get #c() { return S.#b(); } +} + +//// [tslib.d.ts] +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; + + +//// [main.js] +var _a, _S_a, _S_b, _S_c_get; +import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib"; +export class S { +} +_a = S, _S_b = function _S_b() { __classPrivateFieldSet(this, _a, 42, "f", _S_a); }, _S_c_get = function _S_c_get() { return __classPrivateFieldGet(S, _a, "m", _S_b).call(S); }; +_S_a = { value: 1 }; diff --git a/tests/baselines/reference/privateNameStaticEmitHelpers.symbols b/tests/baselines/reference/privateNameStaticEmitHelpers.symbols new file mode 100644 index 0000000000000..12678d86b50f8 --- /dev/null +++ b/tests/baselines/reference/privateNameStaticEmitHelpers.symbols @@ -0,0 +1,40 @@ +=== tests/cases/conformance/classes/members/privateNames/main.ts === +export class S { +>S : Symbol(S, Decl(main.ts, 0, 0)) + + static #a = 1; +>#a : Symbol(S.#a, Decl(main.ts, 0, 16)) + + static #b() { this.#a = 42; } +>#b : Symbol(S.#b, Decl(main.ts, 1, 18)) +>this.#a : Symbol(S.#a, Decl(main.ts, 0, 16)) +>this : Symbol(S, Decl(main.ts, 0, 0)) + + static get #c() { return S.#b(); } +>#c : Symbol(S.#c, Decl(main.ts, 2, 33)) +>S.#b : Symbol(S.#b, Decl(main.ts, 1, 18)) +>S : Symbol(S, Decl(main.ts, 0, 0)) +} + +=== tests/cases/conformance/classes/members/privateNames/tslib.d.ts === +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +>__classPrivateFieldGet : Symbol(__classPrivateFieldGet, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) +>receiver : Symbol(receiver, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>state : Symbol(state, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) + +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; +>__classPrivateFieldSet : Symbol(__classPrivateFieldSet, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) +>receiver : Symbol(receiver, Decl(tslib.d.ts, --, --)) +>T : Symbol(T, Decl(tslib.d.ts, --, --)) +>state : Symbol(state, Decl(tslib.d.ts, --, --)) +>value : Symbol(value, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) +>V : Symbol(V, Decl(tslib.d.ts, --, --)) + diff --git a/tests/baselines/reference/privateNameStaticEmitHelpers.types b/tests/baselines/reference/privateNameStaticEmitHelpers.types new file mode 100644 index 0000000000000..c91637bcad3f4 --- /dev/null +++ b/tests/baselines/reference/privateNameStaticEmitHelpers.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/classes/members/privateNames/main.ts === +export class S { +>S : S + + static #a = 1; +>#a : number +>1 : 1 + + static #b() { this.#a = 42; } +>#b : () => void +>this.#a = 42 : 42 +>this.#a : number +>this : typeof S +>42 : 42 + + static get #c() { return S.#b(); } +>#c : void +>S.#b() : void +>S.#b : () => void +>S : typeof S +} + +=== tests/cases/conformance/classes/members/privateNames/tslib.d.ts === +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +>__classPrivateFieldGet : (receiver: T, state: any) => V +>receiver : T +>state : any + +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; +>__classPrivateFieldSet : (receiver: T, state: any, value: V) => V +>receiver : T +>state : any +>value : V + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameEmitHelpers.ts b/tests/cases/conformance/classes/members/privateNames/privateNameEmitHelpers.ts new file mode 100644 index 0000000000000..82dc5693d42ba --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameEmitHelpers.ts @@ -0,0 +1,16 @@ +// @target: es2015 +// @importHelpers: true +// @isolatedModules: true + +// @filename: main.ts + +export class C { + #a = 1; + #b() { this.#c = 42; } + set #c(v: number) { this.#a += v; } +} + +// @filename: tslib.d.ts +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameStaticEmitHelpers.ts b/tests/cases/conformance/classes/members/privateNames/privateNameStaticEmitHelpers.ts new file mode 100644 index 0000000000000..b1261a039e563 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameStaticEmitHelpers.ts @@ -0,0 +1,16 @@ +// @target: es2015 +// @importHelpers: true +// @isolatedModules: true + +// @filename: main.ts + +export class S { + static #a = 1; + static #b() { this.#a = 42; } + static get #c() { return S.#b(); } +} + +// @filename: tslib.d.ts +// these are pre-TS4.3 versions of emit helpers, which only supported private instance fields +export declare function __classPrivateFieldGet(receiver: T, state: any): V; +export declare function __classPrivateFieldSet(receiver: T, state: any, value: V): V; From 93a7ca3e5a8f0c4e870af43843baa53f01aa7c0d Mon Sep 17 00:00:00 2001 From: Kubilay Kahveci Date: Tue, 23 Mar 2021 16:06:49 +0000 Subject: [PATCH 3/3] fix setter-only compound assignment --- src/compiler/checker.ts | 2 +- .../privateWriteOnlyAccessorRead.errors.txt | 22 +++++---- .../reference/privateWriteOnlyAccessorRead.js | 8 +++- .../privateWriteOnlyAccessorRead.symbols | 46 +++++++++++-------- .../privateWriteOnlyAccessorRead.types | 10 ++++ .../privateWriteOnlyAccessorRead.ts | 3 ++ 6 files changed, 61 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bb1ac6a715b6f..5e9ac6f054e7d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -26823,7 +26823,7 @@ namespace ts { } else { const isSetonlyAccessor = prop && prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor); - if (isSetonlyAccessor && !isAssignmentTarget(node)) { + if (isSetonlyAccessor && assignmentKind !== AssignmentKind.Definite) { error(node, Diagnostics.Private_accessor_was_defined_without_a_getter); } } diff --git a/tests/baselines/reference/privateWriteOnlyAccessorRead.errors.txt b/tests/baselines/reference/privateWriteOnlyAccessorRead.errors.txt index 47534c030719a..10153c7f55259 100644 --- a/tests/baselines/reference/privateWriteOnlyAccessorRead.errors.txt +++ b/tests/baselines/reference/privateWriteOnlyAccessorRead.errors.txt @@ -1,17 +1,19 @@ -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(8,17): error TS2806: Private accessor was defined without a getter. -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(11,5): error TS2806: Private accessor was defined without a getter. -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(16,13): error TS2806: Private accessor was defined without a getter. -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(18,17): error TS2806: Private accessor was defined without a getter. -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(21,18): error TS2806: Private accessor was defined without a getter. -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(25,9): error TS2806: Private accessor was defined without a getter. -tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(26,12): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(9,17): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(12,5): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(17,13): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(19,17): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(22,18): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(26,9): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(27,12): error TS2806: Private accessor was defined without a getter. +tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts(30,5): error TS2806: Private accessor was defined without a getter. -==== tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts (7 errors) ==== +==== tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts (8 errors) ==== class Test { set #value(v: { foo: { bar: number } }) {} set #valueRest(v: number[]) {} set #valueOne(v: number) {} + set #valueCompound(v: number) {} m() { const foo = { bar: 1 }; @@ -49,6 +51,10 @@ tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRea ~~~~~~~~~~~~~~~ !!! error TS2806: Private accessor was defined without a getter. ]; + + this.#valueCompound += 3; + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2806: Private accessor was defined without a getter. } } new Test().m(); diff --git a/tests/baselines/reference/privateWriteOnlyAccessorRead.js b/tests/baselines/reference/privateWriteOnlyAccessorRead.js index 0f4fce73b4130..bd92aaf7e8aee 100644 --- a/tests/baselines/reference/privateWriteOnlyAccessorRead.js +++ b/tests/baselines/reference/privateWriteOnlyAccessorRead.js @@ -3,6 +3,7 @@ class Test { set #value(v: { foo: { bar: number } }) {} set #valueRest(v: number[]) {} set #valueOne(v: number) {} + set #valueCompound(v: number) {} m() { const foo = { bar: 1 }; @@ -26,6 +27,8 @@ class Test { this.#valueOne, ...this.#valueRest ]; + + this.#valueCompound += 3; } } new Test().m(); @@ -54,7 +57,7 @@ var __rest = (this && this.__rest) || function (s, e) { } return t; }; -var _Test_instances, _Test_value_set, _Test_valueRest_set, _Test_valueOne_set; +var _Test_instances, _Test_value_set, _Test_valueRest_set, _Test_valueOne_set, _Test_valueCompound_set; class Test { constructor() { _Test_instances.add(this); @@ -81,7 +84,8 @@ class Test { __classPrivateFieldGet(this, _Test_instances, "a"), ...__classPrivateFieldGet(this, _Test_instances, "a") ]; + __classPrivateFieldSet(this, _Test_instances, __classPrivateFieldGet(this, _Test_instances, "a") + 3, "a", _Test_valueCompound_set); } } -_Test_instances = new WeakSet(), _Test_value_set = function _Test_value_set(v) { }, _Test_valueRest_set = function _Test_valueRest_set(v) { }, _Test_valueOne_set = function _Test_valueOne_set(v) { }; +_Test_instances = new WeakSet(), _Test_value_set = function _Test_value_set(v) { }, _Test_valueRest_set = function _Test_valueRest_set(v) { }, _Test_valueOne_set = function _Test_valueOne_set(v) { }, _Test_valueCompound_set = function _Test_valueCompound_set(v) { }; new Test().m(); diff --git a/tests/baselines/reference/privateWriteOnlyAccessorRead.symbols b/tests/baselines/reference/privateWriteOnlyAccessorRead.symbols index a140e67fee604..d422e533c316c 100644 --- a/tests/baselines/reference/privateWriteOnlyAccessorRead.symbols +++ b/tests/baselines/reference/privateWriteOnlyAccessorRead.symbols @@ -16,12 +16,16 @@ class Test { >#valueOne : Symbol(Test.#valueOne, Decl(privateWriteOnlyAccessorRead.ts, 2, 32)) >v : Symbol(v, Decl(privateWriteOnlyAccessorRead.ts, 3, 16)) + set #valueCompound(v: number) {} +>#valueCompound : Symbol(Test.#valueCompound, Decl(privateWriteOnlyAccessorRead.ts, 3, 29)) +>v : Symbol(v, Decl(privateWriteOnlyAccessorRead.ts, 4, 21)) + m() { ->m : Symbol(Test.m, Decl(privateWriteOnlyAccessorRead.ts, 3, 29)) +>m : Symbol(Test.m, Decl(privateWriteOnlyAccessorRead.ts, 4, 34)) const foo = { bar: 1 }; ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 6, 9)) ->bar : Symbol(bar, Decl(privateWriteOnlyAccessorRead.ts, 6, 17)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 7, 9)) +>bar : Symbol(bar, Decl(privateWriteOnlyAccessorRead.ts, 7, 17)) console.log(this.#value); // error >console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) @@ -33,54 +37,54 @@ class Test { this.#value = { foo }; // ok >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 8, 19)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 9, 19)) this.#value = { foo }; // ok >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 9, 19)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 10, 19)) this.#value.foo = foo; // error >this.#value.foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 1, 17)) >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) >foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 1, 17)) ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 6, 9)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 7, 9)) ({ o: this.#value } = { o: { foo } }); //ok ->o : Symbol(o, Decl(privateWriteOnlyAccessorRead.ts, 12, 6)) +>o : Symbol(o, Decl(privateWriteOnlyAccessorRead.ts, 13, 6)) >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) ->o : Symbol(o, Decl(privateWriteOnlyAccessorRead.ts, 12, 27)) ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 12, 32)) +>o : Symbol(o, Decl(privateWriteOnlyAccessorRead.ts, 13, 27)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 13, 32)) ({ ...this.#value } = { foo }); //ok >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 13, 27)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 14, 27)) ({ foo: this.#value.foo } = { foo }); //error ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 15, 6)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 16, 6)) >this.#value.foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 1, 17)) >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) >foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 1, 17)) ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 15, 33)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 16, 33)) ({ foo: { ...this.#value.foo }, ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 16, 6)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 17, 6)) >this.#value.foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 1, 17)) >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) >foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 1, 17)) } = { foo }); //error ->foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 18, 9)) +>foo : Symbol(foo, Decl(privateWriteOnlyAccessorRead.ts, 19, 9)) let r = { o: this.#value }; //error ->r : Symbol(r, Decl(privateWriteOnlyAccessorRead.ts, 20, 7)) ->o : Symbol(o, Decl(privateWriteOnlyAccessorRead.ts, 20, 13)) +>r : Symbol(r, Decl(privateWriteOnlyAccessorRead.ts, 21, 7)) +>o : Symbol(o, Decl(privateWriteOnlyAccessorRead.ts, 21, 13)) >this.#value : Symbol(Test.#value, Decl(privateWriteOnlyAccessorRead.ts, 0, 12)) >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) @@ -91,7 +95,7 @@ class Test { >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) let arr = [ ->arr : Symbol(arr, Decl(privateWriteOnlyAccessorRead.ts, 23, 7)) +>arr : Symbol(arr, Decl(privateWriteOnlyAccessorRead.ts, 24, 7)) this.#valueOne, >this.#valueOne : Symbol(Test.#valueOne, Decl(privateWriteOnlyAccessorRead.ts, 2, 32)) @@ -102,10 +106,14 @@ class Test { >this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) ]; + + this.#valueCompound += 3; +>this.#valueCompound : Symbol(Test.#valueCompound, Decl(privateWriteOnlyAccessorRead.ts, 3, 29)) +>this : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) } } new Test().m(); ->new Test().m : Symbol(Test.m, Decl(privateWriteOnlyAccessorRead.ts, 3, 29)) +>new Test().m : Symbol(Test.m, Decl(privateWriteOnlyAccessorRead.ts, 4, 34)) >Test : Symbol(Test, Decl(privateWriteOnlyAccessorRead.ts, 0, 0)) ->m : Symbol(Test.m, Decl(privateWriteOnlyAccessorRead.ts, 3, 29)) +>m : Symbol(Test.m, Decl(privateWriteOnlyAccessorRead.ts, 4, 34)) diff --git a/tests/baselines/reference/privateWriteOnlyAccessorRead.types b/tests/baselines/reference/privateWriteOnlyAccessorRead.types index cb2b1d22f9668..23e62fda4c6d9 100644 --- a/tests/baselines/reference/privateWriteOnlyAccessorRead.types +++ b/tests/baselines/reference/privateWriteOnlyAccessorRead.types @@ -14,6 +14,10 @@ class Test { set #valueOne(v: number) {} >#valueOne : number +>v : number + + set #valueCompound(v: number) {} +>#valueCompound : number >v : number m() { @@ -139,6 +143,12 @@ class Test { >this : this ]; + + this.#valueCompound += 3; +>this.#valueCompound += 3 : number +>this.#valueCompound : number +>this : this +>3 : 3 } } new Test().m(); diff --git a/tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts b/tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts index ab71685f053d2..e30ed282df94b 100644 --- a/tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts +++ b/tests/cases/conformance/classes/members/privateNames/privateWriteOnlyAccessorRead.ts @@ -3,6 +3,7 @@ class Test { set #value(v: { foo: { bar: number } }) {} set #valueRest(v: number[]) {} set #valueOne(v: number) {} + set #valueCompound(v: number) {} m() { const foo = { bar: 1 }; @@ -26,6 +27,8 @@ class Test { this.#valueOne, ...this.#valueRest ]; + + this.#valueCompound += 3; } } new Test().m();