@@ -7,7 +7,7 @@ import * as tstl from "./LuaAST";
77import { CompilerOptions } from "./CompilerOptions" ;
88import { DecoratorKind } from "./Decorator" ;
99import { TSTLErrors } from "./Errors" ;
10- import { TSHelper as tsHelper } from "./TSHelper" ;
10+ import { ContextType , TSHelper as tsHelper } from "./TSHelper" ;
1111
1212type StatementVisitResult = tstl . Statement | tstl . Statement [ ] | undefined ;
1313type ExpressionVisitResult = tstl . Expression | undefined ;
@@ -569,22 +569,42 @@ export class LuaTransformer {
569569 body : ts . Block ,
570570 spreadIdentifier ?: tstl . Identifier
571571 ) : tstl . Statement [ ] {
572- this . pushSpecialScope ( ScopeType . Function ) ;
573- let result = "" ;
572+ const headerStatements = [ ] ;
574573
575574 // Add default parameters
576- const defaultValueParams = parameters . filter ( declaration => declaration . initializer !== undefined ) ;
577- result += this . transpileParameterDefaultValues ( defaultValueParams ) ;
575+ const defaultValueDeclarations = parameters
576+ . filter ( declaration => declaration . initializer !== undefined )
577+ . map ( this . transformParameterDefaultValueDeclaration ) ;
578+
579+ headerStatements . push ( ...defaultValueDeclarations ) ;
578580
579581 // Push spread operator here
580- if ( spreadIdentifier !== "" ) {
581- result += this . indent + `local ${ spreadIdentifier } = { ... }\n` ;
582+ if ( spreadIdentifier ) {
583+ const fieldExpression = tstl . createTableFieldExpression ( tstl . createDotsLiteral ( ) ) ;
584+ const spreadTable = tstl . createTableExpression ( [ fieldExpression ] ) ;
585+ headerStatements . push ( this . createLocalOrGlobalDeclaration ( spreadIdentifier , spreadTable ) ) ;
582586 }
583587
584- result += this . transpileBlock ( body ) ;
585- this . popSpecialScope ( ) ;
588+ const bodyStatements = body . statements . map ( this . transformStatement ) ;
586589
587- return result ;
590+ return headerStatements . concat ( bodyStatements ) ;
591+ }
592+
593+ public transformParameterDefaultValueDeclaration ( declaration : ts . ParameterDeclaration ) : tstl . Statement {
594+
595+ const parameterName = this . transformIdentifier ( declaration . name as ts . Identifier ) ;
596+ const parameterValue = this . transformExpression ( declaration . initializer ) ;
597+ const assignment = tstl . createVariableAssignmentStatement ( parameterName , parameterValue ) ;
598+
599+ const nilCondition = tstl . createBinaryExpression (
600+ parameterName ,
601+ tstl . createNilLiteral ( ) ,
602+ tstl . SyntaxKind . EqualityOperator
603+ ) ;
604+
605+ const ifBlock = tstl . createBlock ( [ assignment ] ) ;
606+
607+ return tstl . createIfStatement ( nilCondition , ifBlock , undefined , undefined , declaration ) ;
588608 }
589609
590610 public transformModuleDeclaration ( arg0 : ts . ModuleDeclaration , parent : tstl . Node ) : StatementVisitResult {
@@ -666,9 +686,27 @@ export class LuaTransformer {
666686 } ) ;
667687 }
668688
669- public transformFunctionDeclaration ( arg0 : ts . FunctionDeclaration , parent : Node ) : StatementVisitResult {
670- throw new Error ( "Method not implemented." ) ;
689+ public transformFunctionDeclaration ( functionDeclaration : ts . FunctionDeclaration ) : StatementVisitResult {
690+ // Don't transpile functions without body (overload declarations)
691+ if ( ! functionDeclaration . body ) { return undefined ; }
692+
693+ const type = this . checker . getTypeAtLocation ( functionDeclaration ) ;
694+ const context = tsHelper . getFunctionContextType ( type , this . checker ) !== ContextType . Void
695+ ? this . selfIdentifier
696+ : undefined ;
697+ const [ params , dotsLiteral , restParamName ] = this . transformParameters ( functionDeclaration . parameters , context ) ;
698+
699+ const name = this . transformIdentifier ( functionDeclaration . name ) ;
700+ const body = tstl . createBlock ( this . transformFunctionBody (
701+ functionDeclaration . parameters ,
702+ functionDeclaration . body ,
703+ restParamName
704+ ) ) ;
705+ const functionExpression = tstl . createFunctionExpression ( body , params , dotsLiteral , restParamName ) ;
706+
707+ return this . createLocalOrGlobalDeclaration ( name , functionExpression , undefined , functionDeclaration ) ;
671708 }
709+
672710 public transformTypeAliasDeclaration ( arg0 : ts . TypeAliasDeclaration , parent : Node ) : StatementVisitResult {
673711 throw new Error ( "Method not implemented." ) ;
674712 }
0 commit comments