@@ -343,8 +343,10 @@ export class LuaTransformer {
343343 const fieldName = this . transformPropertyName ( field . name ) ;
344344 const value = this . transformExpression ( field . initializer ) ;
345345
346- const classField =
347- tstl . createTableIndexExpression ( this . addExportToIdentifier ( className , statement . name . text ) , fieldName ) ;
346+ const classField = tstl . createTableIndexExpression (
347+ this . addExportToIdentifier ( className ) ,
348+ fieldName
349+ ) ;
348350
349351 const fieldAssign = tstl . createAssignmentStatement (
350352 classField ,
@@ -400,6 +402,8 @@ export class LuaTransformer {
400402
401403 const result : tstl . Statement [ ] = [ ] ;
402404
405+ const classNameWithExport = this . addExportToIdentifier ( className ) ;
406+
403407 // Write class declaration
404408 if ( extendsType ) {
405409 const baseName = tstl . createIdentifier ( extendsType . symbol . escapedName as string ) ;
@@ -412,7 +416,7 @@ export class LuaTransformer {
412416
413417 if ( ! noClassOr ) {
414418 // className or baseName.new()
415- rhs = tstl . createBinaryExpression ( className , rhs , tstl . SyntaxKind . OrOperator ) ;
419+ rhs = tstl . createBinaryExpression ( classNameWithExport , rhs , tstl . SyntaxKind . OrOperator ) ;
416420 }
417421
418422 // (local) className = className or baseName.new()
@@ -427,10 +431,7 @@ export class LuaTransformer {
427431
428432 if ( ! noClassOr ) {
429433 // className or {}
430- rhs = tstl . createBinaryExpression (
431- this . addExportToIdentifier ( className , statement . name . text ) ,
432- rhs ,
433- tstl . SyntaxKind . OrOperator ) ;
434+ rhs = tstl . createBinaryExpression ( classNameWithExport , rhs , tstl . SyntaxKind . OrOperator ) ;
434435 }
435436
436437 // (local) className = className or {}
@@ -442,20 +443,16 @@ export class LuaTransformer {
442443 }
443444
444445 // className.__index
445- const classIndex = tstl . createTableIndexExpression (
446- this . addExportToIdentifier ( className , statement . name . text ) ,
447- tstl . createStringLiteral ( "__index" ) ) ;
446+ const classIndex = tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "__index" ) ) ;
448447 // className.__index = className
449- const assignClassIndex = tstl . createAssignmentStatement ( classIndex , className , undefined , statement ) ;
448+ const assignClassIndex = tstl . createAssignmentStatement ( classIndex , classNameWithExport , undefined , statement ) ;
450449
451450 result . push ( assignClassIndex ) ;
452451
453452 if ( extendsType ) {
454453 const baseName = tstl . createIdentifier ( extendsType . symbol . escapedName as string ) ;
455454 // className.__base = baseName
456- const classBase = tstl . createTableIndexExpression (
457- this . addExportToIdentifier ( className , statement . name . text ) ,
458- tstl . createStringLiteral ( "__base" ) ) ;
455+ const classBase = tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "__base" ) ) ;
459456
460457 const assignClassBase = tstl . createAssignmentStatement ( classBase , baseName , undefined , statement ) ;
461458
@@ -469,7 +466,7 @@ export class LuaTransformer {
469466 this . selfIdentifier ,
470467 tstl . createCallExpression (
471468 tstl . createIdentifier ( "setmetatable" ) ,
472- [ tstl . createTableExpression ( ) , className ]
469+ [ tstl . createTableExpression ( ) , classNameWithExport ]
473470 )
474471 ) ;
475472
@@ -498,11 +495,11 @@ export class LuaTransformer {
498495 const ifConstructor = tstl . createIfStatement (
499496 tstl . createBinaryExpression (
500497 tstl . createIdentifier ( "construct" ) ,
501- tstl . createTableIndexExpression ( className , tstl . createStringLiteral ( "constructor" ) ) ,
498+ tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "constructor" ) ) ,
502499 tstl . SyntaxKind . AndOperator ) ,
503500 tstl . createBlock ( [
504501 tstl . createExpressionStatement ( tstl . createCallExpression (
505- tstl . createTableIndexExpression ( className , tstl . createStringLiteral ( "constructor" ) ) ,
502+ tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "constructor" ) ) ,
506503 [ this . selfIdentifier , tstl . createDotsLiteral ( ) ] ) ) ,
507504 ] ) ) ;
508505
@@ -517,7 +514,7 @@ export class LuaTransformer {
517514 // or function export.className.new(construct, ...) ... end
518515 const newFunc = tstl . createAssignmentStatement (
519516 tstl . createTableIndexExpression (
520- this . addExportToIdentifier ( className , statement . name . text ) ,
517+ classNameWithExport ,
521518 tstl . createStringLiteral ( "new" ) ) ,
522519 tstl . createFunctionExpression (
523520 tstl . createBlock ( newFuncStatements ) ,
@@ -593,7 +590,7 @@ export class LuaTransformer {
593590
594591 const result = tstl . createAssignmentStatement (
595592 tstl . createTableIndexExpression (
596- this . addExportToIdentifier ( className , classDeclaration . name . text ) ,
593+ this . addExportToIdentifier ( className ) ,
597594 tstl . createStringLiteral ( "constructor" ) ) ,
598595 tstl . createFunctionExpression ( body , params , dotsLiteral , restParamName , undefined , undefined ) ,
599596 undefined ,
@@ -619,7 +616,7 @@ export class LuaTransformer {
619616
620617 return tstl . createAssignmentStatement (
621618 tstl . createTableIndexExpression (
622- this . addExportToIdentifier ( className , classDeclaration . name . text ) ,
619+ this . addExportToIdentifier ( className ) ,
623620 tstl . createStringLiteral ( "get__" + name . text ) ) ,
624621 accessorFunction
625622 ) ;
@@ -644,7 +641,7 @@ export class LuaTransformer {
644641
645642 return tstl . createAssignmentStatement (
646643 tstl . createTableIndexExpression (
647- this . addExportToIdentifier ( className , classDeclaration . name . text ) ,
644+ this . addExportToIdentifier ( className ) ,
648645 tstl . createStringLiteral ( "set__" + name . text ) ) ,
649646 accessorFunction
650647 ) ;
@@ -678,9 +675,10 @@ export class LuaTransformer {
678675 restParamName
679676 ) ;
680677
678+ const parent = node . parent as ts . ClassLikeDeclaration ;
681679 return tstl . createAssignmentStatement (
682680 tstl . createTableIndexExpression (
683- this . addExportToIdentifier ( className , ( node . parent as ts . ClassLikeDeclaration ) . name . text ) ,
681+ this . addExportToIdentifier ( className ) ,
684682 methodName ) ,
685683 functionExpression ,
686684 undefined ,
@@ -944,7 +942,7 @@ export class LuaTransformer {
944942 ) ;
945943 const functionExpression = tstl . createFunctionExpression ( body , params , dotsLiteral , restParamName ) ;
946944
947- return this . createLocalOrExportedDeclaration ( name , functionExpression , undefined , functionDeclaration ) ;
945+ return this . createLocalOrExportedOrGlobalDeclaration ( name , functionExpression , undefined , functionDeclaration ) ;
948946 }
949947
950948 public transformTypeAliasDeclaration ( statement : ts . TypeAliasDeclaration ) : undefined {
@@ -970,9 +968,14 @@ export class LuaTransformer {
970968 const identifierName = this . transformIdentifier ( statement . name ) ;
971969 if ( statement . initializer ) {
972970 const value = this . transformExpression ( statement . initializer ) ;
973- return this . createLocalOrExportedDeclaration ( identifierName , value ) ;
971+ return this . createLocalOrExportedOrGlobalDeclaration ( identifierName , value , undefined , statement ) ;
974972 } else {
975- return this . createLocalOrExportedDeclaration ( identifierName , tstl . createNilLiteral ( ) ) ;
973+ return this . createLocalOrExportedOrGlobalDeclaration (
974+ identifierName ,
975+ tstl . createNilLiteral ( ) ,
976+ undefined ,
977+ statement
978+ ) ;
976979 }
977980 } else if ( ts . isArrayBindingPattern ( statement . name ) ) {
978981 // Destructuring type
@@ -987,17 +990,27 @@ export class LuaTransformer {
987990 // Don't unpack TupleReturn decorated functions
988991 if ( statement . initializer ) {
989992 if ( tsHelper . isTupleReturnCall ( statement . initializer , this . checker ) ) {
990- return this . createLocalOrExportedDeclaration ( vars , this . transformExpression ( statement . initializer ) ) ;
993+ return this . createLocalOrExportedOrGlobalDeclaration (
994+ vars ,
995+ this . transformExpression ( statement . initializer ) ,
996+ undefined ,
997+ statement
998+ ) ;
991999 } else {
9921000 // local vars = this.transpileDestructingAssignmentValue(node.initializer);
9931001 const initializer = this . createUnpackCall (
9941002 this . transformExpression ( statement . initializer ) ,
9951003 statement . initializer
9961004 ) ;
997- return this . createLocalOrExportedDeclaration ( vars , initializer ) ;
1005+ return this . createLocalOrExportedOrGlobalDeclaration ( vars , initializer , undefined , statement ) ;
9981006 }
9991007 } else {
1000- return this . createLocalOrExportedDeclaration ( vars , tstl . createNilLiteral ( ) ) ;
1008+ return this . createLocalOrExportedOrGlobalDeclaration (
1009+ vars ,
1010+ tstl . createNilLiteral ( ) ,
1011+ undefined ,
1012+ statement
1013+ ) ;
10011014 }
10021015 } else {
10031016 throw TSTLErrors . UnsupportedKind ( "variable declaration" , statement . name . kind , statement ) ;
@@ -2955,10 +2968,8 @@ export class LuaTransformer {
29552968 return scopeSymbol . exports . has ( identifierName as ts . __String ) ;
29562969 }
29572970
2958- public addExportToIdentifier ( identifier : tstl . Identifier , originalStr ?: string )
2959- : tstl . IdentifierOrTableIndexExpression {
2960- const testStr = originalStr ? originalStr : identifier . text ;
2961- if ( this . isIdentifierExported ( testStr ) ) {
2971+ public addExportToIdentifier ( identifier : tstl . Identifier ) : tstl . IdentifierOrTableIndexExpression {
2972+ if ( this . isIdentifierExported ( identifier . text ) ) {
29622973 return this . createExportedIdentifier ( identifier ) ;
29632974 }
29642975 return identifier ;
@@ -3083,49 +3094,56 @@ export class LuaTransformer {
30833094 return filePath . replace ( new RegExp ( "\\\\|\/" , "g" ) , "." ) ;
30843095 }
30853096
3086- private createLocalOrExportedOrGlobalDeclaration (
3087- lhs : tstl . Identifier | tstl . Identifier [ ] ,
3088- rhs : tstl . Expression ,
3089- parent ?: tstl . Node ,
3090- tsOriginal ?: ts . Node
3091- ) : tstl . Statement [ ]
3092- {
3093- const statements : tstl . Statement [ ] = [ ] ;
3094- if ( this . isModule || this . currentNamespace ) {
3095- statements . push ( ...this . createLocalOrExportedDeclaration ( lhs , rhs , parent , tsOriginal ) ) ;
3097+ private shouldExportIdentifier ( identifier : tstl . Identifier | tstl . Identifier [ ] ) : boolean {
3098+ if ( ! this . isModule && ! this . currentNamespace ) {
3099+ return false ;
3100+ }
3101+ if ( Array . isArray ( identifier ) ) {
3102+ return identifier . some ( i => this . isIdentifierExported ( i . text ) ) ;
30963103 } else {
3097- statements . push ( tstl . createAssignmentStatement ( lhs , rhs , parent , tsOriginal ) ) ;
3104+ return this . isIdentifierExported ( identifier . text ) ;
30983105 }
3099- return statements ;
31003106 }
31013107
3102- private createLocalOrExportedDeclaration (
3108+ private createLocalOrExportedOrGlobalDeclaration (
31033109 lhs : tstl . Identifier | tstl . Identifier [ ] ,
31043110 rhs : tstl . Expression ,
31053111 parent ?: tstl . Node ,
31063112 tsOriginal ?: ts . Node
31073113 ) : tstl . Statement [ ]
31083114 {
3109- const statements : tstl . Statement [ ] = [ ] ;
3110- if ( ! Array . isArray ( lhs ) ) {
3111- lhs = [ lhs ] ;
3115+ if ( this . shouldExportIdentifier ( lhs ) ) {
3116+ // exported
3117+ if ( Array . isArray ( lhs ) ) {
3118+ return [ tstl . createAssignmentStatement ( lhs . map ( i => this . createExportedIdentifier ( i ) ) , rhs , parent ) ] ;
3119+ } else {
3120+ return [ tstl . createAssignmentStatement ( this . createExportedIdentifier ( lhs ) , rhs , parent ) ] ;
3121+ }
31123122 }
3113- const shouldExport = lhs . some ( i => this . isIdentifierExported ( i . text ) ) ;
3114- if ( shouldExport ) {
3115- statements . push (
3116- tstl . createAssignmentStatement ( lhs . map ( i => this . createExportedIdentifier ( i ) ) , rhs , parent ) ) ;
3117- } else {
3118- // TODO this check probably should be moved out of this function or be improved?
3119- if ( tsOriginal &&
3120- ( ts . isFunctionLike ( tsOriginal ) || tsHelper . findFirstNodeAbove ( tsOriginal , ts . isFunctionLike ) ) ) {
3121- // Separate declaration from assignment to allow for recursion
3122- statements . push ( tstl . createVariableDeclarationStatement ( lhs , undefined , parent ) ) ;
3123- statements . push ( tstl . createAssignmentStatement ( lhs , rhs , parent ) ) ;
3123+
3124+ const insideFunction = this . scopeStack . some ( s => s . type === ScopeType . Function ) ;
3125+ const isLetOrConst = tsOriginal && ts . isVariableDeclaration ( tsOriginal )
3126+ && ( tsOriginal . parent . flags & ( ts . NodeFlags . Let | ts . NodeFlags . Const ) ) !== 0 ;
3127+ if ( this . isModule || this . currentNamespace || insideFunction || isLetOrConst ) {
3128+ // local
3129+ const isFunction =
3130+ tsOriginal
3131+ && ( ts . isFunctionDeclaration ( tsOriginal )
3132+ || ( ts . isVariableDeclaration ( tsOriginal ) && ts . isFunctionLike ( tsOriginal . initializer ) ) ) ;
3133+ if ( isFunction ) {
3134+ // Separate declaration from assignment for functions to allow recursion
3135+ return [
3136+ tstl . createVariableDeclarationStatement ( lhs , undefined , parent , tsOriginal ) ,
3137+ tstl . createAssignmentStatement ( lhs , rhs , parent , tsOriginal ) ,
3138+ ] ;
31243139 } else {
3125- statements . push ( tstl . createVariableDeclarationStatement ( lhs , rhs , parent ) ) ;
3140+ return [ tstl . createVariableDeclarationStatement ( lhs , rhs , parent , tsOriginal ) ] ;
31263141 }
3142+
3143+ } else {
3144+ // global
3145+ return [ tstl . createAssignmentStatement ( lhs , rhs , parent , tsOriginal ) ] ;
31273146 }
3128- return statements ;
31293147 }
31303148
31313149 private validateFunctionAssignment ( node : ts . Node , fromType : ts . Type , toType : ts . Type , toName ?: string ) : void {
0 commit comments