@@ -426,9 +426,8 @@ export class LuaTransformer {
426426 const properties = statement . members . filter ( ts . isPropertyDeclaration ) . filter ( member => member . initializer ) ;
427427
428428 // Divide properties into static and non-static
429- const isStatic = prop => prop . modifiers && prop . modifiers . some ( m => m . kind === ts . SyntaxKind . StaticKeyword ) ;
430- const staticFields = properties . filter ( isStatic ) ;
431- const instanceFields = properties . filter ( prop => ! isStatic ( prop ) ) ;
429+ const staticFields = properties . filter ( tsHelper . isStatic ) ;
430+ const instanceFields = properties . filter ( prop => ! tsHelper . isStatic ( prop ) ) ;
432431
433432 const result : tstl . Statement [ ] = [ ] ;
434433
@@ -605,6 +604,22 @@ export class LuaTransformer {
605604
606605 const createClassNameWithExport = ( ) => this . addExportToIdentifier ( tstl . cloneIdentifier ( className ) ) ;
607606
607+ // className.____getters = {}
608+ if ( statement . members . some ( m => ts . isGetAccessor ( m ) && tsHelper . isStatic ( m ) ) ) {
609+ const classGetters = tstl . createTableIndexExpression (
610+ createClassNameWithExport ( ) ,
611+ tstl . createStringLiteral ( "____getters" )
612+ ) ;
613+ const assignClassGetters = tstl . createAssignmentStatement (
614+ classGetters ,
615+ tstl . createTableExpression ( ) ,
616+ statement
617+ ) ;
618+ result . push ( assignClassGetters ) ;
619+
620+ this . importLuaLibFeature ( LuaLibFeature . ClassIndex ) ;
621+ }
622+
608623 // className.__index = className
609624 const classIndex = tstl . createTableIndexExpression (
610625 createClassNameWithExport ( ) ,
@@ -613,6 +628,22 @@ export class LuaTransformer {
613628 const assignClassIndex = tstl . createAssignmentStatement ( classIndex , createClassNameWithExport ( ) , statement ) ;
614629 result . push ( assignClassIndex ) ;
615630
631+ // className.____setters = {}
632+ if ( statement . members . some ( m => ts . isSetAccessor ( m ) && tsHelper . isStatic ( m ) ) ) {
633+ const classSetters = tstl . createTableIndexExpression (
634+ createClassNameWithExport ( ) ,
635+ tstl . createStringLiteral ( "____setters" )
636+ ) ;
637+ const assignClassSetters = tstl . createAssignmentStatement (
638+ classSetters ,
639+ tstl . createTableExpression ( ) ,
640+ statement
641+ ) ;
642+ result . push ( assignClassSetters ) ;
643+
644+ this . importLuaLibFeature ( LuaLibFeature . ClassNewIndex ) ;
645+ }
646+
616647 // className.prototype = className.prototype or {}
617648 const createClassPrototype = ( ) => tstl . createTableIndexExpression (
618649 createClassNameWithExport ( ) ,
@@ -628,12 +659,8 @@ export class LuaTransformer {
628659 const assignClassPrototype = tstl . createAssignmentStatement ( createClassPrototype ( ) , classPrototypeTable ) ;
629660 result . push ( assignClassPrototype ) ;
630661
631- const classPrototypeIndex = tstl . createTableIndexExpression (
632- createClassPrototype ( ) ,
633- tstl . createStringLiteral ( "__index" )
634- ) ;
635- if ( tsHelper . hasGetAccessorInClassOrAncestor ( statement , this . checker ) ) {
636- // className.prototype.____getters = {}
662+ // className.prototype.____getters = {}
663+ if ( statement . members . some ( m => ts . isGetAccessor ( m ) && ! tsHelper . isStatic ( m ) ) ) {
637664 const classPrototypeGetters = tstl . createTableIndexExpression (
638665 createClassPrototype ( ) ,
639666 tstl . createStringLiteral ( "____getters" )
@@ -643,7 +670,13 @@ export class LuaTransformer {
643670 tstl . createTableExpression ( )
644671 ) ;
645672 result . push ( assignClassPrototypeGetters ) ;
673+ }
646674
675+ const classPrototypeIndex = tstl . createTableIndexExpression (
676+ createClassPrototype ( ) ,
677+ tstl . createStringLiteral ( "__index" )
678+ ) ;
679+ if ( tsHelper . hasGetAccessorInClassOrAncestor ( statement , false , this . checker ) ) {
647680 // className.prototype.__index = __TS_Index(className.prototype)
648681 const assignClassPrototypeIndex = tstl . createAssignmentStatement (
649682 classPrototypeIndex ,
@@ -660,7 +693,7 @@ export class LuaTransformer {
660693 result . push ( assignClassPrototypeIndex ) ;
661694 }
662695
663- if ( tsHelper . hasSetAccessorInClassOrAncestor ( statement , this . checker ) ) {
696+ if ( statement . members . some ( m => ts . isSetAccessor ( m ) && ! tsHelper . isStatic ( m ) ) ) {
664697 // className.prototype.____setters = {}
665698 const classPrototypeSetters = tstl . createTableIndexExpression (
666699 createClassPrototype ( ) ,
@@ -671,7 +704,9 @@ export class LuaTransformer {
671704 tstl . createTableExpression ( )
672705 ) ;
673706 result . push ( assignClassPrototypeSetters ) ;
707+ }
674708
709+ if ( tsHelper . hasSetAccessorInClassOrAncestor ( statement , false , this . checker ) ) {
675710 // className.prototype.__newindex = __TS_NewIndex(className.prototype)
676711 const classPrototypeNewIndex = tstl . createTableIndexExpression (
677712 createClassPrototype ( ) ,
@@ -696,6 +731,9 @@ export class LuaTransformer {
696731 ) ;
697732 result . push ( assignClassPrototypeConstructor ) ;
698733
734+ const hasStaticGetters = tsHelper . hasGetAccessorInClassOrAncestor ( statement , true , this . checker ) ;
735+ const hasStaticSetters = tsHelper . hasSetAccessorInClassOrAncestor ( statement , true , this . checker ) ;
736+
699737 if ( extendsType ) {
700738 const extendedTypeNode = tsHelper . getExtendedTypeNode ( statement , this . checker ) ;
701739 const baseName = this . transformExpression ( extendedTypeNode . expression ) ;
@@ -708,14 +746,51 @@ export class LuaTransformer {
708746 const assignClassBase = tstl . createAssignmentStatement ( createClassBase ( ) , baseName , statement ) ;
709747 result . push ( assignClassBase ) ;
710748
711- // setmetatable(className, className.____super)
712- const setClassMetatable = tstl . createExpressionStatement (
713- tstl . createCallExpression (
714- tstl . createIdentifier ( "setmetatable" ) ,
715- [ createClassNameWithExport ( ) , createClassBase ( ) ]
716- )
717- ) ;
718- result . push ( setClassMetatable ) ;
749+ if ( hasStaticGetters || hasStaticSetters ) {
750+ const metatableFields : tstl . TableFieldExpression [ ] = [ ] ;
751+ if ( hasStaticGetters ) {
752+ // __index = __TS__ClassIndex
753+ metatableFields . push (
754+ tstl . createTableFieldExpression (
755+ tstl . createIdentifier ( "__TS__ClassIndex" ) ,
756+ tstl . createStringLiteral ( "__index" )
757+ )
758+ ) ;
759+ } else {
760+ // __index = className.____super
761+ metatableFields . push (
762+ tstl . createTableFieldExpression ( createClassBase ( ) , tstl . createStringLiteral ( "__index" ) )
763+ ) ;
764+ }
765+
766+ if ( hasStaticSetters ) {
767+ // __newindex = __TS__ClassNewIndex
768+ metatableFields . push (
769+ tstl . createTableFieldExpression (
770+ tstl . createIdentifier ( "__TS__ClassNewIndex" ) ,
771+ tstl . createStringLiteral ( "__newindex" )
772+ )
773+ ) ;
774+ }
775+
776+ const setClassMetatable = tstl . createExpressionStatement (
777+ tstl . createCallExpression (
778+ tstl . createIdentifier ( "setmetatable" ) ,
779+ [ createClassNameWithExport ( ) , tstl . createTableExpression ( metatableFields ) ]
780+ )
781+ ) ;
782+ result . push ( setClassMetatable ) ;
783+
784+ } else {
785+ // setmetatable(className, className.____super)
786+ const setClassMetatable = tstl . createExpressionStatement (
787+ tstl . createCallExpression (
788+ tstl . createIdentifier ( "setmetatable" ) ,
789+ [ createClassNameWithExport ( ) , createClassBase ( ) ]
790+ )
791+ ) ;
792+ result . push ( setClassMetatable ) ;
793+ }
719794
720795 // setmetatable(className.prototype, className.____super.prototype)
721796 const basePrototype = tstl . createTableIndexExpression (
@@ -729,6 +804,36 @@ export class LuaTransformer {
729804 )
730805 ) ;
731806 result . push ( setClassPrototypeMetatable ) ;
807+
808+ } else if ( hasStaticGetters || hasStaticSetters ) {
809+ const metatableFields : tstl . TableFieldExpression [ ] = [ ] ;
810+ if ( hasStaticGetters ) {
811+ // __index = __TS__ClassIndex
812+ metatableFields . push (
813+ tstl . createTableFieldExpression (
814+ tstl . createIdentifier ( "__TS__ClassIndex" ) ,
815+ tstl . createStringLiteral ( "__index" )
816+ )
817+ ) ;
818+ }
819+
820+ if ( hasStaticSetters ) {
821+ // __newindex = __TS__ClassNewIndex
822+ metatableFields . push (
823+ tstl . createTableFieldExpression (
824+ tstl . createIdentifier ( "__TS__ClassNewIndex" ) ,
825+ tstl . createStringLiteral ( "__newindex" )
826+ )
827+ ) ;
828+ }
829+
830+ const setClassMetatable = tstl . createExpressionStatement (
831+ tstl . createCallExpression (
832+ tstl . createIdentifier ( "setmetatable" ) ,
833+ [ createClassNameWithExport ( ) , tstl . createTableExpression ( metatableFields ) ]
834+ )
835+ ) ;
836+ result . push ( setClassMetatable ) ;
732837 }
733838
734839 const newFuncStatements : tstl . Statement [ ] = [ ] ;
@@ -904,12 +1009,13 @@ export class LuaTransformer {
9041009 [ this . createSelfIdentifier ( ) ]
9051010 ) ;
9061011
907- const classPrototype = tstl . createTableIndexExpression (
908- this . addExportToIdentifier ( tstl . cloneIdentifier ( className ) ) ,
909- tstl . createStringLiteral ( "prototype" )
910- ) ;
1012+ const classNameWithExport = this . addExportToIdentifier ( tstl . cloneIdentifier ( className ) ) ;
1013+ const methodTable = tsHelper . isStatic ( getAccessor )
1014+ ? classNameWithExport
1015+ : tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "prototype" ) ) ;
1016+
9111017 const classGetters = tstl . createTableIndexExpression (
912- classPrototype ,
1018+ methodTable ,
9131019 tstl . createStringLiteral ( "____getters" )
9141020 ) ;
9151021 const getter = tstl . createTableIndexExpression (
@@ -938,12 +1044,13 @@ export class LuaTransformer {
9381044 restParam
9391045 ) ;
9401046
941- const classPrototype = tstl . createTableIndexExpression (
942- this . addExportToIdentifier ( tstl . cloneIdentifier ( className ) ) ,
943- tstl . createStringLiteral ( "prototype" )
944- ) ;
1047+ const classNameWithExport = this . addExportToIdentifier ( tstl . cloneIdentifier ( className ) ) ;
1048+ const methodTable = tsHelper . isStatic ( setAccessor )
1049+ ? classNameWithExport
1050+ : tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "prototype" ) ) ;
1051+
9451052 const classSetters = tstl . createTableIndexExpression (
946- classPrototype ,
1053+ methodTable ,
9471054 tstl . createStringLiteral ( "____setters" )
9481055 ) ;
9491056 const setter = tstl . createTableIndexExpression (
@@ -957,7 +1064,7 @@ export class LuaTransformer {
9571064 public transformMethodDeclaration (
9581065 node : ts . MethodDeclaration ,
9591066 className : tstl . Identifier ,
960- usePrototype : boolean
1067+ noPrototype : boolean
9611068 ) : tstl . AssignmentStatement
9621069 {
9631070 // Don't transform methods without body (overload declarations)
@@ -984,9 +1091,8 @@ export class LuaTransformer {
9841091 restParamName
9851092 ) ;
9861093
987- const isStatic = node . modifiers && node . modifiers . some ( m => m . kind === ts . SyntaxKind . StaticKeyword ) ;
9881094 const classNameWithExport = this . addExportToIdentifier ( tstl . cloneIdentifier ( className ) ) ;
989- const methodTable = isStatic || usePrototype
1095+ const methodTable = tsHelper . isStatic ( node ) || noPrototype
9901096 ? classNameWithExport
9911097 : tstl . createTableIndexExpression ( classNameWithExport , tstl . createStringLiteral ( "prototype" ) ) ;
9921098
0 commit comments