Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions tsc/internal/transformers/estransforms/exponentiation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
(<number>getObject()[++key]) ||= 1;
((getObject()[++key]) as number)! ||= 1;
(getObject()[++key]) ||= 1;

getObject().x! ||= 1;
(getObject().x as number) ||= 1;
(getObject().x satisfies number) ||= 1;
(<number>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;
(<number>getObject()[++key]) &&= 1;
((getObject()[++key]) as number)! &&= 1;
(getObject()[++key]) &&= 1;

getObject().x! &&= 1;
(getObject().x as number) &&= 1;
(getObject().x satisfies number) &&= 1;
(<number>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;
(<number>getObject()[++key]) ??= 1;
((getObject()[++key]) as number)! ??= 1;
(getObject()[++key]) ??= 1;

getObject().x! ??= 1;
(getObject().x as number) ??= 1;
(getObject().x satisfies number) ??= 1;
(<number>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;
(<number>getObject()[++key]) **= 2;
((getObject()[++key]) as number)! **= 2;
(getObject()[++key]) **= 2;

getObject().x! **= 2;
(getObject().x as number) **= 2;
(getObject().x satisfies number) **= 2;
(<number>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;
(<number>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;
(<number>super.x) **= 2;
((super.x) as number)! **= 2;
(super.x) **= 2;

super[getKey()]! **= 2;
(super[getKey()] as number) **= 2;
(super[getKey()] satisfies number) **= 2;
(<number>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);
}
}
Loading
Loading