From 8d586e761d332c8aa35894c6e688096eb0059c92 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 25 Feb 2019 15:33:43 -0700 Subject: [PATCH 1/4] fixes for empty destructuring --- src/LuaTransformer.ts | 27 +++++++++++++++++------ test/unit/assignmentDestructuring.spec.ts | 16 +++++++++++++- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 1fd4e46ff..ed620c9c1 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1673,7 +1673,9 @@ export class LuaTransformer { throw TSTLErrors.ForbiddenEllipsisDestruction(statement); } - const vars = statement.name.elements.map(e => this.transformArrayBindingElement(e)); + const vars = statement.name.elements.length > 0 + ? statement.name.elements.map(e => this.transformArrayBindingElement(e)) + : tstl.createAnnonymousIdentifier(statement.name); // Don't unpack TupleReturn decorated functions if (statement.initializer) { @@ -2448,10 +2450,14 @@ export class LuaTransformer { if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment - const left = expression.left.elements.map(e => this.transformExpression(e)); + const left = expression.left.elements.length > 0 + ? expression.left.elements.map(e => this.transformExpression(e)) + : [tstl.createAnnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.map(e => this.transformExpression(e)); + right = expression.right.elements.length > 0 + ? expression.right.elements.map(e => this.transformExpression(e)) + : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { right = [this.transformExpression(expression.right)]; } else { @@ -2459,7 +2465,7 @@ export class LuaTransformer { } return tstl.createAssignmentStatement( left as tstl.IdentifierOrTableIndexExpression[], - right, + right as tstl.Expression[], expression ); } else { @@ -2479,16 +2485,20 @@ export class LuaTransformer { if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment // (function() local ${tmps} = ${right}; ${left} = ${tmps}; return {${tmps}} end)() - const left = expression.left.elements.map(e => this.transformExpression(e)); + const left = expression.left.elements.length > 0 + ? expression.left.elements.map(e => this.transformExpression(e)) + : [tstl.createAnnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.map(e => this.transformExpression(e)); + right = expression.right.elements.length > 0 + ? expression.right.elements.map(e => this.transformExpression(e)) + : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { right = [this.transformExpression(expression.right)]; } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } - const tmps = expression.left.elements.map((_, i) => tstl.createIdentifier(`____TS_tmp${i}`)); + const tmps = left.map((_, i) => tstl.createIdentifier(`____TS_tmp${i}`)); const statements: tstl.Statement[] = [ tstl.createVariableDeclarationStatement(tmps, right), tstl.createAssignmentStatement(left as tstl.IdentifierOrTableIndexExpression[], tmps), @@ -4130,6 +4140,9 @@ export class LuaTransformer { const fromTypeNode = this.checker.typeToTypeNode(fromType); const toTypeNode = this.checker.typeToTypeNode(toType); + if (!fromTypeNode || !toTypeNode) { + return; + } if ((ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode))) { diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 7f8e10507..d13cc5a12 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -1,4 +1,4 @@ -import { Expect, Test, TestCase } from "alsatian"; +import { Expect, Test, TestCase, FocusTest } from "alsatian"; import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; import * as util from "../src/util"; @@ -37,4 +37,18 @@ export class AssignmentDestructuringTests { // Assert Expect(lua).toBe(`local a, b = unpack(myFunc());`); } + + @FocusTest + @TestCase("function foo(): [] { return []; }; let [] = foo();") + @TestCase("let [] = ['a', 'b', 'c'];") + @TestCase("let [] = [];") + @TestCase("let [] = [] = [];") + @TestCase("function foo(): [] { return []; }; [] = foo();") + @TestCase("[] = ['a', 'b', 'c'];") + @TestCase("[] = [];") + @TestCase("[] = [] = [];") + @Test("Empty destructuring") + public emptyDestructuring(code: string): void { + Expect(() => util.transpileAndExecute(code)).not.toThrow(); + } } From ef5517fa8c46aac58407081223f784511ac957ea Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 25 Feb 2019 15:54:05 -0700 Subject: [PATCH 2/4] cleanup --- src/LuaTransformer.ts | 2 +- test/unit/assignmentDestructuring.spec.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ed620c9c1..31027335c 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2465,7 +2465,7 @@ export class LuaTransformer { } return tstl.createAssignmentStatement( left as tstl.IdentifierOrTableIndexExpression[], - right as tstl.Expression[], + right, expression ); } else { diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index d13cc5a12..c5d8d58c6 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -1,4 +1,4 @@ -import { Expect, Test, TestCase, FocusTest } from "alsatian"; +import { Expect, Test, TestCase } from "alsatian"; import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; import * as util from "../src/util"; @@ -38,7 +38,6 @@ export class AssignmentDestructuringTests { Expect(lua).toBe(`local a, b = unpack(myFunc());`); } - @FocusTest @TestCase("function foo(): [] { return []; }; let [] = foo();") @TestCase("let [] = ['a', 'b', 'c'];") @TestCase("let [] = [];") From c53554810da87e268174220756179aabcfca1a91 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 25 Feb 2019 16:05:05 -0700 Subject: [PATCH 3/4] union destructuring test --- test/unit/assignmentDestructuring.spec.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index c5d8d58c6..186d5eb35 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -46,8 +46,19 @@ export class AssignmentDestructuringTests { @TestCase("[] = ['a', 'b', 'c'];") @TestCase("[] = [];") @TestCase("[] = [] = [];") + @TestCase("[] = [] = [];") @Test("Empty destructuring") public emptyDestructuring(code: string): void { Expect(() => util.transpileAndExecute(code)).not.toThrow(); } + + @Test("Union destructuring") + public unionDestructuring(): void { + const code = + `function foo(): [string] | [] { return ["bar"]; } + let x: string; + [x] = foo(); + return x;`; + Expect(util.transpileAndExecute(code)).toBe("bar"); + } } From 8f38f89a0ed086be3646cedcf5f3a327618bcd9c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 25 Feb 2019 16:06:44 -0700 Subject: [PATCH 4/4] removing duplicate test --- test/unit/assignmentDestructuring.spec.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 186d5eb35..e146dac39 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -46,7 +46,6 @@ export class AssignmentDestructuringTests { @TestCase("[] = ['a', 'b', 'c'];") @TestCase("[] = [];") @TestCase("[] = [] = [];") - @TestCase("[] = [] = [];") @Test("Empty destructuring") public emptyDestructuring(code: string): void { Expect(() => util.transpileAndExecute(code)).not.toThrow();