@@ -184,6 +184,34 @@ export abstract class LuaTranspiler {
184184 return filePath . replace ( new RegExp ( "\\\\|\/" , "g" ) , "." ) ;
185185 }
186186
187+ public computeEnumMembers ( node : ts . EnumDeclaration ) : Array < { name : string , value : string | number } > {
188+ let val : number | string = 0 ;
189+ let hasStringInitializers = false ;
190+
191+ return node . members . map ( member => {
192+ if ( member . initializer ) {
193+ if ( ts . isNumericLiteral ( member . initializer ) ) {
194+ val = parseInt ( member . initializer . text ) ;
195+ } else if ( ts . isStringLiteral ( member . initializer ) ) {
196+ hasStringInitializers = true ;
197+ val = `"${ member . initializer . text } "` ;
198+ } else {
199+ throw TSTLErrors . InvalidEnumMember ( member . initializer ) ;
200+ }
201+ } else if ( hasStringInitializers ) {
202+ throw TSTLErrors . HeterogeneousEnum ( node ) ;
203+ }
204+
205+ const enumMember = { name : this . transpileIdentifier ( member . name as ts . Identifier ) , value : val } ;
206+
207+ if ( typeof val === "number" ) {
208+ val ++ ;
209+ }
210+
211+ return enumMember ;
212+ } ) ;
213+ }
214+
187215 // Transpile a source file
188216 public transpileSourceFile ( ) : string {
189217 let header = "" ;
@@ -393,48 +421,36 @@ export abstract class LuaTranspiler {
393421 }
394422
395423 public transpileEnum ( node : ts . EnumDeclaration ) : string {
396- let val : number | string = 0 ;
397- let result = "" ;
398-
399424 const type = this . checker . getTypeAtLocation ( node ) ;
425+
426+ // Const enums should never appear in the resulting code
427+ if ( type . symbol . getFlags ( ) & ts . SymbolFlags . ConstEnum ) {
428+ return "" ;
429+ }
430+
400431 const membersOnly = tsHelper . getCustomDecorators ( type , this . checker )
401432 . has ( DecoratorKind . CompileMembersOnly ) ;
402433
434+ let result = "" ;
435+
403436 if ( ! membersOnly ) {
404437 const name = this . transpileIdentifier ( node . name ) ;
405438 result += this . indent + this . accessPrefix ( node ) + `${ name } ={}\n` ;
406439 this . pushExport ( name , node ) ;
407440 }
408441
409- let hasStringInitializers = false ;
410- node . members . forEach ( member => {
411- if ( member . initializer ) {
412- if ( ts . isNumericLiteral ( member . initializer ) ) {
413- val = parseInt ( member . initializer . text ) ;
414- } else if ( ts . isStringLiteral ( member . initializer ) ) {
415- hasStringInitializers = true ;
416- val = `"${ member . initializer . text } "` ;
417- } else {
418- throw TSTLErrors . InvalidEnumMember ( member . initializer ) ;
419- }
420- } else if ( hasStringInitializers ) {
421- throw TSTLErrors . HeterogeneousEnum ( node ) ;
422- }
423-
442+ this . computeEnumMembers ( node ) . forEach ( enumMember => {
424443 if ( membersOnly ) {
425- const defName = this . definitionName ( this . transpileIdentifier ( member . name as ts . Identifier ) ) ;
426- result += this . indent + `${ defName } =${ val } \n` ;
444+ const defName = this . definitionName ( enumMember . name ) ;
445+ result += this . indent + `${ defName } =${ enumMember . value } \n` ;
427446 } else {
428447 const defName = this . definitionName (
429- `${ this . transpileIdentifier ( node . name ) } .${ this . transpileIdentifier ( ( member . name as ts . Identifier ) ) } `
448+ `${ this . transpileIdentifier ( node . name ) } .${ enumMember . name } `
430449 ) ;
431- result += this . indent + `${ defName } =${ val } \n` ;
432- }
433-
434- if ( typeof val === "number" ) {
435- val ++ ;
450+ result += this . indent + `${ defName } =${ enumMember . value } \n` ;
436451 }
437452 } ) ;
453+
438454 return result ;
439455 }
440456
@@ -1408,6 +1424,33 @@ export abstract class LuaTranspiler {
14081424 }
14091425 }
14101426
1427+ if ( type . symbol && ( type . symbol . flags & ts . SymbolFlags . ConstEnum ) ) {
1428+ const propertyValueDeclaration = this . checker . getTypeAtLocation ( node ) . symbol . valueDeclaration ;
1429+
1430+ if ( propertyValueDeclaration && propertyValueDeclaration . kind === ts . SyntaxKind . EnumMember ) {
1431+ const enumMember = propertyValueDeclaration as ts . EnumMember ;
1432+
1433+ if ( enumMember . initializer ) {
1434+ return this . transpileExpression ( enumMember . initializer ) ;
1435+ } else {
1436+ const enumMembers = this . computeEnumMembers ( enumMember . parent ) ;
1437+ const memberPosition = enumMember . parent . members . indexOf ( enumMember ) ;
1438+
1439+ if ( memberPosition === - 1 ) {
1440+ throw TSTLErrors . UnsupportedProperty ( type . symbol . name , property , node ) ;
1441+ }
1442+
1443+ const value = enumMembers [ memberPosition ] . value ;
1444+
1445+ if ( typeof value === "string" ) {
1446+ return `"${ value } "` ;
1447+ }
1448+
1449+ return value . toString ( ) ;
1450+ }
1451+ }
1452+ }
1453+
14111454 this . checkForLuaLibType ( type ) ;
14121455
14131456 const decorators = tsHelper . getCustomDecorators ( type , this . checker ) ;
0 commit comments