@@ -12,6 +12,7 @@ import { getReferencedDocParams, parseSymbolDocumentation } from './docs';
1212import { Diagnostic , EmitResult , Emitter } from './emitter' ;
1313import literate = require( './literate' ) ;
1414import { ProjectInfo } from './project-info' ;
15+ import { isReservedName } from './reserved-words' ;
1516import { Validator } from './validator' ;
1617import { SHORT_VERSION , VERSION } from './version' ;
1718
@@ -91,7 +92,7 @@ export class Assembler implements Emitter {
9192 // Clearing ``this._types`` to allow contents to be garbage-collected.
9293 delete this . _types ;
9394 try {
94- return { diagnostics : this . _diagnostics , hasErrors : true } ;
95+ return { diagnostics : this . _diagnostics , emitSkipped : true } ;
9596 } finally {
9697 // Clearing ``this._diagnostics`` to allow contents to be garbage-collected.
9798 delete this . _diagnostics ;
@@ -124,7 +125,7 @@ export class Assembler implements Emitter {
124125
125126 const validator = new Validator ( this . projectInfo , assembly ) ;
126127 const validationResult = await validator . emit ( ) ;
127- if ( ! validationResult . hasErrors ) {
128+ if ( ! validationResult . emitSkipped ) {
128129 const assemblyPath = path . join ( this . projectInfo . projectRoot , '.jsii' ) ;
129130 LOG . trace ( `Emitting assembly: ${ colors . blue ( assemblyPath ) } ` ) ;
130131 await fs . writeJson ( assemblyPath , _fingerprint ( assembly ) , { encoding : 'utf8' , spaces : 2 } ) ;
@@ -133,7 +134,7 @@ export class Assembler implements Emitter {
133134 try {
134135 return {
135136 diagnostics : [ ...this . _diagnostics , ...validationResult . diagnostics ] ,
136- hasErrors : validationResult . hasErrors
137+ emitSkipped : validationResult . emitSkipped
137138 } ;
138139 } finally {
139140 // Clearing ``this._types`` to allow contents to be garbage-collected.
@@ -439,6 +440,8 @@ export class Assembler implements Emitter {
439440 return undefined ;
440441 }
441442
443+ this . _warnAboutReservedWords ( type . symbol ) ;
444+
442445 const fqn = `${ [ this . projectInfo . name , ...ctx . namespace ] . join ( '.' ) } .${ type . symbol . name } ` ;
443446
444447 const jsiiType : spec . ClassType = {
@@ -747,6 +750,8 @@ export class Assembler implements Emitter {
747750 return undefined ;
748751 }
749752
753+ this . _warnAboutReservedWords ( type . symbol ) ;
754+
750755 const decl = symbol . valueDeclaration ;
751756 const flags = ts . getCombinedModifierFlags ( decl ) ;
752757 // tslint:disable-next-line:no-bitwise
@@ -822,6 +827,8 @@ export class Assembler implements Emitter {
822827 return undefined ;
823828 }
824829
830+ this . _warnAboutReservedWords ( type . symbol ) ;
831+
825832 const fqn = `${ [ this . projectInfo . name , ...ctx . namespace ] . join ( '.' ) } .${ type . symbol . name } ` ;
826833
827834 const jsiiType : spec . InterfaceType = {
@@ -954,6 +961,8 @@ export class Assembler implements Emitter {
954961 this . _diagnostic ( declaration , ts . DiagnosticCategory . Error , `Prohibited member name: ${ symbol . name } ` ) ;
955962 return ;
956963 }
964+ this . _warnAboutReservedWords ( symbol ) ;
965+
957966 const parameters = await Promise . all ( signature . getParameters ( ) . map ( p => this . _toParameter ( p , ctx ) ) ) ;
958967
959968 const returnType = signature . getReturnType ( ) ;
@@ -1006,6 +1015,16 @@ export class Assembler implements Emitter {
10061015 type . methods . push ( method ) ;
10071016 }
10081017
1018+ private _warnAboutReservedWords ( symbol : ts . Symbol ) {
1019+ const reservingLanguages = isReservedName ( symbol . name ) ;
1020+ if ( reservingLanguages ) {
1021+ this . _diagnostic ( symbol . valueDeclaration ,
1022+ ts . DiagnosticCategory . Warning ,
1023+ `'${ symbol . name } ' is a reserved word in ${ reservingLanguages . join ( ', ' ) } . Using this name may cause problems `
1024+ + 'when generating language bindings. Consider using a different name.' ) ;
1025+ }
1026+ }
1027+
10091028 private async _visitProperty ( symbol : ts . Symbol , type : spec . ClassType | spec . InterfaceType , ctx : EmitContext ) {
10101029 if ( type . properties && type . properties . find ( p => p . name === symbol . name ) ) {
10111030 /*
@@ -1024,6 +1043,8 @@ export class Assembler implements Emitter {
10241043 return ;
10251044 }
10261045
1046+ this . _warnAboutReservedWords ( symbol ) ;
1047+
10271048 const signature = symbol . valueDeclaration as ( ts . PropertySignature
10281049 | ts . PropertyDeclaration
10291050 | ts . AccessorDeclaration
@@ -1069,6 +1090,8 @@ export class Assembler implements Emitter {
10691090 }
10701091 const paramDeclaration = paramSymbol . valueDeclaration as ts . ParameterDeclaration ;
10711092
1093+ this . _warnAboutReservedWords ( paramSymbol ) ;
1094+
10721095 const parameter : spec . Parameter = {
10731096 ...await this . _optionalValue ( this . _typeChecker . getTypeAtLocation ( paramSymbol . valueDeclaration ) , paramSymbol . valueDeclaration ) ,
10741097 name : paramSymbol . name ,
@@ -1643,12 +1666,11 @@ function isErrorType(t: ts.Type) {
16431666}
16441667
16451668/**
1646- * These specifially cause trouble in C#, where we have to specificially annotate them as 'new' but our generator isn't doing that
1647- *
1648- * In C#, 'GetHashCode' is also problematic, but jsii already prevents you from naming a
1649- * method that starts with 'get' so we don't need to do anything special for that.
1669+ * Those have specific semantics in certain languages that don't always translate cleanly in others
1670+ * (like how equals/hashCode are not a thing in Javascript, but carry meaning in Java and C#). The
1671+ * `build` name is reserved for generated code (Java builders use that).
16501672 */
1651- const PROHIBITED_MEMBER_NAMES = [ 'equals' , 'hashcode' ] ;
1673+ const PROHIBITED_MEMBER_NAMES = [ 'build' , ' equals', 'hashcode' ] ;
16521674
16531675/**
16541676 * Whether the given name is prohibited
0 commit comments