From f617bbae4ca9073e964044da88d8a448ad21757d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 25 Feb 2023 13:44:33 +0100 Subject: [PATCH 1/3] Fix exception when unwrapping parenthesised multireturn calls --- .../visitors/language-extensions/multi.ts | 21 ++++++++++--------- test/unit/language-extensions/multi.spec.ts | 11 ++++++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 73dec6d9c..6556d0af7 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -6,7 +6,7 @@ import { IterableExtensionKind, } from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { findFirstNodeAbove } from "../../utils/typescript"; +import { findFirstNodeAbove, findFirstNonOuterParent } from "../../utils/typescript"; const multiReturnExtensionName = "__tstlMultiReturn"; export function isMultiReturnType(type: ts.Type): boolean { @@ -59,45 +59,46 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n } // Variable declaration with destructuring - if (ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) { + const parent = findFirstNonOuterParent(node); + if (ts.isVariableDeclaration(parent) && ts.isArrayBindingPattern(parent.name)) { return false; } // Variable assignment with destructuring if ( - ts.isBinaryExpression(node.parent) && - node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && - ts.isArrayLiteralExpression(node.parent.left) + ts.isBinaryExpression(parent) && + parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isArrayLiteralExpression(parent.left) ) { return false; } // Spread operator - if (ts.isSpreadElement(node.parent)) { + if (ts.isSpreadElement(parent)) { return false; } // Stand-alone expression - if (ts.isExpressionStatement(node.parent)) { + if (ts.isExpressionStatement(parent)) { return false; } // Forwarded multi-return call if ( - (ts.isReturnStatement(node.parent) || ts.isArrowFunction(node.parent)) && // Body-less arrow func + (ts.isReturnStatement(parent) || ts.isArrowFunction(parent)) && // Body-less arrow func isInMultiReturnFunction(context, node) ) { return false; } // Element access expression 'foo()[0]' will be optimized using 'select' - if (ts.isElementAccessExpression(node.parent)) { + if (ts.isElementAccessExpression(parent)) { return false; } // LuaIterable in for...of if ( - ts.isForOfStatement(node.parent) && + ts.isForOfStatement(parent) && getIterableExtensionKindForNode(context, node) === IterableExtensionKind.Iterable ) { return false; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index ed7213b2b..6cad108a7 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -327,3 +327,14 @@ test("return LuaMultiReturn from catch", () => { .withLanguageExtensions() .expectToEqual(2); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1404 +test("LuaMultiReturn applies after casting a functtion (#1404)", () => { + util.testFunction` + let swap: any = (a: number, b: number) => $multi(b, a); + let [a, b] = (swap as (...args: any) => LuaMultiReturn<[number, number]>)(4, 3); + return [a, b]; + ` + .withLanguageExtensions() + .expectToEqual([3, 4]); +}); From 5020aa73707bd1c76209de358cdcc192dcb55d4e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 25 Feb 2023 13:46:21 +0100 Subject: [PATCH 2/3] reorder --- src/transformation/visitors/language-extensions/multi.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 6556d0af7..d9d7cbc02 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -58,8 +58,9 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n return false; } - // Variable declaration with destructuring const parent = findFirstNonOuterParent(node); + + // Variable declaration with destructuring if (ts.isVariableDeclaration(parent) && ts.isArrayBindingPattern(parent.name)) { return false; } From 8d1bed5a92b429899e7a29862f0cbcc291a60ac0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 25 Feb 2023 14:12:10 +0100 Subject: [PATCH 3/3] Update test/unit/language-extensions/multi.spec.ts Co-authored-by: hazzard993 --- test/unit/language-extensions/multi.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 6cad108a7..3350876e8 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -329,7 +329,7 @@ test("return LuaMultiReturn from catch", () => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1404 -test("LuaMultiReturn applies after casting a functtion (#1404)", () => { +test("LuaMultiReturn applies after casting a function (#1404)", () => { util.testFunction` let swap: any = (a: number, b: number) => $multi(b, a); let [a, b] = (swap as (...args: any) => LuaMultiReturn<[number, number]>)(4, 3);