@@ -90,6 +90,13 @@ const typeLiteralNames = new Map<TypeLiteralNode, string>();
90
90
const intersected = new Map < string , ( InterfaceDeclaration | TypeLiteralNode ) [ ] > ( ) ;
91
91
const unionTypes = new Set < string > ( ) ;
92
92
93
+ const javaKeywords = [ 'abstract' , 'assert' , 'boolean' , 'break' , 'byte' , 'case' , 'catch' , 'char' ,
94
+ 'class' , 'const' , 'continue' , 'default' , 'do' , 'double' , 'else' , 'enum' , 'extends' , 'final' ,
95
+ 'finally' , 'float' , 'for' , 'goto' , 'if' , 'implements' , 'import' , 'instanceof' , 'int' , 'interface' ,
96
+ 'long' , 'native' , 'new' , 'package' , 'private' , 'protected' , 'public' , 'return' , 'short' , 'static' ,
97
+ 'strictfp' , 'super' , 'switch' , 'synchronized' , 'this' , 'throw' , 'throws' , 'transient' , 'try' ,
98
+ 'void' , 'volatile' , 'while' , 'true' , 'false' , 'null' ] ;
99
+
93
100
const numberTypes = new Map < string , string > ( ) ;
94
101
numberTypes . set ( 'Color' , 'double' ) ; //TODO: make configurable
95
102
@@ -280,6 +287,7 @@ function getClassText(declNode: DeclarationStatement, moduleNode: ModuleDeclarat
280
287
if ( isAbstract ) {
281
288
text += 'public abstract class ' + clsName + ' extends JSONBase {\n' ;
282
289
} else {
290
+ const allTypeNodes : ( InterfaceDeclaration | TypeLiteralNode ) [ ] = [ ] ;
283
291
let extendedType : InterfaceDeclaration ;
284
292
text += 'public class ' + clsName ;
285
293
if ( declNodes [ 0 ] . kind === SyntaxKind . InterfaceDeclaration && ( declNodes [ 0 ] as InterfaceDeclaration ) . heritageClauses ) {
@@ -330,13 +338,14 @@ function getClassText(declNode: DeclarationStatement, moduleNode: ModuleDeclarat
330
338
}
331
339
332
340
// members
333
- let optionalProperties = unionTypes . has ( clsName ) ? new Set < PropertySignature > ( ) : undefined ;
334
- text += getClassMembersText ( clsName , getMembers ( declNodes , optionalProperties ) , isAbstract , typeParams , optionalProperties ) ;
341
+ const props = new Map < string , PropertySignature > ( ) ;
342
+ const nested = new Set < TypeLiteralNode > ( ) ;
343
+ const overridenProperties = new Map < string , PropertySignature > ( ) ;
344
+ findProperties ( declNodes , props , overridenProperties , nested ) ;
345
+ const optionalProperties = unionTypes . has ( clsName ) ? new Set < PropertySignature > ( ) : undefined ;
346
+ text += getClassMembersText ( clsName , getMembers ( declNodes , optionalProperties ) , isAbstract , typeParams , overridenProperties , optionalProperties ) ;
335
347
if ( ! isAbstract ) {
336
348
seedrandom ( clsName , { global : true } ) ;
337
- const props = new Map < string , PropertySignature > ( ) ;
338
- const nested = new Set < TypeLiteralNode > ( ) ;
339
- findProperties ( declNodes , props , nested ) ;
340
349
// equals
341
350
text += getEqualsText ( clsName , props ) ;
342
351
// hashCode
@@ -381,12 +390,12 @@ function getClassText(declNode: DeclarationStatement, moduleNode: ModuleDeclarat
381
390
return importsText + text ;
382
391
}
383
392
384
- function getClassMembersText ( typeName : string , members : TypeElement [ ] , isAbstract : boolean , typeParams : Map < string , TypeNode | string > , optionalProperties ?:Set < PropertySignature > ) : string {
393
+ function getClassMembersText ( typeName : string , members : TypeElement [ ] , isAbstract : boolean , typeParams : Map < string , TypeNode | string > , overridenProperties : Map < string , PropertySignature > , optionalProperties ?:Set < PropertySignature > ) : string {
385
394
let text : string = '' ;
386
395
members . forEach ( ( element : TypeElement ) => {
387
396
switch ( element . kind ) {
388
397
case SyntaxKind . PropertySignature :
389
- text += getPropertyText ( typeName , element as PropertySignature , isAbstract , typeParams , optionalProperties ) ;
398
+ text += getPropertyText ( typeName , element as PropertySignature , isAbstract , typeParams , overridenProperties , optionalProperties ) ;
390
399
break ;
391
400
case SyntaxKind . MethodSignature :
392
401
text += getMethodSignatureText ( < MethodSignature > element ) ;
@@ -551,6 +560,10 @@ function getNestedTypesText(types: Set<TypeLiteralNode>, typeParams: Map<string,
551
560
text += ( line . length > 0 ? indent . repeat ( indentLevel ) + line : line ) + '\n' ;
552
561
} ) ;
553
562
}
563
+ text += '\n' + indent ;
564
+ getDefaultCreatorText ( name , props ) . trim ( ) . split ( '\n' ) . forEach ( ( line : string ) => {
565
+ text += ( line . length > 0 ? indent . repeat ( indentLevel ) + line : line ) + '\n' ;
566
+ } ) ;
554
567
if ( nested . size > 0 ) {
555
568
text += getNestedTypesText ( nested , typeParams , indentLevel + 1 ) ;
556
569
}
@@ -560,7 +573,11 @@ function getNestedTypesText(types: Set<TypeLiteralNode>, typeParams: Map<string,
560
573
return text ;
561
574
}
562
575
563
- function getPropertyText ( clsName : string , node : PropertySignature , isAbstract : boolean , typeParams : Map < string , TypeNode | string > , optionalProperties ?:Set < PropertySignature > ) : string {
576
+ function getPropertyText ( clsName : string , node : PropertySignature , isAbstract : boolean , typeParams : Map < string , TypeNode | string > , overridenProperties ?:Map < string , PropertySignature > , optionalProperties ?:Set < PropertySignature > ) : string {
577
+ let overriden : boolean = false ;
578
+ if ( overridenProperties && overridenProperties . has ( node . name . getText ( ) ) ) {
579
+ overriden = true ;
580
+ }
564
581
let text : string = '\n' ;
565
582
let comment = getComment ( node , 1 ) ;
566
583
if ( comment ) {
@@ -604,6 +621,13 @@ function getPropertyText(clsName: string, node: PropertySignature, isAbstract: b
604
621
if ( type === 'Boolean' ) {
605
622
text += indent + '@SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL")\n' ;
606
623
}
624
+ if ( overriden ) {
625
+ let overridenType : Node = findType ( overridenProperties . get ( node . name . getText ( ) ) . type ) ;
626
+ if ( ( optional ? getBoxedType ( overridenType ) : getJavaType ( overridenType ) ) === type ) {
627
+ return '' ;
628
+ }
629
+ text += indent + '@Override\n' ;
630
+ }
607
631
const key : string = '"' + node . name . getText ( ) + '"' ;
608
632
if ( isAbstract ) {
609
633
text += indent + 'public abstract ' + type + ' ' + getterNameFor ( node . name . getText ( ) , type ) + '();\n' ;
@@ -1027,8 +1051,9 @@ function getDefaultCreatorText(type: string, props: Map<string, PropertySignatur
1027
1051
if ( params ) {
1028
1052
params += ', ' ;
1029
1053
}
1030
- params += getBoxedType ( propType ) + ' ' + propName ;
1031
- body += creatorPropInit ( prop , propName , propName , propType , type + '.create' ) ;
1054
+ let paramName = varNameFor ( propName ) ;
1055
+ params += getBoxedType ( propType ) + ' ' + paramName ;
1056
+ body += creatorPropInit ( prop , propName , paramName , propType , type + '.create' ) ;
1032
1057
}
1033
1058
}
1034
1059
}
@@ -1633,11 +1658,14 @@ function getHash(node: Node): string {
1633
1658
}
1634
1659
1635
1660
function varNameFor ( type : string ) : string {
1636
- return type . charAt ( 0 ) . toLowerCase ( ) + type . slice ( 1 ) ;
1661
+ if ( javaKeywords . includes ( type ) ) {
1662
+ return type + 'Value' ;
1663
+ }
1664
+ return removeUnderscores ( type . charAt ( 0 ) . toLowerCase ( ) + type . slice ( 1 ) ) ;
1637
1665
}
1638
1666
1639
1667
function valueNameFor ( type : string ) : string {
1640
- return varNameFor ( type ) + 'Value' ;
1668
+ return removeUnderscores ( type . charAt ( 0 ) . toLowerCase ( ) + type . slice ( 1 ) + 'Value' ) ;
1641
1669
}
1642
1670
1643
1671
function unionInfoGetter ( unionInfo :{ typeRef : TypeReferenceNode ; enumRef : TypeReferenceNode ; arrType : ArrayTypeNode } , varName : string , resultPrefix : string , resultSuffix :string , hasNull : boolean , baseIndent : number ) : string {
@@ -1706,19 +1734,34 @@ function unionInfoSetter(unionInfo:{typeRef: TypeReferenceNode; enumRef: TypeRef
1706
1734
}
1707
1735
1708
1736
function getterNameFor ( name : string , type : string ) : string {
1737
+ name = removeUnderscores ( name ) ;
1709
1738
if ( type === 'boolean' ) {
1710
1739
return name . startsWith ( 'is' ) ? name : 'is' + name . charAt ( 0 ) . toUpperCase ( ) + name . slice ( 1 ) ;
1711
1740
}
1712
1741
return 'get' + name . charAt ( 0 ) . toUpperCase ( ) + name . slice ( 1 ) ;
1713
1742
}
1714
1743
1715
1744
function setterNameFor ( name : string , type : string ) : string {
1745
+ name = removeUnderscores ( name ) ;
1716
1746
if ( type === 'boolean' && name . startsWith ( 'is' ) && name . length > 2 ) {
1717
1747
return 'set' + name . charAt ( 2 ) . toUpperCase ( ) + name . slice ( 3 ) ;
1718
1748
}
1719
1749
return 'set' + name . charAt ( 0 ) . toUpperCase ( ) + name . slice ( 1 ) ;
1720
1750
}
1721
1751
1752
+ function removeUnderscores ( s : string ) : string {
1753
+ for ( let idx = s . indexOf ( '_' ) ; idx >= 0 ; idx = s . indexOf ( '_' ) ) {
1754
+ if ( idx === 0 ) {
1755
+ s = s . slice ( 1 ) ;
1756
+ } else if ( idx < s . length - 1 ) {
1757
+ s = s . slice ( 0 , idx ) + s . charAt ( idx + 1 ) . toUpperCase ( ) + s . slice ( idx + 2 ) ;
1758
+ } else {
1759
+ s = s . slice ( 0 , idx ) ;
1760
+ }
1761
+ }
1762
+ return s ;
1763
+ }
1764
+
1722
1765
function suffixFor ( name : string ) : string {
1723
1766
for ( let i = name . length - 1 ; i >= 0 ; i -- ) {
1724
1767
if ( name . charAt ( i ) . toUpperCase ( ) === name . charAt ( i ) ) {
@@ -2023,12 +2066,14 @@ function getMembers(decls: (InterfaceDeclaration | TypeLiteralNode)[], optionalP
2023
2066
return members ;
2024
2067
}
2025
2068
2026
- function findProperties ( decls : ( InterfaceDeclaration | TypeLiteralNode ) [ ] , props : Map < string , PropertySignature > , nested : Set < TypeLiteralNode > ) : void {
2069
+ function findProperties ( decls : ( InterfaceDeclaration | TypeLiteralNode ) [ ] , props : Map < string , PropertySignature > , overridenProperties : Map < string , PropertySignature > , nested : Set < TypeLiteralNode > ) : void {
2027
2070
getMembers ( decls ) . forEach ( ( member : TypeElement ) => {
2028
2071
if ( member . kind === SyntaxKind . PropertySignature ) {
2029
2072
let memberName : string = member . name . getText ( ) ;
2030
2073
if ( ! props . has ( memberName ) ) {
2031
2074
props . set ( memberName , member as PropertySignature ) ;
2075
+ } else {
2076
+ overridenProperties . set ( memberName , member as PropertySignature ) ;
2032
2077
}
2033
2078
if ( nested ) {
2034
2079
let memberType = ( member as PropertySignature ) . type ;
@@ -2054,7 +2099,7 @@ function findProperties(decls: (InterfaceDeclaration | TypeLiteralNode)[], props
2054
2099
}
2055
2100
} ) ;
2056
2101
if ( ! hasMethods ) {
2057
- findProperties ( [ extDecl ] , props , null ) ;
2102
+ findProperties ( [ extDecl ] , props , overridenProperties , null ) ;
2058
2103
}
2059
2104
}
2060
2105
} ) ;
0 commit comments