@@ -70,16 +70,24 @@ export class StaticSymbolCache {
7070export class StaticReflector implements ReflectorReader {
7171 private declarationCache = new Map < string , StaticSymbol > ( ) ;
7272 private annotationCache = new Map < StaticSymbol , any [ ] > ( ) ;
73- private propertyCache = new Map < StaticSymbol , { [ key : string ] : any } > ( ) ;
73+ private propertyCache = new Map < StaticSymbol , { [ key : string ] : any [ ] } > ( ) ;
7474 private parameterCache = new Map < StaticSymbol , any [ ] > ( ) ;
75+ private methodCache = new Map < StaticSymbol , { [ key : string ] : boolean } > ( ) ;
7576 private metadataCache = new Map < string , { [ key : string ] : any } > ( ) ;
7677 private conversionMap = new Map < StaticSymbol , ( context : StaticSymbol , args : any [ ] ) => any > ( ) ;
7778 private opaqueToken : StaticSymbol ;
7879
7980 constructor (
8081 private host : StaticReflectorHost ,
81- private staticSymbolCache : StaticSymbolCache = new StaticSymbolCache ( ) ) {
82+ private staticSymbolCache : StaticSymbolCache = new StaticSymbolCache ( ) ,
83+ knownMetadataClasses : { name : string , filePath : string , ctor : any } [ ] = [ ] ,
84+ knownMetadataFunctions : { name : string , filePath : string , fn : any } [ ] = [ ] ) {
8285 this . initializeConversionMap ( ) ;
86+ knownMetadataClasses . forEach (
87+ ( kc ) => this . _registerDecoratorOrConstructor (
88+ this . getStaticSymbol ( kc . filePath , kc . name ) , kc . ctor ) ) ;
89+ knownMetadataFunctions . forEach (
90+ ( kf ) => this . _registerFunction ( this . getStaticSymbol ( kf . filePath , kf . name ) , kf . fn ) ) ;
8391 }
8492
8593 importUri ( typeOrFunc : StaticSymbol ) : string {
@@ -99,29 +107,45 @@ export class StaticReflector implements ReflectorReader {
99107 public annotations ( type : StaticSymbol ) : any [ ] {
100108 let annotations = this . annotationCache . get ( type ) ;
101109 if ( ! annotations ) {
110+ annotations = [ ] ;
102111 const classMetadata = this . getTypeMetadata ( type ) ;
112+ if ( classMetadata [ 'extends' ] ) {
113+ const parentAnnotations = this . annotations ( this . simplify ( type , classMetadata [ 'extends' ] ) ) ;
114+ annotations . push ( ...parentAnnotations ) ;
115+ }
103116 if ( classMetadata [ 'decorators' ] ) {
104- annotations = this . simplify ( type , classMetadata [ 'decorators' ] ) ;
105- } else {
106- annotations = [ ] ;
117+ const ownAnnotations : any [ ] = this . simplify ( type , classMetadata [ 'decorators' ] ) ;
118+ annotations . push ( ...ownAnnotations ) ;
107119 }
108120 this . annotationCache . set ( type , annotations . filter ( ann => ! ! ann ) ) ;
109121 }
110122 return annotations ;
111123 }
112124
113- public propMetadata ( type : StaticSymbol ) : { [ key : string ] : any } {
125+ public propMetadata ( type : StaticSymbol ) : { [ key : string ] : any [ ] } {
114126 let propMetadata = this . propertyCache . get ( type ) ;
115127 if ( ! propMetadata ) {
116- const classMetadata = this . getTypeMetadata ( type ) ;
117- const members = classMetadata ? classMetadata [ 'members' ] : { } ;
118- propMetadata = mapStringMap ( members , ( propData , propName ) => {
128+ const classMetadata = this . getTypeMetadata ( type ) || { } ;
129+ propMetadata = { } ;
130+ if ( classMetadata [ 'extends' ] ) {
131+ const parentPropMetadata = this . propMetadata ( this . simplify ( type , classMetadata [ 'extends' ] ) ) ;
132+ Object . keys ( parentPropMetadata ) . forEach ( ( parentProp ) => {
133+ propMetadata [ parentProp ] = parentPropMetadata [ parentProp ] ;
134+ } ) ;
135+ }
136+
137+ const members = classMetadata [ 'members' ] || { } ;
138+ Object . keys ( members ) . forEach ( ( propName ) => {
139+ const propData = members [ propName ] ;
119140 const prop = ( < any [ ] > propData )
120141 . find ( a => a [ '__symbolic' ] == 'property' || a [ '__symbolic' ] == 'method' ) ;
142+ const decorators : any [ ] = [ ] ;
143+ if ( propMetadata [ propName ] ) {
144+ decorators . push ( ...propMetadata [ propName ] ) ;
145+ }
146+ propMetadata [ propName ] = decorators ;
121147 if ( prop && prop [ 'decorators' ] ) {
122- return this . simplify ( type , prop [ 'decorators' ] ) ;
123- } else {
124- return [ ] ;
148+ decorators . push ( ...this . simplify ( type , prop [ 'decorators' ] ) ) ;
125149 }
126150 } ) ;
127151 this . propertyCache . set ( type , propMetadata ) ;
@@ -155,6 +179,8 @@ export class StaticReflector implements ReflectorReader {
155179 }
156180 parameters . push ( nestedResult ) ;
157181 } ) ;
182+ } else if ( classMetadata [ 'extends' ] ) {
183+ parameters = this . parameters ( this . simplify ( type , classMetadata [ 'extends' ] ) ) ;
158184 }
159185 if ( ! parameters ) {
160186 parameters = [ ] ;
@@ -168,23 +194,47 @@ export class StaticReflector implements ReflectorReader {
168194 }
169195 }
170196
197+ private _methodNames ( type : any ) : { [ key : string ] : boolean } {
198+ let methodNames = this . methodCache . get ( type ) ;
199+ if ( ! methodNames ) {
200+ const classMetadata = this . getTypeMetadata ( type ) || { } ;
201+ methodNames = { } ;
202+ if ( classMetadata [ 'extends' ] ) {
203+ const parentMethodNames = this . _methodNames ( this . simplify ( type , classMetadata [ 'extends' ] ) ) ;
204+ Object . keys ( parentMethodNames ) . forEach ( ( parentProp ) => {
205+ methodNames [ parentProp ] = parentMethodNames [ parentProp ] ;
206+ } ) ;
207+ }
208+
209+ const members = classMetadata [ 'members' ] || { } ;
210+ Object . keys ( members ) . forEach ( ( propName ) => {
211+ const propData = members [ propName ] ;
212+ const isMethod = ( < any [ ] > propData ) . some ( a => a [ '__symbolic' ] == 'method' ) ;
213+ methodNames [ propName ] = methodNames [ propName ] || isMethod ;
214+ } ) ;
215+ this . methodCache . set ( type , methodNames ) ;
216+ }
217+ return methodNames ;
218+ }
219+
171220 hasLifecycleHook ( type : any , lcProperty : string ) : boolean {
172221 if ( ! ( type instanceof StaticSymbol ) ) {
173222 throw new Error (
174223 `hasLifecycleHook received ${ JSON . stringify ( type ) } which is not a StaticSymbol` ) ;
175224 }
176- const classMetadata = this . getTypeMetadata ( type ) ;
177- const members = classMetadata ? classMetadata [ 'members' ] : null ;
178- const member : any [ ] =
179- members && members . hasOwnProperty ( lcProperty ) ? members [ lcProperty ] : null ;
180- return member ? member . some ( a => a [ '__symbolic' ] == 'method' ) : false ;
225+ try {
226+ return ! ! this . _methodNames ( type ) [ lcProperty ] ;
227+ } catch ( e ) {
228+ console . error ( `Failed on type ${ JSON . stringify ( type ) } with error ${ e } ` ) ;
229+ throw e ;
230+ }
181231 }
182232
183- private registerDecoratorOrConstructor ( type : StaticSymbol , ctor : any ) : void {
233+ private _registerDecoratorOrConstructor ( type : StaticSymbol , ctor : any ) : void {
184234 this . conversionMap . set ( type , ( context : StaticSymbol , args : any [ ] ) => new ctor ( ...args ) ) ;
185235 }
186236
187- private registerFunction ( type : StaticSymbol , fn : any ) : void {
237+ private _registerFunction ( type : StaticSymbol , fn : any ) : void {
188238 this . conversionMap . set ( type , ( context : StaticSymbol , args : any [ ] ) => fn . apply ( undefined , args ) ) ;
189239 }
190240
@@ -193,50 +243,51 @@ export class StaticReflector implements ReflectorReader {
193243 ANGULAR_IMPORT_LOCATIONS ;
194244 this . opaqueToken = this . findDeclaration ( diOpaqueToken , 'OpaqueToken' ) ;
195245
196- this . registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Host' ) , Host ) ;
197- this . registerDecoratorOrConstructor (
246+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Host' ) , Host ) ;
247+ this . _registerDecoratorOrConstructor (
198248 this . findDeclaration ( diDecorators , 'Injectable' ) , Injectable ) ;
199- this . registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Self' ) , Self ) ;
200- this . registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'SkipSelf' ) , SkipSelf ) ;
201- this . registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Inject' ) , Inject ) ;
202- this . registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Optional' ) , Optional ) ;
203- this . registerDecoratorOrConstructor (
249+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Self' ) , Self ) ;
250+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'SkipSelf' ) , SkipSelf ) ;
251+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Inject' ) , Inject ) ;
252+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diDecorators , 'Optional' ) , Optional ) ;
253+ this . _registerDecoratorOrConstructor (
204254 this . findDeclaration ( coreDecorators , 'Attribute' ) , Attribute ) ;
205- this . registerDecoratorOrConstructor (
255+ this . _registerDecoratorOrConstructor (
206256 this . findDeclaration ( coreDecorators , 'ContentChild' ) , ContentChild ) ;
207- this . registerDecoratorOrConstructor (
257+ this . _registerDecoratorOrConstructor (
208258 this . findDeclaration ( coreDecorators , 'ContentChildren' ) , ContentChildren ) ;
209- this . registerDecoratorOrConstructor (
259+ this . _registerDecoratorOrConstructor (
210260 this . findDeclaration ( coreDecorators , 'ViewChild' ) , ViewChild ) ;
211- this . registerDecoratorOrConstructor (
261+ this . _registerDecoratorOrConstructor (
212262 this . findDeclaration ( coreDecorators , 'ViewChildren' ) , ViewChildren ) ;
213- this . registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'Input' ) , Input ) ;
214- this . registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'Output' ) , Output ) ;
215- this . registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'Pipe' ) , Pipe ) ;
216- this . registerDecoratorOrConstructor (
263+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'Input' ) , Input ) ;
264+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'Output' ) , Output ) ;
265+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'Pipe' ) , Pipe ) ;
266+ this . _registerDecoratorOrConstructor (
217267 this . findDeclaration ( coreDecorators , 'HostBinding' ) , HostBinding ) ;
218- this . registerDecoratorOrConstructor (
268+ this . _registerDecoratorOrConstructor (
219269 this . findDeclaration ( coreDecorators , 'HostListener' ) , HostListener ) ;
220- this . registerDecoratorOrConstructor (
270+ this . _registerDecoratorOrConstructor (
221271 this . findDeclaration ( coreDecorators , 'Directive' ) , Directive ) ;
222- this . registerDecoratorOrConstructor (
272+ this . _registerDecoratorOrConstructor (
223273 this . findDeclaration ( coreDecorators , 'Component' ) , Component ) ;
224- this . registerDecoratorOrConstructor ( this . findDeclaration ( coreDecorators , 'NgModule' ) , NgModule ) ;
274+ this . _registerDecoratorOrConstructor (
275+ this . findDeclaration ( coreDecorators , 'NgModule' ) , NgModule ) ;
225276
226277 // Note: Some metadata classes can be used directly with Provider.deps.
227- this . registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'Host' ) , Host ) ;
228- this . registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'Self' ) , Self ) ;
229- this . registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'SkipSelf' ) , SkipSelf ) ;
230- this . registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'Optional' ) , Optional ) ;
231-
232- this . registerFunction ( this . findDeclaration ( animationMetadata , 'trigger' ) , trigger ) ;
233- this . registerFunction ( this . findDeclaration ( animationMetadata , 'state' ) , state ) ;
234- this . registerFunction ( this . findDeclaration ( animationMetadata , 'transition' ) , transition ) ;
235- this . registerFunction ( this . findDeclaration ( animationMetadata , 'style' ) , style ) ;
236- this . registerFunction ( this . findDeclaration ( animationMetadata , 'animate' ) , animate ) ;
237- this . registerFunction ( this . findDeclaration ( animationMetadata , 'keyframes' ) , keyframes ) ;
238- this . registerFunction ( this . findDeclaration ( animationMetadata , 'sequence' ) , sequence ) ;
239- this . registerFunction ( this . findDeclaration ( animationMetadata , 'group' ) , group ) ;
278+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'Host' ) , Host ) ;
279+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'Self' ) , Self ) ;
280+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'SkipSelf' ) , SkipSelf ) ;
281+ this . _registerDecoratorOrConstructor ( this . findDeclaration ( diMetadata , 'Optional' ) , Optional ) ;
282+
283+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'trigger' ) , trigger ) ;
284+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'state' ) , state ) ;
285+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'transition' ) , transition ) ;
286+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'style' ) , style ) ;
287+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'animate' ) , animate ) ;
288+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'keyframes' ) , keyframes ) ;
289+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'sequence' ) , sequence ) ;
290+ this . _registerFunction ( this . findDeclaration ( animationMetadata , 'group' ) , group ) ;
240291 }
241292
242293 /**
@@ -333,7 +384,7 @@ export class StaticReflector implements ReflectorReader {
333384
334385 /** @internal */
335386 public simplify ( context : StaticSymbol , value : any ) : any {
336- const _this = this ;
387+ const self = this ;
337388 let scope = BindingScope . empty ;
338389 const calling = new Map < StaticSymbol , boolean > ( ) ;
339390
@@ -342,15 +393,15 @@ export class StaticReflector implements ReflectorReader {
342393 let staticSymbol : StaticSymbol ;
343394 if ( expression [ 'module' ] ) {
344395 staticSymbol =
345- _this . findDeclaration ( expression [ 'module' ] , expression [ 'name' ] , context . filePath ) ;
396+ self . findDeclaration ( expression [ 'module' ] , expression [ 'name' ] , context . filePath ) ;
346397 } else {
347- staticSymbol = _this . getStaticSymbol ( context . filePath , expression [ 'name' ] ) ;
398+ staticSymbol = self . getStaticSymbol ( context . filePath , expression [ 'name' ] ) ;
348399 }
349400 return staticSymbol ;
350401 }
351402
352403 function resolveReferenceValue ( staticSymbol : StaticSymbol ) : any {
353- const moduleMetadata = _this . getModuleMetadata ( staticSymbol . filePath ) ;
404+ const moduleMetadata = self . getModuleMetadata ( staticSymbol . filePath ) ;
354405 const declarationValue =
355406 moduleMetadata ? moduleMetadata [ 'metadata' ] [ staticSymbol . name ] : null ;
356407 return declarationValue ;
@@ -360,7 +411,7 @@ export class StaticReflector implements ReflectorReader {
360411 if ( value && value . __symbolic === 'new' && value . expression ) {
361412 const target = value . expression ;
362413 if ( target . __symbolic == 'reference' ) {
363- return sameSymbol ( resolveReference ( context , target ) , _this . opaqueToken ) ;
414+ return sameSymbol ( resolveReference ( context , target ) , self . opaqueToken ) ;
364415 }
365416 }
366417 return false ;
@@ -553,7 +604,7 @@ export class StaticReflector implements ReflectorReader {
553604 const members = selectTarget . members ?
554605 ( selectTarget . members as string [ ] ) . concat ( member ) :
555606 [ member ] ;
556- return _this . getStaticSymbol ( selectTarget . filePath , selectTarget . name , members ) ;
607+ return self . getStaticSymbol ( selectTarget . filePath , selectTarget . name , members ) ;
557608 }
558609 }
559610 const member = simplify ( expression [ 'member' ] ) ;
@@ -589,11 +640,11 @@ export class StaticReflector implements ReflectorReader {
589640 let target = expression [ 'expression' ] ;
590641 if ( target [ 'module' ] ) {
591642 staticSymbol =
592- _this . findDeclaration ( target [ 'module' ] , target [ 'name' ] , context . filePath ) ;
643+ self . findDeclaration ( target [ 'module' ] , target [ 'name' ] , context . filePath ) ;
593644 } else {
594- staticSymbol = _this . getStaticSymbol ( context . filePath , target [ 'name' ] ) ;
645+ staticSymbol = self . getStaticSymbol ( context . filePath , target [ 'name' ] ) ;
595646 }
596- let converter = _this . conversionMap . get ( staticSymbol ) ;
647+ let converter = self . conversionMap . get ( staticSymbol ) ;
597648 if ( converter ) {
598649 let args : any [ ] = expression [ 'arguments' ] ;
599650 if ( ! args ) {
0 commit comments