@@ -145,12 +145,11 @@ export class LuaTransformer {
145145 public transformStatements (
146146 statements : ts . Statement [ ] | ReadonlyArray < ts . Statement > ) : tstl . Statement [ ] {
147147
148- const tstlStatements = ( statements as ts . Statement [ ] ) . map ( statement => this . transformStatement ( statement ) as tstl . Statement ) ;
149-
150- const flat = this . flat ( tstlStatements ) ;
151-
152- // TODO this is somewhat hacky and not typesafe
153- return flat ;
148+ const tstlStatements : tstl . Statement [ ] = [ ] ;
149+ ( statements as ts . Statement [ ] ) . forEach ( statement => {
150+ tstlStatements . push ( ...this . statementVisitResultToStatementArray ( this . transformStatement ( statement ) ) ) ;
151+ } ) ;
152+ return tstlStatements ;
154153 }
155154
156155 public transformBlock ( block : ts . Block ) : tstl . Block {
@@ -850,15 +849,15 @@ export class LuaTransformer {
850849 return this . createLocalOrGlobalDeclaration ( name , functionExpression , undefined , functionDeclaration ) ;
851850 }
852851
853- public transformTypeAliasDeclaration ( arg0 : ts . TypeAliasDeclaration ) : StatementVisitResult {
854- throw new Error ( "Method not implemented." ) ;
852+ public transformTypeAliasDeclaration ( statement : ts . TypeAliasDeclaration ) : StatementVisitResult {
853+ return undefined ;
855854 }
856855
857- public transformInterfaceDeclaration ( arg0 : ts . InterfaceDeclaration ) : StatementVisitResult {
858- throw new Error ( "Method not implemented." ) ;
856+ public transformInterfaceDeclaration ( statement : ts . InterfaceDeclaration ) : StatementVisitResult {
857+ return undefined ;
859858 }
860859
861- public transformVariableDeclaration ( statement : ts . VariableDeclaration ) : StatementVisitResult {
860+ public transformVariableDeclaration ( statement : ts . VariableDeclaration ) : tstl . Statement [ ] {
862861 if ( statement . initializer ) {
863862 // Validate assignment
864863 const initializerType = this . checker . getTypeAtLocation ( statement . initializer ) ;
@@ -878,11 +877,11 @@ export class LuaTransformer {
878877 return [ tstl . createVariableDeclarationStatement ( identifierName ) , tstl . createAssignmentStatement ( identifierName , value ) ] ;
879878 } else {
880879 // local identifierName = value;
881- return tstl . createVariableDeclarationStatement ( identifierName , value ) ;
880+ return [ tstl . createVariableDeclarationStatement ( identifierName , value ) ] ;
882881 }
883882 } else {
884883 // local identifierName = nil;
885- return tstl . createVariableDeclarationStatement ( identifierName , tstl . createNilLiteral ( ) ) ;
884+ return [ tstl . createVariableDeclarationStatement ( identifierName , tstl . createNilLiteral ( ) ) ] ;
886885 }
887886 } else if ( ts . isArrayBindingPattern ( statement . name ) ) {
888887 // Destructuring type
@@ -897,23 +896,23 @@ export class LuaTransformer {
897896 // Don't unpack TupleReturn decorated functions
898897 if ( tsHelper . isTupleReturnCall ( statement . initializer , this . checker ) ) {
899898 // local vars = initializer;
900- return tstl . createVariableDeclarationStatement ( vars , this . transformExpression ( statement . initializer ) ) ;
899+ return [ tstl . createVariableDeclarationStatement ( vars , this . transformExpression ( statement . initializer ) ) ] ;
901900 } else {
902901 // local vars = this.transpileDestructingAssignmentValue(node.initializer);
903- return tstl . createVariableDeclarationStatement ( vars , this . createUnpackCall ( statement . initializer ) ) ;
902+ return [ tstl . createVariableDeclarationStatement ( vars , this . createUnpackCall ( statement . initializer ) ) ] ;
904903 }
905904 } else {
906905 throw TSTLErrors . UnsupportedKind ( "variable declaration" , statement . name . kind , statement ) ;
907906 }
908907 }
909908
910909 public transformVariableStatement ( statement : ts . VariableStatement ) : StatementVisitResult {
911- return this . flat (
912- statement . declarationList . declarations . map ( declaration => this . transformVariableDeclaration ( declaration ) ) as tstl . Statement [ ]
913- ) ;
910+ const result : tstl . Statement [ ] = [ ] ;
911+ statement . declarationList . declarations . forEach ( declaration => result . push ( ... this . transformVariableDeclaration ( declaration ) ) ) ;
912+ return result ;
914913 }
915914
916- public transformExpressionStatement ( statement : ts . ExpressionStatement | ts . Expression ) : StatementVisitResult {
915+ public transformExpressionStatement ( statement : ts . ExpressionStatement | ts . Expression ) : tstl . Statement {
917916 const expression = ts . isExpressionStatement ( statement ) ? statement . expression : statement ;
918917 if ( ts . isBinaryExpression ( expression ) ) {
919918 const [ isCompound , replacementOperator ] = tsHelper . isBinaryAssignmentToken (
@@ -965,7 +964,7 @@ export class LuaTransformer {
965964 return tstl . createExpressionStatement ( this . transformExpression ( expression ) ) ;
966965 }
967966
968- public transformReturn ( statement : ts . ReturnStatement ) : StatementVisitResult {
967+ public transformReturn ( statement : ts . ReturnStatement ) : tstl . Statement {
969968 if ( statement . expression ) {
970969 const returnType = tsHelper . getContainingFunctionReturnType ( statement , this . checker ) ;
971970 if ( returnType ) {
@@ -989,22 +988,58 @@ export class LuaTransformer {
989988 }
990989 }
991990
992- public transformIfStatement ( arg0 : ts . IfStatement ) : StatementVisitResult {
993- throw new Error ( "Method not implemented." ) ;
991+ public transformIfStatement ( statement : ts . IfStatement ) : tstl . IfStatement {
992+ const condition = this . transformExpression ( statement . expression ) ;
993+ const ifBlock = tstl . createBlock ( this . statementVisitResultToStatementArray ( this . transformStatement ( statement . thenStatement ) ) ) ;
994+ if ( statement . elseStatement ) {
995+ if ( ts . isIfStatement ( statement . elseStatement ) ) {
996+ return tstl . createIfStatement ( condition , ifBlock , this . transformIfStatement ( statement . elseStatement ) ) ;
997+ } else {
998+ const elseBlock = tstl . createBlock ( this . statementVisitResultToStatementArray ( this . transformStatement ( statement . elseStatement ) ) ) ;
999+ return tstl . createIfStatement ( condition , ifBlock , elseBlock ) ;
1000+ }
1001+ }
1002+ return tstl . createIfStatement ( condition , ifBlock ) ;
9941003 }
9951004
996- public transformWhileStatement ( arg0 : ts . WhileStatement ) : StatementVisitResult {
997- throw new Error ( "Method not implemented." ) ;
1005+ public transformWhileStatement ( statement : ts . WhileStatement ) : StatementVisitResult {
1006+ return tstl . createWhileStatement (
1007+ tstl . createBlock ( this . statementVisitResultToStatementArray ( this . transformStatement ( statement . statement ) ) ) ,
1008+ this . transformExpression ( statement . expression )
1009+ ) ;
9981010 }
9991011
1000- public transformDoStatement ( arg0 : ts . DoStatement ) : StatementVisitResult {
1001- throw new Error ( "Method not implemented." ) ;
1012+ public transformDoStatement ( statement : ts . DoStatement ) : StatementVisitResult {
1013+ return tstl . createRepeatStatement (
1014+ tstl . createBlock ( this . statementVisitResultToStatementArray ( this . transformStatement ( statement . statement ) ) ) ,
1015+ tstl . createUnaryExpression ( this . transformExpression ( statement . expression ) , tstl . SyntaxKind . NotOperator )
1016+ ) ;
10021017 }
10031018
1004- public transformForStatement ( arg0 : ts . ForStatement ) : StatementVisitResult {
1005- // NOTE : When implementing, make sure incrementor is transformed with transformExpressionStatement
1006- // to ensure it is not wrapped in an iife.
1007- throw new Error ( "Method not implemented." ) ;
1019+ public transformForStatement ( statement : ts . ForStatement ) : StatementVisitResult {
1020+ const result : tstl . Statement [ ] = [ ] ;
1021+
1022+ if ( statement . initializer ) {
1023+ for ( const variableDeclaration of ( statement . initializer as ts . VariableDeclarationList ) . declarations ) {
1024+ // local initializer = value
1025+ result . push ( ...this . transformVariableDeclaration ( variableDeclaration ) ) ;
1026+ }
1027+ }
1028+
1029+ const condition = statement . condition ? this . transformExpression ( statement . condition ) : tstl . createBooleanLiteral ( true ) ;
1030+
1031+ // Add body
1032+ const body : tstl . Statement [ ] = [ ] ;
1033+ body . push ( ...this . statementVisitResultToStatementArray ( this . transformStatement ( statement . statement ) ) ) ;
1034+
1035+ if ( statement . incrementor ) {
1036+ body . push ( this . transformExpressionStatement ( statement . incrementor ) ) ;
1037+ }
1038+
1039+ // while (condition) do ... end
1040+ result . push ( tstl . createWhileStatement ( tstl . createBlock ( body ) , condition ) ) ;
1041+
1042+ return result ;
10081043 }
10091044
10101045 public transformForOfStatement ( statement : ts . ForOfStatement ) : StatementVisitResult {
@@ -1079,10 +1114,12 @@ export class LuaTransformer {
10791114 undefined ,
10801115 itemVariable
10811116 ) ;
1117+ // TODO ?????
10821118 this . transformVariableDeclaration ( declaration ) ;
10831119 } else {
10841120 // Assign item variable
10851121 const assignment = ts . createAssignment ( statement . initializer , itemVariable ) ;
1122+ // TODO ??? this does nothing
10861123 this . transformExpression ( assignment ) ;
10871124 }
10881125 }
@@ -1126,7 +1163,7 @@ export class LuaTransformer {
11261163 }
11271164
11281165 public transformEmptyStatement ( arg0 : ts . EmptyStatement ) : StatementVisitResult {
1129- throw new Error ( "Method not implemented." ) ;
1166+ return undefined ;
11301167 }
11311168
11321169 // Expressions
@@ -1152,6 +1189,8 @@ export class LuaTransformer {
11521189 case ts . SyntaxKind . StringLiteral :
11531190 case ts . SyntaxKind . NoSubstitutionTemplateLiteral :
11541191 return this . transformStringLiteral ( expression as ts . StringLiteral ) ;
1192+ case ts . SyntaxKind . TemplateExpression :
1193+ return this . transformTemplateExpression ( expression as ts . TemplateExpression ) ;
11551194 case ts . SyntaxKind . NumericLiteral :
11561195 return tstl . createNumericLiteral (
11571196 Number ( ( expression as ts . NumericLiteral ) . text ) ,
@@ -1468,7 +1507,7 @@ export class LuaTransformer {
14681507 lhs : ts . Expression ,
14691508 rhs : ts . Expression ,
14701509 replacementOperator : tstl . BinaryOperator
1471- ) : StatementVisitResult {
1510+ ) : tstl . Statement {
14721511 const left = this . transformExpression ( lhs ) as tstl . IdentifierOrTableIndexExpression ;
14731512 const right = this . transformExpression ( rhs ) ;
14741513
@@ -2285,6 +2324,18 @@ export class LuaTransformer {
22852324 return tstl . createStringLiteral ( text ) ;
22862325 }
22872326
2327+ public transformTemplateExpression ( expression : ts . TemplateExpression ) : tstl . BinaryExpression {
2328+ const parts : tstl . Expression [ ] = [ tstl . createStringLiteral ( this . escapeString ( expression . head . text ) ) ] ;
2329+ expression . templateSpans . forEach ( span => {
2330+ const expr = this . transformExpression ( span . expression ) ;
2331+ const text = tstl . createStringLiteral ( this . escapeString ( span . literal . text ) ) ;
2332+
2333+ // tostring(expr).."text"
2334+ parts . push ( tstl . createBinaryExpression ( tstl . createCallExpression ( tstl . createIdentifier ( "tostring" ) , [ expr ] ) , text , tstl . SyntaxKind . ConcatOperator ) ) ;
2335+ } ) ;
2336+ return parts . reduce ( ( prev , current ) => tstl . createBinaryExpression ( prev , current , tstl . SyntaxKind . ConcatOperator ) ) as tstl . BinaryExpression ;
2337+ }
2338+
22882339 public transformPropertyName ( propertyName : ts . PropertyName ) : ExpressionVisitResult {
22892340 if ( ts . isComputedPropertyName ( propertyName ) ) {
22902341 return this . transformExpression ( propertyName . expression ) ;
@@ -2520,18 +2571,25 @@ export class LuaTransformer {
25202571 return this . scopeStack . pop ( ) ;
25212572 }
25222573
2523- private flat < T > ( arr : T [ ] | ReadonlyArray < T > ) : T [ ] {
2574+ private statementVisitResultToStatementArray ( visitResult : StatementVisitResult ) : tstl . Statement [ ] {
2575+ if ( ! Array . isArray ( visitResult ) ) {
2576+ if ( visitResult ) {
2577+ return [ visitResult ] ;
2578+ }
2579+ return [ ] ;
2580+ }
25242581 const flatten = ( arr , result = [ ] ) => {
25252582 for ( let i = 0 , length = arr . length ; i < length ; i ++ ) {
25262583 const value = arr [ i ] ;
25272584 if ( Array . isArray ( value ) ) {
25282585 flatten ( value , result ) ;
2529- } else {
2586+ } else if ( value ) {
2587+ // ignore value if undefined
25302588 result . push ( value ) ;
25312589 }
25322590 }
25332591 return result ;
25342592 } ;
2535- return flatten ( arr ) ;
2593+ return flatten ( visitResult ) ;
25362594 }
25372595}
0 commit comments