From 506f4ce1e5a0b5795842782bb6689760871bd5a9 Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Thu, 24 Mar 2016 13:32:47 -0700 Subject: [PATCH] feat(compiler): Resolvers now use DI to create reflector Also introduced ReflectorReader when only read-only access to the reflector is needed. Closes #7762 --- .../src/core/linker/directive_resolver.ts | 17 ++++++++++++++--- .../angular2/src/core/linker/pipe_resolver.ts | 14 ++++++++++++-- .../angular2/src/core/linker/view_resolver.ts | 14 ++++++++++++-- .../src/core/platform_common_providers.ts | 9 +++++++-- .../angular2/src/core/reflection/reflector.ts | 4 +++- .../src/core/reflection/reflector_reader.ts | 9 +++++++++ tools/public_api_guard/public_api_spec.ts | 2 ++ 7 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 modules/angular2/src/core/reflection/reflector_reader.ts diff --git a/modules/angular2/src/core/linker/directive_resolver.ts b/modules/angular2/src/core/linker/directive_resolver.ts index 63b34a46cc..eba655f209 100644 --- a/modules/angular2/src/core/linker/directive_resolver.ts +++ b/modules/angular2/src/core/linker/directive_resolver.ts @@ -16,6 +16,7 @@ import { ViewChildMetadata } from 'angular2/src/core/metadata'; import {reflector} from 'angular2/src/core/reflection/reflection'; +import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader'; function _isDirectiveMetadata(type: any): boolean { return type instanceof DirectiveMetadata; @@ -30,15 +31,25 @@ function _isDirectiveMetadata(type: any): boolean { */ @Injectable() export class DirectiveResolver { + private _reflector: ReflectorReader; + + constructor(_reflector?: ReflectorReader) { + if (isPresent(_reflector)) { + this._reflector = _reflector; + } else { + this._reflector = reflector; + } + } + /** * Return {@link DirectiveMetadata} for a given `Type`. */ resolve(type: Type): DirectiveMetadata { - var typeMetadata = reflector.annotations(resolveForwardRef(type)); + var typeMetadata = this._reflector.annotations(resolveForwardRef(type)); if (isPresent(typeMetadata)) { var metadata = typeMetadata.find(_isDirectiveMetadata); if (isPresent(metadata)) { - var propertyMetadata = reflector.propMetadata(type); + var propertyMetadata = this._reflector.propMetadata(type); return this._mergeWithPropertyMetadata(metadata, propertyMetadata, type); } } @@ -155,4 +166,4 @@ export class DirectiveResolver { } } -export var CODEGEN_DIRECTIVE_RESOLVER = new DirectiveResolver(); +export var CODEGEN_DIRECTIVE_RESOLVER = new DirectiveResolver(reflector); diff --git a/modules/angular2/src/core/linker/pipe_resolver.ts b/modules/angular2/src/core/linker/pipe_resolver.ts index 3de7a3f23c..f947f3e7ba 100644 --- a/modules/angular2/src/core/linker/pipe_resolver.ts +++ b/modules/angular2/src/core/linker/pipe_resolver.ts @@ -2,6 +2,7 @@ import {resolveForwardRef, Injectable} from 'angular2/src/core/di'; import {Type, isPresent, stringify} from 'angular2/src/facade/lang'; import {BaseException} from 'angular2/src/facade/exceptions'; import {PipeMetadata} from 'angular2/src/core/metadata'; +import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader'; import {reflector} from 'angular2/src/core/reflection/reflection'; function _isPipeMetadata(type: any): boolean { @@ -17,11 +18,20 @@ function _isPipeMetadata(type: any): boolean { */ @Injectable() export class PipeResolver { + private _reflector: ReflectorReader; + constructor(_reflector?: ReflectorReader) { + if (isPresent(_reflector)) { + this._reflector = _reflector; + } else { + this._reflector = reflector; + } + } + /** * Return {@link PipeMetadata} for a given `Type`. */ resolve(type: Type): PipeMetadata { - var metas = reflector.annotations(resolveForwardRef(type)); + var metas = this._reflector.annotations(resolveForwardRef(type)); if (isPresent(metas)) { var annotation = metas.find(_isPipeMetadata); if (isPresent(annotation)) { @@ -32,4 +42,4 @@ export class PipeResolver { } } -export var CODEGEN_PIPE_RESOLVER = new PipeResolver(); +export var CODEGEN_PIPE_RESOLVER = new PipeResolver(reflector); diff --git a/modules/angular2/src/core/linker/view_resolver.ts b/modules/angular2/src/core/linker/view_resolver.ts index 8eb82cac03..56340b1363 100644 --- a/modules/angular2/src/core/linker/view_resolver.ts +++ b/modules/angular2/src/core/linker/view_resolver.ts @@ -6,17 +6,27 @@ import {Type, stringify, isBlank, isPresent} from 'angular2/src/facade/lang'; import {BaseException} from 'angular2/src/facade/exceptions'; import {Map} from 'angular2/src/facade/collection'; +import {ReflectorReader} from 'angular2/src/core/reflection/reflector_reader'; import {reflector} from 'angular2/src/core/reflection/reflection'; - /** * Resolves types to {@link ViewMetadata}. */ @Injectable() export class ViewResolver { + private _reflector: ReflectorReader; + /** @internal */ _cache = new Map(); + constructor(_reflector?: ReflectorReader) { + if (isPresent(_reflector)) { + this._reflector = _reflector; + } else { + this._reflector = reflector; + } + } + resolve(component: Type): ViewMetadata { var view = this._cache.get(component); @@ -33,7 +43,7 @@ export class ViewResolver { var compMeta: ComponentMetadata; var viewMeta: ViewMetadata; - reflector.annotations(component).forEach(m => { + this._reflector.annotations(component).forEach(m => { if (m instanceof ViewMetadata) { viewMeta = m; } diff --git a/modules/angular2/src/core/platform_common_providers.ts b/modules/angular2/src/core/platform_common_providers.ts index 491b30e5b3..5010c11b6d 100644 --- a/modules/angular2/src/core/platform_common_providers.ts +++ b/modules/angular2/src/core/platform_common_providers.ts @@ -2,6 +2,7 @@ import {Type, isBlank, isPresent, assertionsEnabled, CONST_EXPR} from 'angular2/ import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di'; import {Console} from 'angular2/src/core/console'; import {Reflector, reflector} from './reflection/reflection'; +import {ReflectorReader} from './reflection/reflector_reader'; import {TestabilityRegistry} from 'angular2/src/core/testability/testability'; function _reflector(): Reflector { @@ -11,5 +12,9 @@ function _reflector(): Reflector { /** * A default set of providers which should be included in any Angular platform. */ -export const PLATFORM_COMMON_PROVIDERS: Array = CONST_EXPR( - [new Provider(Reflector, {useFactory: _reflector, deps: []}), TestabilityRegistry, Console]); +export const PLATFORM_COMMON_PROVIDERS: Array = CONST_EXPR([ + new Provider(Reflector, {useFactory: _reflector, deps: []}), + new Provider(ReflectorReader, {useExisting: Reflector}), + TestabilityRegistry, + Console +]); \ No newline at end of file diff --git a/modules/angular2/src/core/reflection/reflector.ts b/modules/angular2/src/core/reflection/reflector.ts index 94b472ef7b..f8253c94bc 100644 --- a/modules/angular2/src/core/reflection/reflector.ts +++ b/modules/angular2/src/core/reflection/reflector.ts @@ -9,6 +9,7 @@ import { StringMapWrapper } from 'angular2/src/facade/collection'; import {SetterFn, GetterFn, MethodFn} from './types'; +import {ReflectorReader} from './reflector_reader'; import {PlatformReflectionCapabilities} from './platform_reflection_capabilities'; export {SetterFn, GetterFn, MethodFn} from './types'; export {PlatformReflectionCapabilities} from './platform_reflection_capabilities'; @@ -25,7 +26,7 @@ export class ReflectionInfo { * Provides access to reflection data about symbols. Used internally by Angular * to power dependency injection and compilation. */ -export class Reflector { +export class Reflector extends ReflectorReader { /** @internal */ _injectableInfo = new Map(); /** @internal */ @@ -39,6 +40,7 @@ export class Reflector { reflectionCapabilities: PlatformReflectionCapabilities; constructor(reflectionCapabilities: PlatformReflectionCapabilities) { + super(); this._usedKeys = null; this.reflectionCapabilities = reflectionCapabilities; } diff --git a/modules/angular2/src/core/reflection/reflector_reader.ts b/modules/angular2/src/core/reflection/reflector_reader.ts new file mode 100644 index 0000000000..4cf7e33c86 --- /dev/null +++ b/modules/angular2/src/core/reflection/reflector_reader.ts @@ -0,0 +1,9 @@ +/** + * Provides read-only access to reflection data about symbols. Used internally by Angular + * to power dependency injection and compilation. + */ +export abstract class ReflectorReader { + abstract parameters(typeOrFunc: /*Type*/ any): any[][]; + abstract annotations(typeOrFunc: /*Type*/ any): any[]; + abstract propMetadata(typeOrFunc: /*Type*/ any): {[key: string]: any[]}; +} \ No newline at end of file diff --git a/tools/public_api_guard/public_api_spec.ts b/tools/public_api_guard/public_api_spec.ts index d5eb25c315..1705d8ec75 100644 --- a/tools/public_api_guard/public_api_spec.ts +++ b/tools/public_api_guard/public_api_spec.ts @@ -169,6 +169,7 @@ const CORE = [ 'DirectiveMetadata.queries:{[key:string]:any}', 'DirectiveMetadata.selector:string', 'DirectiveResolver', + 'DirectiveResolver.constructor(_reflector:ReflectorReader)', 'DirectiveResolver.resolve(type:Type):DirectiveMetadata', 'DoCheck', 'DoCheck.ngDoCheck():any', @@ -493,6 +494,7 @@ const CORE = [ 'ViewRef.changeDetectorRef:ChangeDetectorRef', 'ViewRef.destroyed:boolean', 'ViewResolver', + 'ViewResolver.constructor(_reflector:ReflectorReader)', 'ViewResolver.resolve(component:Type):ViewMetadata', 'WrappedException', 'WrappedException.constructor(_wrapperMessage:string, _originalException:any, _originalStack:any, _context:any)',