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
46 changes: 13 additions & 33 deletions src/transformation/visitors/binary-expression/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function transformBinaryOperationWithNoPrecedingStatements(

if (operator === ts.SyntaxKind.QuestionQuestionToken) {
assert(ts.isBinaryExpression(node));
return transformNullishCoalescingExpression(context, node, left, right);
return transformNullishCoalescingOperationNoPrecedingStatements(context, node, left, right);
}

let luaOperator = simpleOperatorsToLua[operator];
Expand Down Expand Up @@ -138,21 +138,7 @@ function transformShortCircuitBinaryExpression(
const [rightPrecedingStatements, rhs] = transformInPrecedingStatementScope(context, () =>
context.transformExpression(node.right)
);
if (rightPrecedingStatements.length > 0) {
return createShortCircuitBinaryExpressionPrecedingStatements(
context,
lhs,
rhs,
rightPrecedingStatements,
operator,
node
);
} else {
return [
rightPrecedingStatements,
transformBinaryOperationWithNoPrecedingStatements(context, lhs, rhs, operator, node),
];
}
return transformBinaryOperation(context, lhs, rhs, rightPrecedingStatements, operator, node);
}

export function transformBinaryOperation(
Expand Down Expand Up @@ -274,7 +260,7 @@ export function transformBinaryExpressionStatement(
}
}

function transformNullishCoalescingExpression(
function transformNullishCoalescingOperationNoPrecedingStatements(
context: TransformationContext,
node: ts.BinaryExpression,
transformedLeft: lua.Expression,
Expand All @@ -287,23 +273,17 @@ function transformNullishCoalescingExpression(
(type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Boolean)) !== 0 ||
(type.flags & ts.TypeFlags.BooleanLiteral & ts.TypeFlags.PossiblyFalsy) !== 0;
if (typeCanSatisfy(context, lhsType, typeCanBeFalse)) {
// lhs can be false, transform to IIFE
const lhsIdentifier = lua.createIdentifier("____lhs");
const nilComparison = lua.createBinaryExpression(
lua.cloneIdentifier(lhsIdentifier),
lua.createNilLiteral(),
lua.SyntaxKind.EqualityOperator
);
// if ____ == nil then return rhs else return ____ end
const ifStatement = lua.createIfStatement(
nilComparison,
lua.createBlock([lua.createReturnStatement([transformedRight])]),
lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])])
);
// (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs)
return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [
// reuse logic from case with preceding statements
const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements(
context,
transformedLeft,
]);
transformedRight,
[],
ts.SyntaxKind.QuestionQuestionToken,
node
);
context.addPrecedingStatements(precedingStatements);
return result;
} else {
// lhs or rhs
return lua.createBinaryExpression(transformedLeft, transformedRight, lua.SyntaxKind.OrOperator, node);
Expand Down
14 changes: 14 additions & 0 deletions test/unit/nullishCoalescing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,17 @@ test("nullish-coalescing operator with side effect rhs", () => {
return [i, undefined ?? incI(), i];
`.expectToMatchJsResult();
});

test("nullish-coalescing operator with vararg", () => {
util.testFunction`

function foo(...args: any[]){
return args
}
function bar(...args: any[]) {
let x: boolean | undefined = false
const y = x ?? foo(...args)
}
return bar(1, 2)
`.expectToMatchJsResult();
});