diff --git a/modules/@angular/compiler-cli/integrationtest/src/features.ts b/modules/@angular/compiler-cli/integrationtest/src/features.ts index c6f3da13a2..29d38311e7 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/features.ts +++ b/modules/@angular/compiler-cli/integrationtest/src/features.ts @@ -30,11 +30,12 @@ export class CompWithProviders { @Component({ selector: 'cmp-reference', template: ` - {{a.value}} + {{a.value}}
{{a.value}}
` }) export class CompWithReferences { + foo: string; } @Component({selector: 'cmp-pipes', template: `
{{test | somePipe}}
`}) diff --git a/modules/@angular/compiler-cli/integrationtest/src/module.ts b/modules/@angular/compiler-cli/integrationtest/src/module.ts index 596230e1ea..65e90d9300 100644 --- a/modules/@angular/compiler-cli/integrationtest/src/module.ts +++ b/modules/@angular/compiler-cli/integrationtest/src/module.ts @@ -35,7 +35,7 @@ import {CompForChildQuery, CompWithChildQuery, CompWithDirectiveChild, Directive providers: [SomeService], entryComponents: [ AnimateCmp, BasicComp, CompWithEntryComponents, CompWithAnalyzeEntryComponentsProvider, - ProjectingComp, CompWithChildQuery, CompUsingRootModuleDirectiveAndPipe + ProjectingComp, CompWithChildQuery, CompUsingRootModuleDirectiveAndPipe, CompWithReferences ] }) export class MainModule { diff --git a/modules/@angular/compiler-cli/src/reflector_host.ts b/modules/@angular/compiler-cli/src/reflector_host.ts index 2011c2c80a..6162fb7d94 100644 --- a/modules/@angular/compiler-cli/src/reflector_host.ts +++ b/modules/@angular/compiler-cli/src/reflector_host.ts @@ -221,11 +221,12 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator { * @param declarationFile the absolute path of the file where the symbol is declared * @param name the name of the type. */ - getStaticSymbol(declarationFile: string, name: string): StaticSymbol { - let key = `"${declarationFile}".${name}`; + getStaticSymbol(declarationFile: string, name: string, members?: string[]): StaticSymbol { + const memberSuffix = members ? `.${ members.join('.')}` : ''; + const key = `"${declarationFile}".${name}${memberSuffix}`; let result = this.typeCache.get(key); if (!result) { - result = new StaticSymbol(declarationFile, name); + result = new StaticSymbol(declarationFile, name, members); this.typeCache.set(key, result); } return result; diff --git a/modules/@angular/compiler-cli/src/static_reflector.ts b/modules/@angular/compiler-cli/src/static_reflector.ts index 14ee9f382f..d2115def62 100644 --- a/modules/@angular/compiler-cli/src/static_reflector.ts +++ b/modules/@angular/compiler-cli/src/static_reflector.ts @@ -34,7 +34,7 @@ export interface StaticReflectorHost { */ findDeclaration(modulePath: string, symbolName: string, containingFile?: string): StaticSymbol; - getStaticSymbol(declarationFile: string, name: string): StaticSymbol; + getStaticSymbol(declarationFile: string, name: string, members?: string[]): StaticSymbol; angularImportLocations(): { coreDecorators: string, @@ -52,7 +52,7 @@ export interface StaticReflectorHost { * This token is unique for a filePath and name and can be used as a hash table key. */ export class StaticSymbol { - constructor(public filePath: string, public name: string) {} + constructor(public filePath: string, public name: string, public members?: string[]) {} } /** @@ -451,7 +451,12 @@ export class StaticReflector implements ReflectorReader { if (declarationValue && declarationValue.statics) { selectTarget = declarationValue.statics; } else { - return null; + const member: string = expression['member']; + const members = selectTarget.members ? + (selectTarget.members as string[]).concat(member) : + [member]; + return _this.host.getStaticSymbol( + selectTarget.filePath, selectTarget.name, members); } } const member = simplify(expression['member']); diff --git a/modules/@angular/compiler-cli/test/static_reflector_spec.ts b/modules/@angular/compiler-cli/test/static_reflector_spec.ts index 682f7a847d..bf82870649 100644 --- a/modules/@angular/compiler-cli/test/static_reflector_spec.ts +++ b/modules/@angular/compiler-cli/test/static_reflector_spec.ts @@ -426,6 +426,13 @@ describe('StaticReflector', () => { expect(annotations.length).toBe(1); expect(annotations[0].providers).toEqual([['a', true, false]]); }); + + it('should be able to get metadata with a reference to a static method', () => { + const annotations = reflector.annotations( + host.getStaticSymbol('/tmp/src/static-method-ref.ts', 'MethodReference')); + expect(annotations.length).toBe(1); + expect(annotations[0]._providers[0].useValue.members[0]).toEqual('staticMethod'); + }); }); class MockReflectorHost implements StaticReflectorHost { @@ -444,11 +451,11 @@ class MockReflectorHost implements StaticReflectorHost { provider: 'angular2/src/core/di/provider' }; } - getStaticSymbol(declarationFile: string, name: string): StaticSymbol { - var cacheKey = `${declarationFile}:${name}`; + getStaticSymbol(declarationFile: string, name: string, members?: string[]): StaticSymbol { + var cacheKey = `${declarationFile}:${name}${members?'.'+members.join('.'):''}`; var result = this.staticTypeCache.get(cacheKey); if (isBlank(result)) { - result = new StaticSymbol(declarationFile, name); + result = new StaticSymbol(declarationFile, name, members); this.staticTypeCache.set(cacheKey, result); } return result; @@ -1011,6 +1018,22 @@ class MockReflectorHost implements StaticReflectorHost { providers: [ { provider: 'a', useValue: MyModule.VALUE } ] }) export class Foo { } + `, + '/tmp/src/static-method-def.ts': ` + export class ClassWithStatics { + static staticMethod() {} + } + `, + '/tmp/src/static-method-ref.ts': ` + import {Component} from 'angular2/src/core/metadata'; + import {ClassWithStatics} from './static-method-def'; + + @Component({ + providers: [ { provider: 'a', useValue: ClassWithStatics.staticMethod}] + }) + export class MethodReference { + + } ` }; diff --git a/modules/@angular/compiler/src/output/ts_emitter.ts b/modules/@angular/compiler/src/output/ts_emitter.ts index b95114bffe..d8fbd7331a 100644 --- a/modules/@angular/compiler/src/output/ts_emitter.ts +++ b/modules/@angular/compiler/src/output/ts_emitter.ts @@ -319,5 +319,9 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor (type: any /** TODO #9100 */) => type.visitType(this, ctx), typeParams, ctx, ','); ctx.print(`>`); } + if (value.runtime && value.runtime.members) { + ctx.print('.'); + ctx.print(value.runtime.members.join('.')); + } } }