@@ -25,14 +25,14 @@ interface SymbolInfo {
2525}
2626
2727interface FunctionDefinitionInfo {
28- referencedSymbols : Set < tstl . SymbolId > ;
28+ referencedSymbols : Map < tstl . SymbolId , ts . Node [ ] > ;
2929 definition ?: tstl . VariableDeclarationStatement | tstl . AssignmentStatement ;
3030}
3131
3232interface Scope {
3333 type : ScopeType ;
3434 id : number ;
35- referencedSymbols ?: Set < tstl . SymbolId > ;
35+ referencedSymbols ?: Map < tstl . SymbolId , ts . Node [ ] > ;
3636 variableDeclarations ?: tstl . VariableDeclarationStatement [ ] ;
3737 functionDefinitions ?: Map < tstl . SymbolId , FunctionDefinitionInfo > ;
3838 importStatements ?: tstl . Statement [ ] ;
@@ -1388,12 +1388,31 @@ export class LuaTransformer {
13881388 return [ paramNames , dotsLiteral , restParamName ] ;
13891389 }
13901390
1391+ protected isRestParameterReferenced ( identifier : tstl . Identifier , scope : Scope ) : boolean {
1392+ if ( ! identifier . symbolId ) {
1393+ return true ;
1394+ }
1395+ if ( scope . referencedSymbols === undefined ) {
1396+ return false ;
1397+ }
1398+ const references = scope . referencedSymbols . get ( identifier . symbolId ) ;
1399+ if ( ! references ) {
1400+ return false ;
1401+ }
1402+ // Ignore references to @vararg types in spread elements
1403+ return references . some (
1404+ r => ! r . parent || ! ts . isSpreadElement ( r . parent ) || ! tsHelper . isVarArgType ( r , this . checker )
1405+ ) ;
1406+ }
1407+
13911408 protected transformFunctionBody (
13921409 parameters : ts . NodeArray < ts . ParameterDeclaration > ,
13931410 body : ts . Block ,
13941411 spreadIdentifier ?: tstl . Identifier
13951412 ) : [ tstl . Statement [ ] , Scope ] {
13961413 this . pushScope ( ScopeType . Function ) ;
1414+ const bodyStatements = this . performHoisting ( this . transformStatements ( body . statements ) ) ;
1415+ const scope = this . popScope ( ) ;
13971416
13981417 const headerStatements = [ ] ;
13991418
@@ -1426,18 +1445,14 @@ export class LuaTransformer {
14261445 }
14271446
14281447 // Push spread operator here
1429- if ( spreadIdentifier ) {
1448+ if ( spreadIdentifier && this . isRestParameterReferenced ( spreadIdentifier , scope ) ) {
14301449 const spreadTable = this . wrapInTable ( tstl . createDotsLiteral ( ) ) ;
14311450 headerStatements . push ( tstl . createVariableDeclarationStatement ( spreadIdentifier , spreadTable ) ) ;
14321451 }
14331452
14341453 // Binding pattern statements need to be after spread table is declared
14351454 headerStatements . push ( ...bindingPatternDeclarations ) ;
14361455
1437- const bodyStatements = this . performHoisting ( this . transformStatements ( body . statements ) ) ;
1438-
1439- const scope = this . popScope ( ) ;
1440-
14411456 return [ headerStatements . concat ( bodyStatements ) , scope ] ;
14421457 }
14431458
@@ -1844,7 +1859,7 @@ export class LuaTransformer {
18441859 if ( ! scope . functionDefinitions ) {
18451860 scope . functionDefinitions = new Map ( ) ;
18461861 }
1847- const functionInfo = { referencedSymbols : functionScope . referencedSymbols || new Set ( ) } ;
1862+ const functionInfo = { referencedSymbols : functionScope . referencedSymbols || new Map ( ) } ;
18481863 scope . functionDefinitions . set ( name . symbolId , functionInfo ) ;
18491864 }
18501865 return this . createLocalOrExportedOrGlobalDeclaration ( name , functionExpression , functionDeclaration ) ;
@@ -4603,6 +4618,10 @@ export class LuaTransformer {
46034618 return innerExpression ;
46044619 }
46054620
4621+ if ( ts . isIdentifier ( expression . expression ) && tsHelper . isVarArgType ( expression . expression , this . checker ) ) {
4622+ return tstl . createDotsLiteral ( expression ) ;
4623+ }
4624+
46064625 const type = this . checker . getTypeAtLocation ( expression . expression ) ;
46074626 if ( tsHelper . isArrayType ( type , this . checker , this . program ) ) {
46084627 return this . createUnpackCall ( innerExpression , expression ) ;
@@ -5278,13 +5297,20 @@ export class LuaTransformer {
52785297 if ( declaration && identifier . pos < declaration . pos ) {
52795298 throw TSTLErrors . ReferencedBeforeDeclaration ( identifier ) ;
52805299 }
5281- } else if ( symbolId !== undefined ) {
5300+ }
5301+
5302+ if ( symbolId !== undefined ) {
52825303 //Mark symbol as seen in all current scopes
52835304 for ( const scope of this . scopeStack ) {
52845305 if ( ! scope . referencedSymbols ) {
5285- scope . referencedSymbols = new Set ( ) ;
5306+ scope . referencedSymbols = new Map ( ) ;
5307+ }
5308+ let references = scope . referencedSymbols . get ( symbolId ) ;
5309+ if ( ! references ) {
5310+ references = [ ] ;
5311+ scope . referencedSymbols . set ( symbolId , references ) ;
52865312 }
5287- scope . referencedSymbols . add ( symbolId ) ;
5313+ references . push ( identifier ) ;
52885314 }
52895315 }
52905316 }
0 commit comments