@@ -1351,12 +1351,67 @@ export class LuaTransformer {
13511351 ) ;
13521352 }
13531353
1354- public transformSwitchStatement ( arg0 : ts . SwitchStatement ) : StatementVisitResult {
1355- throw new Error ( "Method not implemented." ) ;
1354+ public transformSwitchStatement ( statement : ts . SwitchStatement ) : StatementVisitResult {
1355+ if ( this . options . luaTarget === LuaTarget . Lua51 ) {
1356+ throw TSTLErrors . UnsupportedForTarget ( "Switch statements" , this . options . luaTarget , statement ) ;
1357+ }
1358+
1359+ this . pushScope ( ScopeType . Switch ) ;
1360+
1361+ // Give the switch a unique name to prevent nested switches from acting up.
1362+ const switchName = `____TS_switch${ this . scopeStack . length } ` ;
1363+
1364+ const expression = this . transformExpression ( statement . expression ) ;
1365+ const switchVariable = tstl . createIdentifier ( switchName ) ;
1366+ const switchVariableDeclaration = tstl . createVariableDeclarationStatement ( switchVariable , expression ) ;
1367+
1368+ const statements : tstl . Statement [ ] = [ switchVariableDeclaration ] ;
1369+
1370+ const caseClauses = statement . caseBlock . clauses . filter ( c => ts . isCaseClause ( c ) ) as ts . CaseClause [ ] ;
1371+
1372+ for ( let i = 0 ; i < caseClauses . length ; i ++ ) {
1373+ const clause = caseClauses [ i ] ;
1374+ // If the clause condition holds, go to the correct label
1375+ const condition = tstl . createBinaryExpression (
1376+ switchVariable ,
1377+ this . transformExpression ( clause . expression ) ,
1378+ tstl . SyntaxKind . EqualityOperator
1379+ ) ;
1380+ const goto = tstl . createGotoStatement ( `${ switchName } _case_${ i } ` ) ;
1381+ const conditionalGoto = tstl . createIfStatement ( condition , tstl . createBlock ( [ goto ] ) ) ;
1382+ statements . push ( conditionalGoto ) ;
1383+ }
1384+
1385+ const hasDefaultCase = statement . caseBlock . clauses . some ( c => ts . isDefaultClause ( c ) ) ;
1386+ if ( hasDefaultCase ) {
1387+ statements . push ( tstl . createGotoStatement ( `${ switchName } _case_default` ) ) ;
1388+ } else {
1389+ statements . push ( tstl . createGotoStatement ( `${ switchName } _end` ) ) ;
1390+ }
1391+
1392+ for ( let i = 0 ; i < statement . caseBlock . clauses . length ; i ++ ) {
1393+ const clause = statement . caseBlock . clauses [ i ] ;
1394+ const label = ts . isCaseClause ( clause )
1395+ ? tstl . createLabelStatement ( `${ switchName } _case_${ i } ` )
1396+ : tstl . createLabelStatement ( `${ switchName } _case_default` ) ;
1397+
1398+ const body = tstl . createDoStatement ( this . transformStatements ( clause . statements ) ) ;
1399+ statements . push ( label , body ) ;
1400+ }
1401+
1402+ statements . push ( tstl . createLabelStatement ( `${ switchName } _end` ) ) ;
1403+
1404+ this . popScope ( ) ;
1405+
1406+ return statements ;
13561407 }
13571408
13581409 public transformBreakStatement ( breakStatement : ts . BreakStatement ) : StatementVisitResult {
1359- return tstl . createBreakStatement ( undefined , breakStatement ) ;
1410+ if ( this . peekScope ( ) . type === ScopeType . Switch ) {
1411+ return tstl . createGotoStatement ( `____TS_switch${ this . scopeStack . length } _end` ) ;
1412+ } else {
1413+ return tstl . createBreakStatement ( undefined , breakStatement ) ;
1414+ }
13601415 }
13611416
13621417 public transformTryStatement ( statement : ts . TryStatement ) : StatementVisitResult {
0 commit comments