diff --git a/tsc/internal/transformers/estransforms/exponentiation.go b/tsc/internal/transformers/estransforms/exponentiation.go index c1cf0c5a0b7c8..2d850ecb380cb 100644 --- a/tsc/internal/transformers/estransforms/exponentiation.go +++ b/tsc/internal/transformers/estransforms/exponentiation.go @@ -34,17 +34,25 @@ func (ch *exponentiationTransformer) visitBinaryExpression(node *ast.BinaryExpre func (ch *exponentiationTransformer) visitExponentiationAssignmentExpression(node *ast.BinaryExpression) *ast.Node { var target *ast.Node var value *ast.Node - left := ch.Visitor().VisitNode(node.Left) + left := ast.SkipOuterExpressions(ch.Visitor().VisitNode(node.Left), ast.OEKParentheses|ast.OEKPartiallyEmittedExpressions) right := ch.Visitor().VisitNode(node.Right) + var expressionTemp *ast.Node + var objExpr *ast.Node + if ast.IsAccessExpression(left) { + expressionTemp = left.Expression() + objExpr = expressionTemp + if expressionTemp.Kind != ast.KindSuperKeyword { + expressionTemp = ch.Factory().NewTempVariable() + ch.EmitContext().AddVariableDeclaration(expressionTemp) + objExpr = ch.Factory().NewAssignmentExpression(expressionTemp, left.Expression()) + objExpr.Loc = left.Expression().Loc + } + } if ast.IsElementAccessExpression(left) { // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)` - expressionTemp := ch.Factory().NewTempVariable() - ch.EmitContext().AddVariableDeclaration(expressionTemp) argumentExpressionTemp := ch.Factory().NewTempVariable() ch.EmitContext().AddVariableDeclaration(argumentExpressionTemp) - objExpr := ch.Factory().NewAssignmentExpression(expressionTemp, left.Expression()) - objExpr.Loc = left.Expression().Loc accessExpr := ch.Factory().NewAssignmentExpression(argumentExpressionTemp, left.AsElementAccessExpression().ArgumentExpression) accessExpr.Loc = left.AsElementAccessExpression().ArgumentExpression.Loc @@ -54,11 +62,7 @@ func (ch *exponentiationTransformer) visitExponentiationAssignmentExpression(nod value.Loc = left.Loc } else if ast.IsPropertyAccessExpression(left) { // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)` - expressionTemp := ch.Factory().NewTempVariable() - ch.EmitContext().AddVariableDeclaration(expressionTemp) - assignment := ch.Factory().NewAssignmentExpression(expressionTemp, left.Expression()) - assignment.Loc = left.Expression().Loc - target = ch.Factory().NewPropertyAccessExpression(assignment, nil, left.Name(), ast.NodeFlagsNone) + target = ch.Factory().NewPropertyAccessExpression(objExpr, nil, left.Name(), ast.NodeFlagsNone) target.Loc = left.Loc value = ch.Factory().NewPropertyAccessExpression(expressionTemp, nil, left.Name(), ast.NodeFlagsNone) diff --git a/tsc/internal/transformers/estransforms/logicalassignment.go b/tsc/internal/transformers/estransforms/logicalassignment.go index 7cf03fc0183e4..a92a5c4c2042b 100644 --- a/tsc/internal/transformers/estransforms/logicalassignment.go +++ b/tsc/internal/transformers/estransforms/logicalassignment.go @@ -34,7 +34,7 @@ func (ch *logicalAssignmentTransformer) visitBinaryExpression(node *ast.BinaryEx return ch.Visitor().VisitEachChild(node.AsNode()) } - left := ast.SkipParentheses(ch.Visitor().VisitNode(node.Left)) + left := ast.SkipOuterExpressions(ch.Visitor().VisitNode(node.Left), ast.OEKParentheses|ast.OEKPartiallyEmittedExpressions) assignmentTarget := left right := ast.SkipParentheses(ch.Visitor().VisitNode(node.Right)) diff --git a/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2015).js b/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2015).js new file mode 100644 index 0000000000000..e60ebacce39c6 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2015).js @@ -0,0 +1,200 @@ +//// [tests/cases/compiler/compoundAssignmentWithTypeOnlyExpressions.ts] //// + +//// [compoundAssignmentWithTypeOnlyExpressions.ts] +declare function getObject(): { x: number; [key: number]: number }; +let key = 0; + +function logicalOrAssignment() { + getObject()[++key]! ||= 1; + (getObject()[++key] as number) ||= 1; + (getObject()[++key] satisfies number) ||= 1; + (getObject()[++key]) ||= 1; + ((getObject()[++key]) as number)! ||= 1; + (getObject()[++key]) ||= 1; + + getObject().x! ||= 1; + (getObject().x as number) ||= 1; + (getObject().x satisfies number) ||= 1; + (getObject().x) ||= 1; + ((getObject().x) as number)! ||= 1; + (getObject().x) ||= 1; +} + +function logicalAndAssignment() { + getObject()[++key]! &&= 1; + (getObject()[++key] as number) &&= 1; + (getObject()[++key] satisfies number) &&= 1; + (getObject()[++key]) &&= 1; + ((getObject()[++key]) as number)! &&= 1; + (getObject()[++key]) &&= 1; + + getObject().x! &&= 1; + (getObject().x as number) &&= 1; + (getObject().x satisfies number) &&= 1; + (getObject().x) &&= 1; + ((getObject().x) as number)! &&= 1; + (getObject().x) &&= 1; +} + +function nullishAssignment() { + getObject()[++key]! ??= 1; + (getObject()[++key] as number) ??= 1; + (getObject()[++key] satisfies number) ??= 1; + (getObject()[++key]) ??= 1; + ((getObject()[++key]) as number)! ??= 1; + (getObject()[++key]) ??= 1; + + getObject().x! ??= 1; + (getObject().x as number) ??= 1; + (getObject().x satisfies number) ??= 1; + (getObject().x) ??= 1; + ((getObject().x) as number)! ??= 1; + (getObject().x) ??= 1; +} + +function exponentiationAssignment() { + getObject()[++key]! **= 2; + (getObject()[++key] as number) **= 2; + (getObject()[++key] satisfies number) **= 2; + (getObject()[++key]) **= 2; + ((getObject()[++key]) as number)! **= 2; + (getObject()[++key]) **= 2; + + getObject().x! **= 2; + (getObject().x as number) **= 2; + (getObject().x satisfies number) **= 2; + (getObject().x) **= 2; + ((getObject().x) as number)! **= 2; + (getObject().x) **= 2; +} + +declare function getKey(): "x"; + +class Base { + get x() { return 2; } + set x(value: number) {} +} + +class Derived extends Base { + logicalAssignment() { + super.x! ||= 1; + (super.x as number) &&= 1; + (super.x satisfies number) ??= 1; + (super[getKey()]) ||= 1; + super[getKey()]! &&= 1; + (super[getKey()] as number) ??= 1; + } + + exponentiationAssignment() { + super.x! **= 2; + (super.x as number) **= 2; + (super.x satisfies number) **= 2; + (super.x) **= 2; + ((super.x) as number)! **= 2; + (super.x) **= 2; + + super[getKey()]! **= 2; + (super[getKey()] as number) **= 2; + (super[getKey()] satisfies number) **= 2; + (super[getKey()]) **= 2; + ((super[getKey()]) as number)! **= 2; + (super[getKey()]) **= 2; + } +} + + +//// [compoundAssignmentWithTypeOnlyExpressions.js] +"use strict"; +let key = 0; +function logicalOrAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; + (_a = getObject())[_b = ++key] || (_a[_b] = 1); + (_c = getObject())[_d = ++key] || (_c[_d] = 1); + (_e = getObject())[_f = ++key] || (_e[_f] = 1); + (_g = getObject())[_h = ++key] || (_g[_h] = 1); + (_j = getObject())[_k = ++key] || (_j[_k] = 1); + (_l = getObject())[_m = ++key] || (_l[_m] = 1); + (_o = getObject()).x || (_o.x = 1); + (_p = getObject()).x || (_p.x = 1); + (_q = getObject()).x || (_q.x = 1); + (_r = getObject()).x || (_r.x = 1); + (_s = getObject()).x || (_s.x = 1); + (_t = getObject()).x || (_t.x = 1); +} +function logicalAndAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; + (_a = getObject())[_b = ++key] && (_a[_b] = 1); + (_c = getObject())[_d = ++key] && (_c[_d] = 1); + (_e = getObject())[_f = ++key] && (_e[_f] = 1); + (_g = getObject())[_h = ++key] && (_g[_h] = 1); + (_j = getObject())[_k = ++key] && (_j[_k] = 1); + (_l = getObject())[_m = ++key] && (_l[_m] = 1); + (_o = getObject()).x && (_o.x = 1); + (_p = getObject()).x && (_p.x = 1); + (_q = getObject()).x && (_q.x = 1); + (_r = getObject()).x && (_r.x = 1); + (_s = getObject()).x && (_s.x = 1); + (_t = getObject()).x && (_t.x = 1); +} +function nullishAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m; + var _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5; + (_a = (_o = getObject())[_p = ++key]) !== null && _a !== void 0 ? _a : (_o[_p] = 1); + (_b = (_q = getObject())[_r = ++key]) !== null && _b !== void 0 ? _b : (_q[_r] = 1); + (_c = (_s = getObject())[_t = ++key]) !== null && _c !== void 0 ? _c : (_s[_t] = 1); + (_d = (_u = getObject())[_v = ++key]) !== null && _d !== void 0 ? _d : (_u[_v] = 1); + (_e = (_w = getObject())[_x = ++key]) !== null && _e !== void 0 ? _e : (_w[_x] = 1); + (_f = (_y = getObject())[_z = ++key]) !== null && _f !== void 0 ? _f : (_y[_z] = 1); + (_g = (_0 = getObject()).x) !== null && _g !== void 0 ? _g : (_0.x = 1); + (_h = (_1 = getObject()).x) !== null && _h !== void 0 ? _h : (_1.x = 1); + (_j = (_2 = getObject()).x) !== null && _j !== void 0 ? _j : (_2.x = 1); + (_k = (_3 = getObject()).x) !== null && _k !== void 0 ? _k : (_3.x = 1); + (_l = (_4 = getObject()).x) !== null && _l !== void 0 ? _l : (_4.x = 1); + (_m = (_5 = getObject()).x) !== null && _m !== void 0 ? _m : (_5.x = 1); +} +function exponentiationAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; + (_a = getObject())[_b = ++key] = Math.pow(_a[_b], 2); + (_c = getObject())[_d = ++key] = Math.pow(_c[_d], 2); + (_e = getObject())[_f = ++key] = Math.pow(_e[_f], 2); + (_g = getObject())[_h = ++key] = Math.pow(_g[_h], 2); + (_j = getObject())[_k = ++key] = Math.pow(_j[_k], 2); + (_l = getObject())[_m = ++key] = Math.pow(_l[_m], 2); + (_o = getObject()).x = Math.pow(_o.x, 2); + (_p = getObject()).x = Math.pow(_p.x, 2); + (_q = getObject()).x = Math.pow(_q.x, 2); + (_r = getObject()).x = Math.pow(_r.x, 2); + (_s = getObject()).x = Math.pow(_s.x, 2); + (_t = getObject()).x = Math.pow(_t.x, 2); +} +class Base { + get x() { return 2; } + set x(value) { } +} +class Derived extends Base { + logicalAssignment() { + var _a, _b; + var _c, _d, _e; + super.x || (super.x = 1); + super.x && (super.x = 1); + (_a = super.x) !== null && _a !== void 0 ? _a : (super.x = 1); + super[_c = getKey()] || (super[_c] = 1); + super[_d = getKey()] && (super[_d] = 1); + (_b = super[_e = getKey()]) !== null && _b !== void 0 ? _b : (super[_e] = 1); + } + exponentiationAssignment() { + var _a, _b, _c, _d, _e, _f; + super.x = Math.pow(super.x, 2); + super.x = Math.pow(super.x, 2); + super.x = Math.pow(super.x, 2); + super.x = Math.pow(super.x, 2); + super.x = Math.pow(super.x, 2); + super.x = Math.pow(super.x, 2); + super[_a = getKey()] = Math.pow(super[_a], 2); + super[_b = getKey()] = Math.pow(super[_b], 2); + super[_c = getKey()] = Math.pow(super[_c], 2); + super[_d = getKey()] = Math.pow(super[_d], 2); + super[_e = getKey()] = Math.pow(super[_e], 2); + super[_f = getKey()] = Math.pow(super[_f], 2); + } +} diff --git a/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2020).js b/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2020).js new file mode 100644 index 0000000000000..070b0ed734328 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2020).js @@ -0,0 +1,196 @@ +//// [tests/cases/compiler/compoundAssignmentWithTypeOnlyExpressions.ts] //// + +//// [compoundAssignmentWithTypeOnlyExpressions.ts] +declare function getObject(): { x: number; [key: number]: number }; +let key = 0; + +function logicalOrAssignment() { + getObject()[++key]! ||= 1; + (getObject()[++key] as number) ||= 1; + (getObject()[++key] satisfies number) ||= 1; + (getObject()[++key]) ||= 1; + ((getObject()[++key]) as number)! ||= 1; + (getObject()[++key]) ||= 1; + + getObject().x! ||= 1; + (getObject().x as number) ||= 1; + (getObject().x satisfies number) ||= 1; + (getObject().x) ||= 1; + ((getObject().x) as number)! ||= 1; + (getObject().x) ||= 1; +} + +function logicalAndAssignment() { + getObject()[++key]! &&= 1; + (getObject()[++key] as number) &&= 1; + (getObject()[++key] satisfies number) &&= 1; + (getObject()[++key]) &&= 1; + ((getObject()[++key]) as number)! &&= 1; + (getObject()[++key]) &&= 1; + + getObject().x! &&= 1; + (getObject().x as number) &&= 1; + (getObject().x satisfies number) &&= 1; + (getObject().x) &&= 1; + ((getObject().x) as number)! &&= 1; + (getObject().x) &&= 1; +} + +function nullishAssignment() { + getObject()[++key]! ??= 1; + (getObject()[++key] as number) ??= 1; + (getObject()[++key] satisfies number) ??= 1; + (getObject()[++key]) ??= 1; + ((getObject()[++key]) as number)! ??= 1; + (getObject()[++key]) ??= 1; + + getObject().x! ??= 1; + (getObject().x as number) ??= 1; + (getObject().x satisfies number) ??= 1; + (getObject().x) ??= 1; + ((getObject().x) as number)! ??= 1; + (getObject().x) ??= 1; +} + +function exponentiationAssignment() { + getObject()[++key]! **= 2; + (getObject()[++key] as number) **= 2; + (getObject()[++key] satisfies number) **= 2; + (getObject()[++key]) **= 2; + ((getObject()[++key]) as number)! **= 2; + (getObject()[++key]) **= 2; + + getObject().x! **= 2; + (getObject().x as number) **= 2; + (getObject().x satisfies number) **= 2; + (getObject().x) **= 2; + ((getObject().x) as number)! **= 2; + (getObject().x) **= 2; +} + +declare function getKey(): "x"; + +class Base { + get x() { return 2; } + set x(value: number) {} +} + +class Derived extends Base { + logicalAssignment() { + super.x! ||= 1; + (super.x as number) &&= 1; + (super.x satisfies number) ??= 1; + (super[getKey()]) ||= 1; + super[getKey()]! &&= 1; + (super[getKey()] as number) ??= 1; + } + + exponentiationAssignment() { + super.x! **= 2; + (super.x as number) **= 2; + (super.x satisfies number) **= 2; + (super.x) **= 2; + ((super.x) as number)! **= 2; + (super.x) **= 2; + + super[getKey()]! **= 2; + (super[getKey()] as number) **= 2; + (super[getKey()] satisfies number) **= 2; + (super[getKey()]) **= 2; + ((super[getKey()]) as number)! **= 2; + (super[getKey()]) **= 2; + } +} + + +//// [compoundAssignmentWithTypeOnlyExpressions.js] +"use strict"; +let key = 0; +function logicalOrAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; + (_a = getObject())[_b = ++key] || (_a[_b] = 1); + (_c = getObject())[_d = ++key] || (_c[_d] = 1); + (_e = getObject())[_f = ++key] || (_e[_f] = 1); + (_g = getObject())[_h = ++key] || (_g[_h] = 1); + (_j = getObject())[_k = ++key] || (_j[_k] = 1); + (_l = getObject())[_m = ++key] || (_l[_m] = 1); + (_o = getObject()).x || (_o.x = 1); + (_p = getObject()).x || (_p.x = 1); + (_q = getObject()).x || (_q.x = 1); + (_r = getObject()).x || (_r.x = 1); + (_s = getObject()).x || (_s.x = 1); + (_t = getObject()).x || (_t.x = 1); +} +function logicalAndAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; + (_a = getObject())[_b = ++key] && (_a[_b] = 1); + (_c = getObject())[_d = ++key] && (_c[_d] = 1); + (_e = getObject())[_f = ++key] && (_e[_f] = 1); + (_g = getObject())[_h = ++key] && (_g[_h] = 1); + (_j = getObject())[_k = ++key] && (_j[_k] = 1); + (_l = getObject())[_m = ++key] && (_l[_m] = 1); + (_o = getObject()).x && (_o.x = 1); + (_p = getObject()).x && (_p.x = 1); + (_q = getObject()).x && (_q.x = 1); + (_r = getObject()).x && (_r.x = 1); + (_s = getObject()).x && (_s.x = 1); + (_t = getObject()).x && (_t.x = 1); +} +function nullishAssignment() { + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t; + (_a = getObject())[_b = ++key] ?? (_a[_b] = 1); + (_c = getObject())[_d = ++key] ?? (_c[_d] = 1); + (_e = getObject())[_f = ++key] ?? (_e[_f] = 1); + (_g = getObject())[_h = ++key] ?? (_g[_h] = 1); + (_j = getObject())[_k = ++key] ?? (_j[_k] = 1); + (_l = getObject())[_m = ++key] ?? (_l[_m] = 1); + (_o = getObject()).x ?? (_o.x = 1); + (_p = getObject()).x ?? (_p.x = 1); + (_q = getObject()).x ?? (_q.x = 1); + (_r = getObject()).x ?? (_r.x = 1); + (_s = getObject()).x ?? (_s.x = 1); + (_t = getObject()).x ?? (_t.x = 1); +} +function exponentiationAssignment() { + getObject()[++key] **= 2; + getObject()[++key] **= 2; + getObject()[++key] **= 2; + getObject()[++key] **= 2; + (getObject()[++key]) **= 2; + (getObject()[++key]) **= 2; + getObject().x **= 2; + getObject().x **= 2; + getObject().x **= 2; + getObject().x **= 2; + (getObject().x) **= 2; + (getObject().x) **= 2; +} +class Base { + get x() { return 2; } + set x(value) { } +} +class Derived extends Base { + logicalAssignment() { + var _a, _b, _c; + super.x || (super.x = 1); + super.x && (super.x = 1); + super.x ?? (super.x = 1); + super[_a = getKey()] || (super[_a] = 1); + super[_b = getKey()] && (super[_b] = 1); + super[_c = getKey()] ?? (super[_c] = 1); + } + exponentiationAssignment() { + super.x **= 2; + super.x **= 2; + super.x **= 2; + super.x **= 2; + (super.x) **= 2; + (super.x) **= 2; + super[getKey()] **= 2; + super[getKey()] **= 2; + super[getKey()] **= 2; + super[getKey()] **= 2; + (super[getKey()]) **= 2; + (super[getKey()]) **= 2; + } +} diff --git a/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2021).js b/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2021).js new file mode 100644 index 0000000000000..ad67cee828975 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/compoundAssignmentWithTypeOnlyExpressions(target=es2021).js @@ -0,0 +1,192 @@ +//// [tests/cases/compiler/compoundAssignmentWithTypeOnlyExpressions.ts] //// + +//// [compoundAssignmentWithTypeOnlyExpressions.ts] +declare function getObject(): { x: number; [key: number]: number }; +let key = 0; + +function logicalOrAssignment() { + getObject()[++key]! ||= 1; + (getObject()[++key] as number) ||= 1; + (getObject()[++key] satisfies number) ||= 1; + (getObject()[++key]) ||= 1; + ((getObject()[++key]) as number)! ||= 1; + (getObject()[++key]) ||= 1; + + getObject().x! ||= 1; + (getObject().x as number) ||= 1; + (getObject().x satisfies number) ||= 1; + (getObject().x) ||= 1; + ((getObject().x) as number)! ||= 1; + (getObject().x) ||= 1; +} + +function logicalAndAssignment() { + getObject()[++key]! &&= 1; + (getObject()[++key] as number) &&= 1; + (getObject()[++key] satisfies number) &&= 1; + (getObject()[++key]) &&= 1; + ((getObject()[++key]) as number)! &&= 1; + (getObject()[++key]) &&= 1; + + getObject().x! &&= 1; + (getObject().x as number) &&= 1; + (getObject().x satisfies number) &&= 1; + (getObject().x) &&= 1; + ((getObject().x) as number)! &&= 1; + (getObject().x) &&= 1; +} + +function nullishAssignment() { + getObject()[++key]! ??= 1; + (getObject()[++key] as number) ??= 1; + (getObject()[++key] satisfies number) ??= 1; + (getObject()[++key]) ??= 1; + ((getObject()[++key]) as number)! ??= 1; + (getObject()[++key]) ??= 1; + + getObject().x! ??= 1; + (getObject().x as number) ??= 1; + (getObject().x satisfies number) ??= 1; + (getObject().x) ??= 1; + ((getObject().x) as number)! ??= 1; + (getObject().x) ??= 1; +} + +function exponentiationAssignment() { + getObject()[++key]! **= 2; + (getObject()[++key] as number) **= 2; + (getObject()[++key] satisfies number) **= 2; + (getObject()[++key]) **= 2; + ((getObject()[++key]) as number)! **= 2; + (getObject()[++key]) **= 2; + + getObject().x! **= 2; + (getObject().x as number) **= 2; + (getObject().x satisfies number) **= 2; + (getObject().x) **= 2; + ((getObject().x) as number)! **= 2; + (getObject().x) **= 2; +} + +declare function getKey(): "x"; + +class Base { + get x() { return 2; } + set x(value: number) {} +} + +class Derived extends Base { + logicalAssignment() { + super.x! ||= 1; + (super.x as number) &&= 1; + (super.x satisfies number) ??= 1; + (super[getKey()]) ||= 1; + super[getKey()]! &&= 1; + (super[getKey()] as number) ??= 1; + } + + exponentiationAssignment() { + super.x! **= 2; + (super.x as number) **= 2; + (super.x satisfies number) **= 2; + (super.x) **= 2; + ((super.x) as number)! **= 2; + (super.x) **= 2; + + super[getKey()]! **= 2; + (super[getKey()] as number) **= 2; + (super[getKey()] satisfies number) **= 2; + (super[getKey()]) **= 2; + ((super[getKey()]) as number)! **= 2; + (super[getKey()]) **= 2; + } +} + + +//// [compoundAssignmentWithTypeOnlyExpressions.js] +"use strict"; +let key = 0; +function logicalOrAssignment() { + getObject()[++key] ||= 1; + getObject()[++key] ||= 1; + getObject()[++key] ||= 1; + getObject()[++key] ||= 1; + (getObject()[++key]) ||= 1; + (getObject()[++key]) ||= 1; + getObject().x ||= 1; + getObject().x ||= 1; + getObject().x ||= 1; + getObject().x ||= 1; + (getObject().x) ||= 1; + (getObject().x) ||= 1; +} +function logicalAndAssignment() { + getObject()[++key] &&= 1; + getObject()[++key] &&= 1; + getObject()[++key] &&= 1; + getObject()[++key] &&= 1; + (getObject()[++key]) &&= 1; + (getObject()[++key]) &&= 1; + getObject().x &&= 1; + getObject().x &&= 1; + getObject().x &&= 1; + getObject().x &&= 1; + (getObject().x) &&= 1; + (getObject().x) &&= 1; +} +function nullishAssignment() { + getObject()[++key] ??= 1; + getObject()[++key] ??= 1; + getObject()[++key] ??= 1; + getObject()[++key] ??= 1; + (getObject()[++key]) ??= 1; + (getObject()[++key]) ??= 1; + getObject().x ??= 1; + getObject().x ??= 1; + getObject().x ??= 1; + getObject().x ??= 1; + (getObject().x) ??= 1; + (getObject().x) ??= 1; +} +function exponentiationAssignment() { + getObject()[++key] **= 2; + getObject()[++key] **= 2; + getObject()[++key] **= 2; + getObject()[++key] **= 2; + (getObject()[++key]) **= 2; + (getObject()[++key]) **= 2; + getObject().x **= 2; + getObject().x **= 2; + getObject().x **= 2; + getObject().x **= 2; + (getObject().x) **= 2; + (getObject().x) **= 2; +} +class Base { + get x() { return 2; } + set x(value) { } +} +class Derived extends Base { + logicalAssignment() { + super.x ||= 1; + super.x &&= 1; + super.x ??= 1; + super[getKey()] ||= 1; + super[getKey()] &&= 1; + super[getKey()] ??= 1; + } + exponentiationAssignment() { + super.x **= 2; + super.x **= 2; + super.x **= 2; + super.x **= 2; + (super.x) **= 2; + (super.x) **= 2; + super[getKey()] **= 2; + super[getKey()] **= 2; + super[getKey()] **= 2; + super[getKey()] **= 2; + (super[getKey()]) **= 2; + (super[getKey()]) **= 2; + } +} diff --git a/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsReference.js b/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsReference.js index 3410267ab5a2f..19b76ccde901e 100644 --- a/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsReference.js +++ b/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsReference.js @@ -30,7 +30,7 @@ function fn2(x4: number) { //// [compoundExponentiationAssignmentLHSIsReference.js] "use strict"; -var _a, _b, _c; +var _a, _b, _c, _d, _e, _f; var value; // identifiers: variable and parameter var x1; @@ -43,9 +43,9 @@ var x3; (_a = x3).a = Math.pow(_a.a, value); (_b = x3)[_c = 'a'] = Math.pow(_b[_c], value); // parentheses, the contained expression is reference -(x1) = Math.pow((x1), value); +x1 = Math.pow(x1, value); function fn2(x4) { - (x4) = Math.pow((x4), value); + x4 = Math.pow(x4, value); } -(x3.a) = Math.pow((x3.a), value); -(x3['a']) = Math.pow((x3['a']), value); +(_d = x3).a = Math.pow(_d.a, value); +(_e = x3)[_f = 'a'] = Math.pow(_e[_f], value); diff --git a/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsValue.js b/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsValue.js index 41d3f079f71a3..cd483011c19b4 100644 --- a/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsValue.js +++ b/tsc/testdata/baselines/reference/conformance/compoundExponentiationAssignmentLHSIsValue.js @@ -135,17 +135,14 @@ value; // super class Derived extends C { constructor() { - var _a; super(); - (_a = super). = Math.pow(_a., value); + super. = Math.pow(super., value); } foo() { - var _a; - (_a = super). = Math.pow(_a., value); + super. = Math.pow(super., value); } static sfoo() { - var _a; - (_a = super). = Math.pow(_a., value); + super. = Math.pow(super., value); } } // function expression @@ -156,17 +153,17 @@ value; // function calls foo() = Math.pow(foo(), value); // parentheses, the containted expression is value -(this) = Math.pow((this), value); -(M) = Math.pow((M), value); -(C) = Math.pow((C), value); -(E) = Math.pow((E), value); -(foo) = Math.pow((foo), value); -(null) = Math.pow((null), value); -(true) = Math.pow((true), value); -(0) = Math.pow((0), value); -('') = Math.pow((''), value); -(/d+/) = Math.pow((/d+/), value); -({}) = Math.pow(({}), value); -([]) = Math.pow(([]), value); -(function baz1() { }) = Math.pow((function baz1() { }), value); -(foo()) = Math.pow((foo()), value); +this = Math.pow(this, value); +M = Math.pow(M, value); +C = Math.pow(C, value); +E = Math.pow(E, value); +foo = Math.pow(foo, value); +null = Math.pow(null, value); +true = Math.pow(true, value); +0 = Math.pow(0, value); +'' = Math.pow('', value); +/d+/ = Math.pow(/d+/, value); +({} = Math.pow({}, value)); +[] = Math.pow([], value); +(function baz1() { } = Math.pow(function baz1() { }, value)); +foo() = Math.pow(foo(), value); diff --git a/tsc/testdata/tests/cases/compiler/compoundAssignmentWithTypeOnlyExpressions.ts b/tsc/testdata/tests/cases/compiler/compoundAssignmentWithTypeOnlyExpressions.ts new file mode 100644 index 0000000000000..3099bd5d0782f --- /dev/null +++ b/tsc/testdata/tests/cases/compiler/compoundAssignmentWithTypeOnlyExpressions.ts @@ -0,0 +1,104 @@ +// @target: es2015, es2020, es2021 +// @strict: true +// @noTypesAndSymbols: true + +declare function getObject(): { x: number; [key: number]: number }; +let key = 0; + +function logicalOrAssignment() { + getObject()[++key]! ||= 1; + (getObject()[++key] as number) ||= 1; + (getObject()[++key] satisfies number) ||= 1; + (getObject()[++key]) ||= 1; + ((getObject()[++key]) as number)! ||= 1; + (getObject()[++key]) ||= 1; + + getObject().x! ||= 1; + (getObject().x as number) ||= 1; + (getObject().x satisfies number) ||= 1; + (getObject().x) ||= 1; + ((getObject().x) as number)! ||= 1; + (getObject().x) ||= 1; +} + +function logicalAndAssignment() { + getObject()[++key]! &&= 1; + (getObject()[++key] as number) &&= 1; + (getObject()[++key] satisfies number) &&= 1; + (getObject()[++key]) &&= 1; + ((getObject()[++key]) as number)! &&= 1; + (getObject()[++key]) &&= 1; + + getObject().x! &&= 1; + (getObject().x as number) &&= 1; + (getObject().x satisfies number) &&= 1; + (getObject().x) &&= 1; + ((getObject().x) as number)! &&= 1; + (getObject().x) &&= 1; +} + +function nullishAssignment() { + getObject()[++key]! ??= 1; + (getObject()[++key] as number) ??= 1; + (getObject()[++key] satisfies number) ??= 1; + (getObject()[++key]) ??= 1; + ((getObject()[++key]) as number)! ??= 1; + (getObject()[++key]) ??= 1; + + getObject().x! ??= 1; + (getObject().x as number) ??= 1; + (getObject().x satisfies number) ??= 1; + (getObject().x) ??= 1; + ((getObject().x) as number)! ??= 1; + (getObject().x) ??= 1; +} + +function exponentiationAssignment() { + getObject()[++key]! **= 2; + (getObject()[++key] as number) **= 2; + (getObject()[++key] satisfies number) **= 2; + (getObject()[++key]) **= 2; + ((getObject()[++key]) as number)! **= 2; + (getObject()[++key]) **= 2; + + getObject().x! **= 2; + (getObject().x as number) **= 2; + (getObject().x satisfies number) **= 2; + (getObject().x) **= 2; + ((getObject().x) as number)! **= 2; + (getObject().x) **= 2; +} + +declare function getKey(): "x"; + +class Base { + get x() { return 2; } + set x(value: number) {} +} + +class Derived extends Base { + logicalAssignment() { + super.x! ||= 1; + (super.x as number) &&= 1; + (super.x satisfies number) ??= 1; + (super[getKey()]) ||= 1; + super[getKey()]! &&= 1; + (super[getKey()] as number) ??= 1; + } + + exponentiationAssignment() { + super.x! **= 2; + (super.x as number) **= 2; + (super.x satisfies number) **= 2; + (super.x) **= 2; + ((super.x) as number)! **= 2; + (super.x) **= 2; + + super[getKey()]! **= 2; + (super[getKey()] as number) **= 2; + (super[getKey()] satisfies number) **= 2; + (super[getKey()]) **= 2; + ((super[getKey()]) as number)! **= 2; + (super[getKey()]) **= 2; + } +}