From 170ef9c1925eafeed06d94f7c2233ea2a063ab7f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 6 Jun 2022 22:02:09 +0200 Subject: [PATCH] Fix compound assignment not assigning in expressions --- .../visitors/binary-expression/compound.ts | 47 ++++++------------- test/unit/assignments.spec.ts | 15 +++++- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 76947ede9..44c492505 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -76,7 +76,7 @@ export function transformCompoundAssignment( context.transformExpression(rhs) ); - if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) { + if (lua.isTableIndexExpression(left)) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects // local __obj, __index = ${objExpression}, ${indexExpression}; const obj = context.createTempNameForLuaExpression(left.table); @@ -105,6 +105,20 @@ export function transformCompoundAssignment( result: tmp, }; } else { + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return { + statements: [ + objAndIndexDeclaration, + ...transformSetterSkippingCompoundAssignment( + accessExpression, + operator, + right, + rightPrecedingStatements + ), + ], + result: left, + }; + } // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; // ____obj[____index] = ____tmp; // return ____tmp @@ -145,37 +159,6 @@ export function transformCompoundAssignment( rightPrecedingStatements ); return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier }; - } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { - // Simple property/element access expressions need to cache in temp to avoid double-evaluation - // local ____tmp = ${left} ${replacementOperator} ${right}; - // ${left} = ____tmp; - // return ____tmp - const tmpIdentifier = context.createTempNameForLuaExpression(left); - const [precedingStatements, operatorExpression] = transformBinaryOperation( - context, - left, - right, - rightPrecedingStatements, - operator, - expression - ); - const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); - - if (isSetterSkippingCompoundAssignmentOperator(operator)) { - const statements = [ - tmpDeclaration, - ...transformSetterSkippingCompoundAssignment(tmpIdentifier, operator, right, precedingStatements), - ]; - return { statements, result: tmpIdentifier }; - } - - const assignStatements = transformAssignmentWithRightPrecedingStatements( - context, - lhs, - tmpIdentifier, - precedingStatements - ); - return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else { if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) { return { diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 71a7503e2..398f0513b 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -135,6 +135,17 @@ test.each([ `.expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1277 +test("Compound assignment as expression (#1277)", () => { + util.testFunction` + let foo = { + bar: false as any + } + const result = foo.bar ||= true; + return { result, foo }; + `.expectToMatchJsResult(); +}); + test.each([ "++o.p", "o.p++", @@ -417,7 +428,7 @@ test.each([ * x.y ||= z is translated to x.y || (x.y = z). * x.y &&= z is translated to x.y && (x.y = z). * x.y ||= z is translated to x.y !== undefined && (x.y = z). - + Test if setter in Lua is called same nr of times as in JS. */ util.testModule` @@ -449,7 +460,7 @@ test.each([ * x.y ||= z is translated to x.y || (x.y = z). * x.y &&= z is translated to x.y && (x.y = z). * x.y ||= z is translated to x.y !== undefined && (x.y = z). - + Test if setter in Lua is called same nr of times as in JS. */ util.testModule`