Skip to content

Commit 34d3f4a

Browse files
tomblindPerryvw
authored andcommitted
refactored try block to allow rethrow (#251)
* refactored try block to allow rethrow * updated rethrow test with something less convoluted
1 parent 9399f10 commit 34d3f4a

File tree

5 files changed

+108
-29
lines changed

5 files changed

+108
-29
lines changed

src/Transpiler.ts

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -687,24 +687,44 @@ export abstract class LuaTranspiler {
687687
}
688688

689689
public transpileTry(node: ts.TryStatement): string {
690-
let tryFunc = "function()\n";
690+
let result = this.indent + "do\n";
691+
this.pushIndent();
692+
693+
result += this.indent;
694+
if (node.catchClause) {
695+
result += "local __TS_try";
696+
if (node.catchClause.variableDeclaration) {
697+
const variableName = this.transpileIdentifier(
698+
node.catchClause.variableDeclaration.name as ts.Identifier);
699+
result += ", " + variableName;
700+
}
701+
result += " = ";
702+
}
703+
704+
result += "pcall(function()\n";
691705
this.pushIndent();
692-
tryFunc += this.transpileBlock(node.tryBlock);
706+
result += this.transpileBlock(node.tryBlock);
693707
this.popIndent();
694-
tryFunc += "end";
695-
let catchFunc = "function(e)\nend";
696-
if (node.catchClause && node.catchClause.variableDeclaration) {
697-
const variableName = this.transpileIdentifier(node.catchClause.variableDeclaration.name as ts.Identifier);
698-
catchFunc = this.indent + `function(${variableName})\n`;
708+
result += this.indent + "end);\n";
709+
710+
if (node.catchClause) {
711+
result += this.indent + `if not __TS_try then\n`;
699712
this.pushIndent();
700-
catchFunc += this.transpileBlock(node.catchClause.block);
713+
result += this.transpileBlock(node.catchClause.block);
701714
this.popIndent();
702-
catchFunc += "end";
715+
result += this.indent + "end\n";
703716
}
704-
let result = this.indent + `xpcall(${tryFunc},\n${catchFunc})\n`;
717+
705718
if (node.finallyBlock) {
719+
result += this.indent + "do\n";
720+
this.pushIndent();
706721
result += this.transpileBlock(node.finallyBlock);
722+
this.popIndent();
723+
result += this.indent + "end\n";
707724
}
725+
726+
this.popIndent();
727+
result += this.indent + "end\n";
708728
return result;
709729
}
710730

test/translation/lua/tryCatch.lua

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
xpcall(function()
2-
local a = 42;
3-
end,
4-
function(er)
5-
local b = "fail";
6-
end)
1+
do
2+
local __TS_try, er = pcall(function()
3+
local a = 42;
4+
end);
5+
if not __TS_try then
6+
local b = "fail";
7+
end
8+
end
Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
xpcall(function()
2-
local a = 42;
3-
end,
4-
function(er)
5-
local b = "fail";
6-
end)
7-
local c = "finally";
1+
do
2+
local __TS_try, er = pcall(function()
3+
local a = 42;
4+
end);
5+
if not __TS_try then
6+
local b = "fail";
7+
end
8+
do
9+
local c = "finally";
10+
end
11+
end
Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
xpcall(function()
2-
local a = 42;
3-
end,
4-
function(e)
5-
end)
6-
local b = "finally";
1+
do
2+
pcall(function()
3+
local a = 42;
4+
end);
5+
do
6+
local b = "finally";
7+
end
8+
end

test/unit/error.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,55 @@ export class LuaErrorTests {
2424
);
2525
}).toThrowError(TranspileError, "Invalid throw expression, only strings can be thrown.");
2626
}
27+
28+
@TestCase(0, "A")
29+
@TestCase(1, "B")
30+
@TestCase(2, "C")
31+
@Test("re-throw")
32+
public reThrow(i: number, expected: any): void {
33+
const source =
34+
`const i = ${i};
35+
function foo() {
36+
try {
37+
try {
38+
if (i === 0) { throw "z"; }
39+
} catch (e) {
40+
throw "a";
41+
} finally {
42+
if (i === 1) { throw "b"; }
43+
}
44+
} catch (e) {
45+
throw (e as string).toUpperCase();
46+
} finally {
47+
throw "C";
48+
}
49+
}
50+
let result = "x";
51+
try {
52+
foo();
53+
} catch (e) {
54+
result = (e as string)[(e as string).length - 1];
55+
}
56+
return result;`;
57+
const result = util.transpileAndExecute(source);
58+
Expect(result).toBe(expected);
59+
}
60+
61+
@Test("re-throw (no catch var)")
62+
public reThrowWithoutCatchVar(): void {
63+
const source =
64+
`let result = "x";
65+
try {
66+
try {
67+
throw "y";
68+
} catch {
69+
throw "z";
70+
}
71+
} catch (e) {
72+
result = (e as string)[(e as string).length - 1];
73+
}
74+
return result;`;
75+
const result = util.transpileAndExecute(source);
76+
Expect(result).toBe("z");
77+
}
2778
}

0 commit comments

Comments
 (0)