From 0966fdb90f3839c70af6833cbe23e7f72925c228 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Wed, 22 Mar 2023 12:56:38 +0200 Subject: [PATCH] fix(53347): omit parenthesis in left assignment --- src/compiler/transformers/classFields.ts | 8 ++- ...ivateNameFieldParenthesisLeftAssignment.js | 53 ++++++++++++++ ...NameFieldParenthesisLeftAssignment.symbols | 57 +++++++++++++++ ...teNameFieldParenthesisLeftAssignment.types | 72 +++++++++++++++++++ ...ivateNameFieldParenthesisLeftAssignment.ts | 25 +++++++ 5 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.js create mode 100644 tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.symbols create mode 100644 tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.types create mode 100644 tests/cases/conformance/classes/members/privateNames/privateNameFieldParenthesisLeftAssignment.ts diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index d604a1845100e..2d04a305d424a 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -156,6 +156,7 @@ import { nodeIsSynthesized, ObjectLiteralElement, OmittedExpression, + OuterExpressionKinds, ParameterDeclaration, ParenthesizedExpression, PartiallyEmittedExpression, @@ -1489,13 +1490,14 @@ export function transformClassFields(context: TransformationContext): (x: Source return factory.updateBinaryExpression(node, left, node.operatorToken, right); } - if (isPrivateIdentifierPropertyAccessExpression(node.left)) { + const left = skipOuterExpressions(node.left, OuterExpressionKinds.PartiallyEmittedExpressions | OuterExpressionKinds.Parentheses); + if (isPrivateIdentifierPropertyAccessExpression(left)) { // obj.#x = ... - const info = accessPrivateIdentifier(node.left.name); + const info = accessPrivateIdentifier(left.name); if (info) { return setTextRange( setOriginalNode( - createPrivateIdentifierAssignment(info, node.left.expression, node.right, node.operatorToken.kind), + createPrivateIdentifierAssignment(info, left.expression, node.right, node.operatorToken.kind), node ), node diff --git a/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.js b/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.js new file mode 100644 index 0000000000000..3e4e464c65a8f --- /dev/null +++ b/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.js @@ -0,0 +1,53 @@ +//// [privateNameFieldParenthesisLeftAssignment.ts] +class Foo { + #p: number; + + constructor(value: number) { + this.#p = value; + } + + t1(p: number) { + (this.#p as number) = p; + } + + t2(p: number) { + (((this.#p as number))) = p; + } + + t3(p: number) { + (this.#p) = p; + } + + t4(p: number) { + (((this.#p))) = p; + } +} + + +//// [privateNameFieldParenthesisLeftAssignment.js] +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var _Foo_p; +class Foo { + constructor(value) { + _Foo_p.set(this, void 0); + __classPrivateFieldSet(this, _Foo_p, value, "f"); + } + t1(p) { + __classPrivateFieldSet(this, _Foo_p, p, "f"); + } + t2(p) { + __classPrivateFieldSet(this, _Foo_p, p, "f"); + } + t3(p) { + __classPrivateFieldSet(this, _Foo_p, p, "f"); + } + t4(p) { + __classPrivateFieldSet(this, _Foo_p, p, "f"); + } +} +_Foo_p = new WeakMap(); diff --git a/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.symbols b/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.symbols new file mode 100644 index 0000000000000..c8e238ad913c2 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.symbols @@ -0,0 +1,57 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldParenthesisLeftAssignment.ts === +class Foo { +>Foo : Symbol(Foo, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 0)) + + #p: number; +>#p : Symbol(Foo.#p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 11)) + + constructor(value: number) { +>value : Symbol(value, Decl(privateNameFieldParenthesisLeftAssignment.ts, 3, 16)) + + this.#p = value; +>this.#p : Symbol(Foo.#p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 11)) +>this : Symbol(Foo, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 0)) +>value : Symbol(value, Decl(privateNameFieldParenthesisLeftAssignment.ts, 3, 16)) + } + + t1(p: number) { +>t1 : Symbol(Foo.t1, Decl(privateNameFieldParenthesisLeftAssignment.ts, 5, 5)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 7, 7)) + + (this.#p as number) = p; +>this.#p : Symbol(Foo.#p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 11)) +>this : Symbol(Foo, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 0)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 7, 7)) + } + + t2(p: number) { +>t2 : Symbol(Foo.t2, Decl(privateNameFieldParenthesisLeftAssignment.ts, 9, 5)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 11, 7)) + + (((this.#p as number))) = p; +>this.#p : Symbol(Foo.#p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 11)) +>this : Symbol(Foo, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 0)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 11, 7)) + } + + t3(p: number) { +>t3 : Symbol(Foo.t3, Decl(privateNameFieldParenthesisLeftAssignment.ts, 13, 5)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 15, 7)) + + (this.#p) = p; +>this.#p : Symbol(Foo.#p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 11)) +>this : Symbol(Foo, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 0)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 15, 7)) + } + + t4(p: number) { +>t4 : Symbol(Foo.t4, Decl(privateNameFieldParenthesisLeftAssignment.ts, 17, 5)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 19, 7)) + + (((this.#p))) = p; +>this.#p : Symbol(Foo.#p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 11)) +>this : Symbol(Foo, Decl(privateNameFieldParenthesisLeftAssignment.ts, 0, 0)) +>p : Symbol(p, Decl(privateNameFieldParenthesisLeftAssignment.ts, 19, 7)) + } +} + diff --git a/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.types b/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.types new file mode 100644 index 0000000000000..a5f8eb122aff8 --- /dev/null +++ b/tests/baselines/reference/privateNameFieldParenthesisLeftAssignment.types @@ -0,0 +1,72 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameFieldParenthesisLeftAssignment.ts === +class Foo { +>Foo : Foo + + #p: number; +>#p : number + + constructor(value: number) { +>value : number + + this.#p = value; +>this.#p = value : number +>this.#p : number +>this : this +>value : number + } + + t1(p: number) { +>t1 : (p: number) => void +>p : number + + (this.#p as number) = p; +>(this.#p as number) = p : number +>(this.#p as number) : number +>this.#p as number : number +>this.#p : number +>this : this +>p : number + } + + t2(p: number) { +>t2 : (p: number) => void +>p : number + + (((this.#p as number))) = p; +>(((this.#p as number))) = p : number +>(((this.#p as number))) : number +>((this.#p as number)) : number +>(this.#p as number) : number +>this.#p as number : number +>this.#p : number +>this : this +>p : number + } + + t3(p: number) { +>t3 : (p: number) => void +>p : number + + (this.#p) = p; +>(this.#p) = p : number +>(this.#p) : number +>this.#p : number +>this : this +>p : number + } + + t4(p: number) { +>t4 : (p: number) => void +>p : number + + (((this.#p))) = p; +>(((this.#p))) = p : number +>(((this.#p))) : number +>((this.#p)) : number +>(this.#p) : number +>this.#p : number +>this : this +>p : number + } +} + diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameFieldParenthesisLeftAssignment.ts b/tests/cases/conformance/classes/members/privateNames/privateNameFieldParenthesisLeftAssignment.ts new file mode 100644 index 0000000000000..b43e3cc65a770 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameFieldParenthesisLeftAssignment.ts @@ -0,0 +1,25 @@ +// @target: es2015 + +class Foo { + #p: number; + + constructor(value: number) { + this.#p = value; + } + + t1(p: number) { + (this.#p as number) = p; + } + + t2(p: number) { + (((this.#p as number))) = p; + } + + t3(p: number) { + (this.#p) = p; + } + + t4(p: number) { + (((this.#p))) = p; + } +}