@@ -5,6 +5,7 @@ import { TSHelper as tsHelper } from "./TSHelper";
55
66import * as fs from "fs" ;
77import * as path from "path" ;
8+ import { DecoratorKind } from "./Decorator" ;
89
910/* tslint:disable */
1011const packageJSON = require ( "../package.json" ) ;
@@ -343,8 +344,9 @@ export abstract class LuaTranspiler {
343344 }
344345
345346 public transpileNamespace ( node : ts . ModuleDeclaration ) : string {
347+ const decorators = tsHelper . getCustomDecorators ( this . checker . getTypeAtLocation ( node ) , this . checker ) ;
346348 // If phantom namespace just transpile the body as normal
347- if ( tsHelper . isPhantom ( this . checker . getTypeAtLocation ( node ) , this . checker ) && node . body ) {
349+ if ( decorators . has ( DecoratorKind . Phantom ) && node . body ) {
348350 return this . transpileNode ( node . body ) ;
349351 }
350352
@@ -376,7 +378,8 @@ export abstract class LuaTranspiler {
376378 let result = "" ;
377379
378380 const type = this . checker . getTypeAtLocation ( node ) ;
379- const membersOnly = tsHelper . isCompileMembersOnlyEnum ( type , this . checker ) ;
381+ const membersOnly = tsHelper . getCustomDecorators ( type , this . checker )
382+ . has ( DecoratorKind . CompileMembersOnly ) ;
380383
381384 if ( ! membersOnly ) {
382385 const name = this . transpileIdentifier ( node . name ) ;
@@ -681,8 +684,15 @@ export abstract class LuaTranspiler {
681684 // If parent function is a TupleReturn function
682685 // and return expression is an array literal, leave out brackets.
683686 const declaration = tsHelper . findFirstNodeAbove ( node , ts . isFunctionDeclaration ) ;
684- if ( declaration && tsHelper . isTupleReturnFunction ( this . checker . getTypeAtLocation ( declaration ) , this . checker )
685- && ts . isArrayLiteralExpression ( node . expression ) ) {
687+ let isTupleReturn = false ;
688+ if ( declaration ) {
689+ const decorators = tsHelper . getCustomDecorators (
690+ this . checker . getTypeAtLocation ( declaration ) ,
691+ this . checker
692+ ) ;
693+ isTupleReturn = decorators . has ( DecoratorKind . TupleReturn ) ;
694+ }
695+ if ( isTupleReturn && ts . isArrayLiteralExpression ( node . expression ) ) {
686696 return "return " + node . expression . elements . map ( elem => this . transpileExpression ( elem ) ) . join ( "," ) ;
687697 }
688698
@@ -1030,8 +1040,18 @@ export abstract class LuaTranspiler {
10301040 public transpileNewExpression ( node : ts . NewExpression ) : string {
10311041 const name = this . transpileExpression ( node . expression ) ;
10321042 const params = node . arguments ? this . transpileArguments ( node . arguments , ts . createTrue ( ) ) : "true" ;
1043+ const type = this . checker . getTypeAtLocation ( node ) ;
1044+ const classDecorators = tsHelper . getCustomDecorators ( type , this . checker ) ;
10331045
1034- this . checkForLuaLibType ( this . checker . getTypeAtLocation ( node ) ) ;
1046+ this . checkForLuaLibType ( type ) ;
1047+
1048+ if ( classDecorators . has ( DecoratorKind . CustomConstructor ) ) {
1049+ const customDecorator = classDecorators . get ( DecoratorKind . CustomConstructor ) ;
1050+ if ( ! customDecorator . args [ 0 ] ) {
1051+ throw new TranspileError ( "!CustomConstructor requires one argument" , node ) ;
1052+ }
1053+ return `${ customDecorator . args [ 0 ] } (${ this . transpileArguments ( node . arguments ) } )` ;
1054+ }
10351055
10361056 return `${ name } .new(${ params } )` ;
10371057 }
@@ -1246,8 +1266,9 @@ export abstract class LuaTranspiler {
12461266
12471267 this . checkForLuaLibType ( type ) ;
12481268
1269+ const decorators = tsHelper . getCustomDecorators ( type , this . checker ) ;
12491270 // Do not output path for member only enums
1250- if ( tsHelper . isCompileMembersOnlyEnum ( type , this . checker ) ) {
1271+ if ( decorators . has ( DecoratorKind . CompileMembersOnly ) ) {
12511272 return property ;
12521273 }
12531274
@@ -1537,8 +1558,19 @@ export abstract class LuaTranspiler {
15371558
15381559 let className = this . transpileIdentifier ( node . name ) ;
15391560
1561+ const decorators = tsHelper . getCustomDecorators ( this . checker . getTypeAtLocation ( node ) , this . checker ) ;
1562+
15401563 // Find out if this class is extension of existing class
1541- const isExtension = tsHelper . isExtensionClass ( this . checker . getTypeAtLocation ( node ) , this . checker ) ;
1564+ const isExtension = decorators . has ( DecoratorKind . Extension ) ;
1565+
1566+ const isMetaExtension = decorators . has ( DecoratorKind . MetaExtension ) ;
1567+
1568+ if ( isExtension && isMetaExtension ) {
1569+ throw new TranspileError (
1570+ "Can't use both decorators '!Extension' and '!MetaExtension' on the same class." ,
1571+ node
1572+ ) ;
1573+ }
15421574
15431575 // Get type that is extended
15441576 const extendsType = tsHelper . getExtendedType ( node , this . checker ) ;
@@ -1554,16 +1586,33 @@ export abstract class LuaTranspiler {
15541586
15551587 let result = "" ;
15561588
1557- if ( ! isExtension ) {
1589+ if ( ! isExtension && ! isMetaExtension ) {
15581590 result += this . transpileClassCreationMethods ( node , instanceFields , extendsType ) ;
15591591 } else {
15601592 // export empty table
15611593 this . pushExport ( className , node , true ) ;
15621594 }
15631595
15641596 // Overwrite the original className with the class we are overriding for extensions
1565- if ( isExtension && extendsType ) {
1566- className = extendsType . symbol . escapedName as string ;
1597+ if ( isMetaExtension ) {
1598+ if ( ! extendsType ) {
1599+ throw new TranspileError (
1600+ "!MetaExtension requires the base class to have the name of the metatable beeing extended." ,
1601+ node
1602+ ) ;
1603+ }
1604+ const extendsName = extendsType . symbol . escapedName as string ;
1605+ className = "__meta__" + extendsName ;
1606+ result += `local ${ className } = debug.getregistry()["${ extendsName } "]\n` ;
1607+ }
1608+
1609+ if ( isExtension ) {
1610+ const extensionNameArg = decorators . get ( DecoratorKind . Extension ) . args [ 0 ] ;
1611+ if ( extensionNameArg ) {
1612+ className = extensionNameArg ;
1613+ } else if ( extendsType ) {
1614+ className = extendsType . symbol . escapedName as string ;
1615+ }
15671616 }
15681617
15691618 // Add static declarations
@@ -1606,7 +1655,11 @@ export abstract class LuaTranspiler {
16061655 extendsType : ts . Type ) : string {
16071656 const className = this . transpileIdentifier ( node . name ) ;
16081657
1609- const noClassOr = extendsType && tsHelper . hasCustomDecorator ( extendsType , this . checker , "!NoClassOr" ) ;
1658+ let noClassOr = false ;
1659+ if ( extendsType ) {
1660+ const decorators = tsHelper . getCustomDecorators ( extendsType , this . checker ) ;
1661+ noClassOr = decorators . has ( DecoratorKind . NoClassOr ) ;
1662+ }
16101663
16111664 let result = "" ;
16121665
0 commit comments