diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index d198362ba..941d8182d 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -19,7 +19,9 @@ export const transformSwitchStatement: FunctionVisitor = (st let statements: lua.Statement[] = []; const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); - for (const [index, clause] of caseClauses.entries()) { + + // Starting from the back, concatenating ifs into one big if/elseif statement + const concatenatedIf = caseClauses.reduceRight((previousCondition, clause, index) => { // If the clause condition holds, go to the correct label const condition = lua.createBinaryExpression( switchVariable, @@ -28,8 +30,11 @@ export const transformSwitchStatement: FunctionVisitor = (st ); const goto = lua.createGotoStatement(`${switchName}_case_${index}`); - const conditionalGoto = lua.createIfStatement(condition, lua.createBlock([goto])); - statements.push(conditionalGoto); + return lua.createIfStatement(condition, lua.createBlock([goto]), previousCondition); + }, undefined as lua.IfStatement | undefined); + + if (concatenatedIf) { + statements.push(concatenatedIf); } const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause); diff --git a/test/unit/__snapshots__/conditionals.spec.ts.snap b/test/unit/__snapshots__/conditionals.spec.ts.snap new file mode 100644 index 000000000..e1c59f48f --- /dev/null +++ b/test/unit/__snapshots__/conditionals.spec.ts.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`array 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result = -1 + local ____switch3 = 2 + if ____switch3 == 0 then + goto ____switch3_case_0 + elseif ____switch3 == 1 then + goto ____switch3_case_1 + elseif ____switch3 == 2 then + goto ____switch3_case_2 + end + goto ____switch3_end + ::____switch3_case_0:: + do + do + result = 200 + goto ____switch3_end + end + end + ::____switch3_case_1:: + do + do + result = 100 + goto ____switch3_end + end + end + ::____switch3_case_2:: + do + do + result = 1 + goto ____switch3_end + end + end + ::____switch3_end:: + return result +end +return ____exports" +`; diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 54534e9c8..a11fd0595 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -184,7 +184,7 @@ test("variable in nested scope does not interfere with case scope", () => { `.expectToMatchJsResult(); }); -test.only("switch using variable re-declared in cases", () => { +test("switch using variable re-declared in cases", () => { util.testFunction` let foo: number = 0; switch (foo) { @@ -311,6 +311,35 @@ test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { `.expectToMatchJsResult(); }); +test("switch uses elseif", () => { + test("array", () => { + util.testFunction` + let result: number = -1; + + switch (2 as number) { + case 0: { + result = 200; + break; + } + + case 1: { + result = 100; + break; + } + + case 2: { + result = 1; + break; + } + } + + return result; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); +}); + test("switch not allowed in 5.1", () => { util.testFunction` switch ("abc") {}