From 692f87e2daae8a941821b5399f10992692db5694 Mon Sep 17 00:00:00 2001 From: Janne Date: Sat, 28 Jul 2018 02:28:45 +0300 Subject: [PATCH 1/6] Fix variable destructuring compatibility issue for lua 5.1 --- src/Transpiler.ts | 7 +++++-- src/targets/Transpiler.51.ts | 5 ++++- src/targets/Transpiler.52.ts | 4 ++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index 7320fe7d5..b241586a7 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -1286,6 +1286,9 @@ export abstract class LuaTranspiler { return result; } + // Implemented in 5.1 and overridden in 5.2 (and onwards) + public abstract transpileVariableDestructuring(value: string): string; + public transpileVariableDeclaration(node: ts.VariableDeclaration): string { if (ts.isIdentifier(node.name)) { // Find variable identifier @@ -1298,7 +1301,6 @@ export abstract class LuaTranspiler { } } else if (ts.isArrayBindingPattern(node.name)) { // Destructuring type - const value = this.transpileExpression(node.initializer); // Disallow ellipsis destruction if (node.name.elements.some(elem => !ts.isBindingElement(elem) || elem.dotDotDotToken !== undefined)) { @@ -1306,12 +1308,13 @@ export abstract class LuaTranspiler { } const vars = node.name.elements.map(e => this.transpileArrayBindingElement(e)).join(","); + const value = this.transpileExpression(node.initializer); // Don't unpack TupleReturn decorated functions if (tsHelper.isTupleReturnCall(node.initializer, this.checker)) { return `local ${vars}=${value}\n`; } else { - return `local ${vars}=table.unpack(${value})\n`; + return `local ${vars}=${this.transpileVariableDestructuring(value)}\n`; } } else { throw new TranspileError( diff --git a/src/targets/Transpiler.51.ts b/src/targets/Transpiler.51.ts index c63cf6f0a..1bbc3d903 100644 --- a/src/targets/Transpiler.51.ts +++ b/src/targets/Transpiler.51.ts @@ -4,5 +4,8 @@ import { TSHelper as tsHelper } from "../TSHelper"; import * as ts from "typescript"; export class LuaTranspiler51 extends LuaTranspiler { - + /** @override */ + public transpileVariableDestructuring(value: string): string { + return `unpack(${value})`; + } } diff --git a/src/targets/Transpiler.52.ts b/src/targets/Transpiler.52.ts index 07b48e50a..691e48345 100644 --- a/src/targets/Transpiler.52.ts +++ b/src/targets/Transpiler.52.ts @@ -53,4 +53,8 @@ export class LuaTranspiler52 extends LuaTranspiler51 { return `bit32.arshift(${lhs},${rhs})`; } } + /** @override */ + public transpileVariableDestructuring(value: string): string { + return `table.unpack(${value})`; + } } From 3da4f7e96e53fadbe328a5cc36af1bc7a291dd91 Mon Sep 17 00:00:00 2001 From: Janne Date: Sat, 28 Jul 2018 02:29:07 +0300 Subject: [PATCH 2/6] Remove deprecated assignmentDestructuring test files in favor of version-specific tests --- .../translation/lua/assignmentDestructing.lua | 1 - test/translation/ts/assignmentDestructing.ts | 3 -- test/unit/assignmentDestructuring.spec.ts | 50 +++++++++++++++++++ 3 files changed, 50 insertions(+), 4 deletions(-) delete mode 100644 test/translation/lua/assignmentDestructing.lua delete mode 100644 test/translation/ts/assignmentDestructing.ts create mode 100644 test/unit/assignmentDestructuring.spec.ts diff --git a/test/translation/lua/assignmentDestructing.lua b/test/translation/lua/assignmentDestructing.lua deleted file mode 100644 index d136990d4..000000000 --- a/test/translation/lua/assignmentDestructing.lua +++ /dev/null @@ -1 +0,0 @@ -local a,b=table.unpack(myFunc()) diff --git a/test/translation/ts/assignmentDestructing.ts b/test/translation/ts/assignmentDestructing.ts deleted file mode 100644 index 7f2fd7194..000000000 --- a/test/translation/ts/assignmentDestructing.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare function myFunc(): [number, string]; - -let [a, b] = myFunc(); \ No newline at end of file diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts new file mode 100644 index 000000000..66d0c295f --- /dev/null +++ b/test/unit/assignmentDestructuring.spec.ts @@ -0,0 +1,50 @@ +import { Expect, Test, TestCase } from "alsatian"; +import * as util from "../src/util"; +import { LuaTarget } from "../../src/Transpiler"; + +const tupleDestructuringTs = ` + declare function myFunc(): [number, string]; + let [a, b] = myFunc();`; + +export class AssignmentDestructuringTests { + + @Test("Tuple destructuring [5.1]") + public tupleDestructing51() { + // Transpile + const lua = util.transpileString( + tupleDestructuringTs, {luaTarget: LuaTarget.Lua51, luaLibImport: "none"} + ); + // Assert + Expect(lua).toBe(`local a,b=unpack(myFunc())`); + } + + @Test("Tuple destructuring [5.2]") + public tupleDestructing52() { + // Transpile + const lua = util.transpileString( + tupleDestructuringTs, {luaTarget: LuaTarget.Lua52, luaLibImport: "none"} + ); + // Assert + Expect(lua).toBe(`local a,b=table.unpack(myFunc())`); + } + + @Test("Tuple destructuring [5.3]") + public tupleDestructing53() { + // Transpile + const lua = util.transpileString( + tupleDestructuringTs, {luaTarget: LuaTarget.Lua53, luaLibImport: "none"} + ); + // Assert + Expect(lua).toBe(`local a,b=table.unpack(myFunc())`); + } + + @Test("Tuple destructuring [JIT]") + public tupleDestructingJIT() { + // Transpile + const lua = util.transpileString( + tupleDestructuringTs, {luaTarget: LuaTarget.LuaJIT, luaLibImport: "none"} + ); + // Assert + Expect(lua).toBe(`local a,b=table.unpack(myFunc())`); + } +} From 9e126b1f7e0e414a85ec4718de8fb3aaa80ef55c Mon Sep 17 00:00:00 2001 From: Janne Date: Sat, 28 Jul 2018 02:59:42 +0300 Subject: [PATCH 3/6] fix Lua 5.3 VM compatibility issue with running Lua 5.1 code --- test/src/backport.51.lua | 2 ++ test/src/util.ts | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test/src/backport.51.lua diff --git a/test/src/backport.51.lua b/test/src/backport.51.lua new file mode 100644 index 000000000..0e5001a8a --- /dev/null +++ b/test/src/backport.51.lua @@ -0,0 +1,2 @@ +-- Lua 5.1 unpack was moved to table.unpack in Lua 5.3, make it available as a backport +unpack = table.unpack diff --git a/test/src/util.ts b/test/src/util.ts index 463172c22..9525c5bb1 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -12,6 +12,7 @@ import {lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; const fs = require("fs"); const libSource = fs.readFileSync(path.join(path.dirname(require.resolve("typescript")), "lib.es6.d.ts")).toString(); +const backport51 = fs.readFileSync("test/src/backport.51.lua") + "\n"; export function transpileString(str: string, options: CompilerOptions = { luaLibImport: "none", luaTarget: LuaTarget.Lua53 }): string { const compilerHost = { @@ -60,11 +61,15 @@ export function transpileFile(filePath: string): string { return result.trim(); } -export function executeLua(luaStr: string, withLib = true): any { +export function executeLua(luaStr: string, withLib = true, with51Backport = true): any { if (withLib) { luaStr = minimalTestLib + luaStr; } + if (with51Backport) { + luaStr = backport51 + luaStr; + } + const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const status = lauxlib.luaL_dostring(L, to_luastring(luaStr)); From 4b5a78710641bf27a036fa450459d98673382242 Mon Sep 17 00:00:00 2001 From: Janne Date: Sat, 28 Jul 2018 09:26:13 +0300 Subject: [PATCH 4/6] Removed duplicate tests, renamed tests to match the test case --- test/unit/assignmentDestructuring.spec.ts | 35 ++++++----------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 66d0c295f..deb339186 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -2,47 +2,28 @@ import { Expect, Test, TestCase } from "alsatian"; import * as util from "../src/util"; import { LuaTarget } from "../../src/Transpiler"; -const tupleDestructuringTs = ` +export class AssignmentDestructuringTests { + + private readonly assignmentDestruturingTs = ` declare function myFunc(): [number, string]; let [a, b] = myFunc();`; -export class AssignmentDestructuringTests { - @Test("Tuple destructuring [5.1]") - public tupleDestructing51() { + @Test("Assignment destructuring [5.1]") + public assignmentDestructuring51() { // Transpile const lua = util.transpileString( - tupleDestructuringTs, {luaTarget: LuaTarget.Lua51, luaLibImport: "none"} + this.assignmentDestruturingTs, {luaTarget: LuaTarget.Lua51, luaLibImport: "none"} ); // Assert Expect(lua).toBe(`local a,b=unpack(myFunc())`); } - @Test("Tuple destructuring [5.2]") + @Test("Assignment destructuring [5.2]") public tupleDestructing52() { // Transpile const lua = util.transpileString( - tupleDestructuringTs, {luaTarget: LuaTarget.Lua52, luaLibImport: "none"} - ); - // Assert - Expect(lua).toBe(`local a,b=table.unpack(myFunc())`); - } - - @Test("Tuple destructuring [5.3]") - public tupleDestructing53() { - // Transpile - const lua = util.transpileString( - tupleDestructuringTs, {luaTarget: LuaTarget.Lua53, luaLibImport: "none"} - ); - // Assert - Expect(lua).toBe(`local a,b=table.unpack(myFunc())`); - } - - @Test("Tuple destructuring [JIT]") - public tupleDestructingJIT() { - // Transpile - const lua = util.transpileString( - tupleDestructuringTs, {luaTarget: LuaTarget.LuaJIT, luaLibImport: "none"} + this.assignmentDestruturingTs, {luaTarget: LuaTarget.Lua52, luaLibImport: "none"} ); // Assert Expect(lua).toBe(`local a,b=table.unpack(myFunc())`); From 4119b749d5e81e5997213d13f680728c08d63ab1 Mon Sep 17 00:00:00 2001 From: Janne Date: Sat, 28 Jul 2018 14:33:47 +0300 Subject: [PATCH 5/6] Fix style & coding conventions to match the project --- src/Transpiler.ts | 7 ++++++- src/targets/Transpiler.52.ts | 1 + test/unit/assignmentDestructuring.spec.ts | 9 ++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Transpiler.ts b/src/Transpiler.ts index b241586a7..2c0b2be5e 100644 --- a/src/Transpiler.ts +++ b/src/Transpiler.ts @@ -1287,7 +1287,12 @@ export abstract class LuaTranspiler { } // Implemented in 5.1 and overridden in 5.2 (and onwards) - public abstract transpileVariableDestructuring(value: string): string; + public transpileVariableDestructuring(value: string): string { + throw new TranspileError( + `transpileVariableDestructuring must be implemented!`, + null + ); + } public transpileVariableDeclaration(node: ts.VariableDeclaration): string { if (ts.isIdentifier(node.name)) { diff --git a/src/targets/Transpiler.52.ts b/src/targets/Transpiler.52.ts index 691e48345..970f59fdf 100644 --- a/src/targets/Transpiler.52.ts +++ b/src/targets/Transpiler.52.ts @@ -53,6 +53,7 @@ export class LuaTranspiler52 extends LuaTranspiler51 { return `bit32.arshift(${lhs},${rhs})`; } } + /** @override */ public transpileVariableDestructuring(value: string): string { return `table.unpack(${value})`; diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index deb339186..f2d373632 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -1,13 +1,12 @@ import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; import { LuaTarget } from "../../src/Transpiler"; +import * as util from "../src/util"; export class AssignmentDestructuringTests { - - private readonly assignmentDestruturingTs = ` - declare function myFunc(): [number, string]; - let [a, b] = myFunc();`; + private readonly assignmentDestruturingTs = ` + declare function myFunc(): [number, string]; + let [a, b] = myFunc();`; @Test("Assignment destructuring [5.1]") public assignmentDestructuring51() { From 8b23e07dcd5fdb84247809f0450734472a872cf6 Mon Sep 17 00:00:00 2001 From: Janne Date: Sat, 28 Jul 2018 14:34:56 +0300 Subject: [PATCH 6/6] Remove unnecessary backport (generated lualib no longer contains varible destruturing) --- test/src/backport.51.lua | 2 -- test/src/util.ts | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 test/src/backport.51.lua diff --git a/test/src/backport.51.lua b/test/src/backport.51.lua deleted file mode 100644 index 0e5001a8a..000000000 --- a/test/src/backport.51.lua +++ /dev/null @@ -1,2 +0,0 @@ --- Lua 5.1 unpack was moved to table.unpack in Lua 5.3, make it available as a backport -unpack = table.unpack diff --git a/test/src/util.ts b/test/src/util.ts index 9525c5bb1..463172c22 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -12,7 +12,6 @@ import {lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; const fs = require("fs"); const libSource = fs.readFileSync(path.join(path.dirname(require.resolve("typescript")), "lib.es6.d.ts")).toString(); -const backport51 = fs.readFileSync("test/src/backport.51.lua") + "\n"; export function transpileString(str: string, options: CompilerOptions = { luaLibImport: "none", luaTarget: LuaTarget.Lua53 }): string { const compilerHost = { @@ -61,15 +60,11 @@ export function transpileFile(filePath: string): string { return result.trim(); } -export function executeLua(luaStr: string, withLib = true, with51Backport = true): any { +export function executeLua(luaStr: string, withLib = true): any { if (withLib) { luaStr = minimalTestLib + luaStr; } - if (with51Backport) { - luaStr = backport51 + luaStr; - } - const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); const status = lauxlib.luaL_dostring(L, to_luastring(luaStr));