refactor(MetadataResolver): cleanup

This commit is contained in:
Victor Berchet 2016-09-14 15:58:18 -07:00 committed by Alex Eagle
parent 1c24096650
commit 255099aa61
2 changed files with 144 additions and 127 deletions

View File

@ -8,12 +8,10 @@
import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, Host, Inject, Injectable, ModuleWithProviders, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core'; import {AnimationAnimateMetadata, AnimationEntryMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationStateDeclarationMetadata, AnimationStateMetadata, AnimationStateTransitionMetadata, AnimationStyleMetadata, AnimationWithStepsMetadata, Attribute, ChangeDetectionStrategy, Component, Host, Inject, Injectable, ModuleWithProviders, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core';
import {StringMapWrapper} from '../src/facade/collection';
import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions'; import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
import * as cpl from './compile_metadata'; import * as cpl from './compile_metadata';
import {DirectiveResolver} from './directive_resolver'; import {DirectiveResolver} from './directive_resolver';
import {StringWrapper, isArray, isBlank, isPresent, isString, stringify} from './facade/lang'; import {isBlank, isPresent, isString, stringify} from './facade/lang';
import {Identifiers, resolveIdentifierToken} from './identifiers'; import {Identifiers, resolveIdentifierToken} from './identifiers';
import {hasLifecycleHook} from './lifecycle_reflector'; import {hasLifecycleHook} from './lifecycle_reflector';
import {NgModuleResolver} from './ng_module_resolver'; import {NgModuleResolver} from './ng_module_resolver';
@ -42,7 +40,7 @@ export class CompileMetadataResolver {
if (identifier.indexOf('(') >= 0) { if (identifier.indexOf('(') >= 0) {
// case: anonymous functions! // case: anonymous functions!
let found = this._anonymousTypes.get(token); let found = this._anonymousTypes.get(token);
if (isBlank(found)) { if (!found) {
this._anonymousTypes.set(token, this._anonymousTypeIndex++); this._anonymousTypes.set(token, this._anonymousTypeIndex++);
found = this._anonymousTypes.get(token); found = this._anonymousTypes.get(token);
} }
@ -67,18 +65,21 @@ export class CompileMetadataResolver {
} }
getAnimationEntryMetadata(entry: AnimationEntryMetadata): cpl.CompileAnimationEntryMetadata { getAnimationEntryMetadata(entry: AnimationEntryMetadata): cpl.CompileAnimationEntryMetadata {
var defs = entry.definitions.map(def => this.getAnimationStateMetadata(def)); const defs = entry.definitions.map(def => this.getAnimationStateMetadata(def));
return new cpl.CompileAnimationEntryMetadata(entry.name, defs); return new cpl.CompileAnimationEntryMetadata(entry.name, defs);
} }
getAnimationStateMetadata(value: AnimationStateMetadata): cpl.CompileAnimationStateMetadata { getAnimationStateMetadata(value: AnimationStateMetadata): cpl.CompileAnimationStateMetadata {
if (value instanceof AnimationStateDeclarationMetadata) { if (value instanceof AnimationStateDeclarationMetadata) {
var styles = this.getAnimationStyleMetadata(value.styles); const styles = this.getAnimationStyleMetadata(value.styles);
return new cpl.CompileAnimationStateDeclarationMetadata(value.stateNameExpr, styles); return new cpl.CompileAnimationStateDeclarationMetadata(value.stateNameExpr, styles);
} else if (value instanceof AnimationStateTransitionMetadata) { }
if (value instanceof AnimationStateTransitionMetadata) {
return new cpl.CompileAnimationStateTransitionMetadata( return new cpl.CompileAnimationStateTransitionMetadata(
value.stateChangeExpr, this.getAnimationMetadata(value.steps)); value.stateChangeExpr, this.getAnimationMetadata(value.steps));
} }
return null; return null;
} }
@ -89,21 +90,28 @@ export class CompileMetadataResolver {
getAnimationMetadata(value: AnimationMetadata): cpl.CompileAnimationMetadata { getAnimationMetadata(value: AnimationMetadata): cpl.CompileAnimationMetadata {
if (value instanceof AnimationStyleMetadata) { if (value instanceof AnimationStyleMetadata) {
return this.getAnimationStyleMetadata(value); return this.getAnimationStyleMetadata(value);
} else if (value instanceof AnimationKeyframesSequenceMetadata) { }
if (value instanceof AnimationKeyframesSequenceMetadata) {
return new cpl.CompileAnimationKeyframesSequenceMetadata( return new cpl.CompileAnimationKeyframesSequenceMetadata(
value.steps.map(entry => this.getAnimationStyleMetadata(entry))); value.steps.map(entry => this.getAnimationStyleMetadata(entry)));
} else if (value instanceof AnimationAnimateMetadata) { }
let animateData =
if (value instanceof AnimationAnimateMetadata) {
const animateData =
<cpl.CompileAnimationStyleMetadata|cpl.CompileAnimationKeyframesSequenceMetadata>this <cpl.CompileAnimationStyleMetadata|cpl.CompileAnimationKeyframesSequenceMetadata>this
.getAnimationMetadata(value.styles); .getAnimationMetadata(value.styles);
return new cpl.CompileAnimationAnimateMetadata(value.timings, animateData); return new cpl.CompileAnimationAnimateMetadata(value.timings, animateData);
} else if (value instanceof AnimationWithStepsMetadata) { }
var steps = value.steps.map(step => this.getAnimationMetadata(step));
if (value instanceof AnimationWithStepsMetadata) {
const steps = value.steps.map(step => this.getAnimationMetadata(step));
if (value instanceof AnimationGroupMetadata) { if (value instanceof AnimationGroupMetadata) {
return new cpl.CompileAnimationGroupMetadata(steps); return new cpl.CompileAnimationGroupMetadata(steps);
} else {
return new cpl.CompileAnimationSequenceMetadata(steps);
} }
return new cpl.CompileAnimationSequenceMetadata(steps);
} }
return null; return null;
} }
@ -111,47 +119,49 @@ export class CompileMetadataResolver {
getDirectiveMetadata(directiveType: Type<any>, throwIfNotFound = true): getDirectiveMetadata(directiveType: Type<any>, throwIfNotFound = true):
cpl.CompileDirectiveMetadata { cpl.CompileDirectiveMetadata {
directiveType = resolveForwardRef(directiveType); directiveType = resolveForwardRef(directiveType);
var meta = this._directiveCache.get(directiveType); let meta = this._directiveCache.get(directiveType);
if (isBlank(meta)) { if (!meta) {
var dirMeta = this._directiveResolver.resolve(directiveType, throwIfNotFound); const dirMeta = this._directiveResolver.resolve(directiveType, throwIfNotFound);
if (!dirMeta) { if (!dirMeta) {
return null; return null;
} }
var templateMeta: cpl.CompileTemplateMetadata = null; let templateMeta: cpl.CompileTemplateMetadata = null;
var changeDetectionStrategy: ChangeDetectionStrategy = null; let changeDetectionStrategy: ChangeDetectionStrategy = null;
var viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = []; let viewProviders: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
var moduleUrl = staticTypeModuleUrl(directiveType); let moduleUrl = staticTypeModuleUrl(directiveType);
var entryComponentMetadata: cpl.CompileTypeMetadata[] = []; let entryComponentMetadata: cpl.CompileTypeMetadata[] = [];
let selector = dirMeta.selector; let selector = dirMeta.selector;
if (dirMeta instanceof Component) { if (dirMeta instanceof Component) {
var cmpMeta = <Component>dirMeta; // Component
assertArrayOfStrings('styles', cmpMeta.styles); assertArrayOfStrings('styles', dirMeta.styles);
assertInterpolationSymbols('interpolation', cmpMeta.interpolation); assertArrayOfStrings('styleUrls', dirMeta.styleUrls);
var animations = isPresent(cmpMeta.animations) ? assertInterpolationSymbols('interpolation', dirMeta.interpolation);
cmpMeta.animations.map(e => this.getAnimationEntryMetadata(e)) :
const animations = dirMeta.animations ?
dirMeta.animations.map(e => this.getAnimationEntryMetadata(e)) :
null; null;
assertArrayOfStrings('styles', cmpMeta.styles);
assertArrayOfStrings('styleUrls', cmpMeta.styleUrls);
templateMeta = new cpl.CompileTemplateMetadata({ templateMeta = new cpl.CompileTemplateMetadata({
encapsulation: cmpMeta.encapsulation, encapsulation: dirMeta.encapsulation,
template: cmpMeta.template, template: dirMeta.template,
templateUrl: cmpMeta.templateUrl, templateUrl: dirMeta.templateUrl,
styles: cmpMeta.styles, styles: dirMeta.styles,
styleUrls: cmpMeta.styleUrls, styleUrls: dirMeta.styleUrls,
animations: animations, animations: animations,
interpolation: cmpMeta.interpolation interpolation: dirMeta.interpolation
}); });
changeDetectionStrategy = cmpMeta.changeDetection;
if (isPresent(dirMeta.viewProviders)) { changeDetectionStrategy = dirMeta.changeDetection;
if (dirMeta.viewProviders) {
viewProviders = this.getProvidersMetadata( viewProviders = this.getProvidersMetadata(
dirMeta.viewProviders, entryComponentMetadata, dirMeta.viewProviders, entryComponentMetadata,
`viewProviders for "${stringify(directiveType)}"`); `viewProviders for "${stringify(directiveType)}"`);
} }
moduleUrl = componentModuleUrl(this._reflector, directiveType, cmpMeta); moduleUrl = componentModuleUrl(this._reflector, directiveType, dirMeta);
if (cmpMeta.entryComponents) { if (dirMeta.entryComponents) {
entryComponentMetadata = entryComponentMetadata =
flattenArray(cmpMeta.entryComponents) flattenArray(dirMeta.entryComponents)
.map((type) => this.getTypeMetadata(type, staticTypeModuleUrl(type))) .map((type) => this.getTypeMetadata(type, staticTypeModuleUrl(type)))
.concat(entryComponentMetadata); .concat(entryComponentMetadata);
} }
@ -159,27 +169,29 @@ export class CompileMetadataResolver {
selector = this._schemaRegistry.getDefaultComponentElementName(); selector = this._schemaRegistry.getDefaultComponentElementName();
} }
} else { } else {
// Directive
if (!selector) { if (!selector) {
throw new Error(`Directive ${stringify(directiveType)} has no selector, please add it!`); throw new Error(`Directive ${stringify(directiveType)} has no selector, please add it!`);
} }
} }
var providers: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = []; let providers: Array<cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]> = [];
if (isPresent(dirMeta.providers)) { if (isPresent(dirMeta.providers)) {
providers = this.getProvidersMetadata( providers = this.getProvidersMetadata(
dirMeta.providers, entryComponentMetadata, dirMeta.providers, entryComponentMetadata,
`providers for "${stringify(directiveType)}"`); `providers for "${stringify(directiveType)}"`);
} }
var queries: cpl.CompileQueryMetadata[] = []; let queries: cpl.CompileQueryMetadata[] = [];
var viewQueries: cpl.CompileQueryMetadata[] = []; let viewQueries: cpl.CompileQueryMetadata[] = [];
if (isPresent(dirMeta.queries)) { if (isPresent(dirMeta.queries)) {
queries = this.getQueriesMetadata(dirMeta.queries, false, directiveType); queries = this.getQueriesMetadata(dirMeta.queries, false, directiveType);
viewQueries = this.getQueriesMetadata(dirMeta.queries, true, directiveType); viewQueries = this.getQueriesMetadata(dirMeta.queries, true, directiveType);
} }
meta = cpl.CompileDirectiveMetadata.create({ meta = cpl.CompileDirectiveMetadata.create({
selector: selector, selector: selector,
exportAs: dirMeta.exportAs, exportAs: dirMeta.exportAs,
isComponent: isPresent(templateMeta), isComponent: !!templateMeta,
type: this.getTypeMetadata(directiveType, moduleUrl), type: this.getTypeMetadata(directiveType, moduleUrl),
template: templateMeta, template: templateMeta,
changeDetection: changeDetectionStrategy, changeDetection: changeDetectionStrategy,
@ -199,7 +211,7 @@ export class CompileMetadataResolver {
getNgModuleMetadata(moduleType: any, throwIfNotFound = true): cpl.CompileNgModuleMetadata { getNgModuleMetadata(moduleType: any, throwIfNotFound = true): cpl.CompileNgModuleMetadata {
moduleType = resolveForwardRef(moduleType); moduleType = resolveForwardRef(moduleType);
var compileMeta = this._ngModuleCache.get(moduleType); let compileMeta = this._ngModuleCache.get(moduleType);
if (!compileMeta) { if (!compileMeta) {
const meta = this._ngModuleResolver.resolve(moduleType, throwIfNotFound); const meta = this._ngModuleResolver.resolve(moduleType, throwIfNotFound);
if (!meta) { if (!meta) {
@ -230,8 +242,9 @@ export class CompileMetadataResolver {
`provider for the NgModule '${stringify(importedModuleType)}'`)); `provider for the NgModule '${stringify(importedModuleType)}'`));
} }
} }
if (importedModuleType) { if (importedModuleType) {
let importedMeta = this.getNgModuleMetadata(importedModuleType, false); const importedMeta = this.getNgModuleMetadata(importedModuleType, false);
if (importedMeta === null) { if (importedMeta === null) {
throw new Error( throw new Error(
`Unexpected ${this._getTypeDescriptor(importedType)} '${stringify(importedType)}' imported by the module '${stringify(moduleType)}'`); `Unexpected ${this._getTypeDescriptor(importedType)} '${stringify(importedType)}' imported by the module '${stringify(moduleType)}'`);
@ -298,11 +311,13 @@ export class CompileMetadataResolver {
meta.providers, entryComponents, meta.providers, entryComponents,
`provider for the NgModule '${stringify(moduleType)}'`)); `provider for the NgModule '${stringify(moduleType)}'`));
} }
if (meta.entryComponents) { if (meta.entryComponents) {
entryComponents.push( entryComponents.push(
...flattenArray(meta.entryComponents) ...flattenArray(meta.entryComponents)
.map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type)))); .map(type => this.getTypeMetadata(type, staticTypeModuleUrl(type))));
} }
if (meta.bootstrap) { if (meta.bootstrap) {
const typeMetadata = flattenArray(meta.bootstrap).map(type => { const typeMetadata = flattenArray(meta.bootstrap).map(type => {
if (!isValidType(type)) { if (!isValidType(type)) {
@ -313,7 +328,9 @@ export class CompileMetadataResolver {
}); });
bootstrapComponents.push(...typeMetadata); bootstrapComponents.push(...typeMetadata);
} }
entryComponents.push(...bootstrapComponents); entryComponents.push(...bootstrapComponents);
if (meta.schemas) { if (meta.schemas) {
schemas.push(...flattenArray(meta.schemas)); schemas.push(...flattenArray(meta.schemas));
} }
@ -323,19 +340,20 @@ export class CompileMetadataResolver {
compileMeta = new cpl.CompileNgModuleMetadata({ compileMeta = new cpl.CompileNgModuleMetadata({
type: this.getTypeMetadata(moduleType, staticTypeModuleUrl(moduleType)), type: this.getTypeMetadata(moduleType, staticTypeModuleUrl(moduleType)),
providers: providers, providers,
entryComponents: entryComponents, entryComponents,
bootstrapComponents: bootstrapComponents, bootstrapComponents,
schemas: schemas, schemas,
declaredDirectives: declaredDirectives, declaredDirectives,
exportedDirectives: exportedDirectives, exportedDirectives,
declaredPipes: declaredPipes, declaredPipes,
exportedPipes: exportedPipes, exportedPipes,
importedModules: importedModules, importedModules,
exportedModules: exportedModules, exportedModules,
transitiveModule: transitiveModule, transitiveModule,
id: meta.id, id: meta.id,
}); });
transitiveModule.modules.push(compileMeta); transitiveModule.modules.push(compileMeta);
this._verifyModule(compileMeta); this._verifyModule(compileMeta);
this._ngModuleCache.set(moduleType, compileMeta); this._ngModuleCache.set(moduleType, compileMeta);
@ -351,6 +369,7 @@ export class CompileMetadataResolver {
`Can't export directive ${stringify(dirMeta.type.reference)} from ${stringify(moduleMeta.type.reference)} as it was neither declared nor imported!`); `Can't export directive ${stringify(dirMeta.type.reference)} from ${stringify(moduleMeta.type.reference)} as it was neither declared nor imported!`);
} }
}); });
moduleMeta.exportedPipes.forEach((pipeMeta) => { moduleMeta.exportedPipes.forEach((pipeMeta) => {
if (!moduleMeta.transitiveModule.pipesSet.has(pipeMeta.type.reference)) { if (!moduleMeta.transitiveModule.pipesSet.has(pipeMeta.type.reference)) {
throw new Error( throw new Error(
@ -362,15 +381,21 @@ export class CompileMetadataResolver {
private _getTypeDescriptor(type: Type<any>): string { private _getTypeDescriptor(type: Type<any>): string {
if (this._directiveResolver.resolve(type, false) !== null) { if (this._directiveResolver.resolve(type, false) !== null) {
return 'directive'; return 'directive';
} else if (this._pipeResolver.resolve(type, false) !== null) {
return 'pipe';
} else if (this._ngModuleResolver.resolve(type, false) !== null) {
return 'module';
} else if ((type as any).provide) {
return 'provider';
} else {
return 'value';
} }
if (this._pipeResolver.resolve(type, false) !== null) {
return 'pipe';
}
if (this._ngModuleResolver.resolve(type, false) !== null) {
return 'module';
}
if ((type as any).provide) {
return 'provider';
}
return 'value';
} }
private _addTypeToModule(type: Type<any>, moduleType: Type<any>) { private _addTypeToModule(type: Type<any>, moduleType: Type<any>) {
@ -434,7 +459,7 @@ export class CompileMetadataResolver {
type = resolveForwardRef(type); type = resolveForwardRef(type);
return new cpl.CompileTypeMetadata({ return new cpl.CompileTypeMetadata({
name: this.sanitizeTokenName(type), name: this.sanitizeTokenName(type),
moduleUrl: moduleUrl, moduleUrl,
reference: type, reference: type,
diDeps: this.getDependenciesMetadata(type, dependencies), diDeps: this.getDependenciesMetadata(type, dependencies),
lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, type)), lifecycleHooks: LIFECYCLE_HOOKS_VALUES.filter(hook => hasLifecycleHook(hook, type)),
@ -446,7 +471,7 @@ export class CompileMetadataResolver {
factory = resolveForwardRef(factory); factory = resolveForwardRef(factory);
return new cpl.CompileFactoryMetadata({ return new cpl.CompileFactoryMetadata({
name: this.sanitizeTokenName(factory), name: this.sanitizeTokenName(factory),
moduleUrl: moduleUrl, moduleUrl,
reference: factory, reference: factory,
diDeps: this.getDependenciesMetadata(factory, dependencies) diDeps: this.getDependenciesMetadata(factory, dependencies)
}); });
@ -454,12 +479,13 @@ export class CompileMetadataResolver {
getPipeMetadata(pipeType: Type<any>, throwIfNotFound = true): cpl.CompilePipeMetadata { getPipeMetadata(pipeType: Type<any>, throwIfNotFound = true): cpl.CompilePipeMetadata {
pipeType = resolveForwardRef(pipeType); pipeType = resolveForwardRef(pipeType);
var meta = this._pipeCache.get(pipeType); let meta = this._pipeCache.get(pipeType);
if (isBlank(meta)) { if (!meta) {
var pipeMeta = this._pipeResolver.resolve(pipeType, throwIfNotFound); const pipeMeta = this._pipeResolver.resolve(pipeType, throwIfNotFound);
if (!pipeMeta) { if (!pipeMeta) {
return null; return null;
} }
meta = new cpl.CompilePipeMetadata({ meta = new cpl.CompilePipeMetadata({
type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)), type: this.getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
name: pipeMeta.name, name: pipeMeta.name,
@ -473,10 +499,8 @@ export class CompileMetadataResolver {
getDependenciesMetadata(typeOrFunc: Type<any>|Function, dependencies: any[]): getDependenciesMetadata(typeOrFunc: Type<any>|Function, dependencies: any[]):
cpl.CompileDiDependencyMetadata[] { cpl.CompileDiDependencyMetadata[] {
let hasUnknownDeps = false; let hasUnknownDeps = false;
let params = isPresent(dependencies) ? dependencies : this._reflector.parameters(typeOrFunc); let params = dependencies || this._reflector.parameters(typeOrFunc) || [];
if (isBlank(params)) {
params = [];
}
let dependenciesMetadata: cpl.CompileDiDependencyMetadata[] = params.map((param) => { let dependenciesMetadata: cpl.CompileDiDependencyMetadata[] = params.map((param) => {
let isAttribute = false; let isAttribute = false;
let isHost = false; let isHost = false;
@ -486,8 +510,8 @@ export class CompileMetadataResolver {
let query: Query = null; let query: Query = null;
let viewQuery: Query = null; let viewQuery: Query = null;
var token: any = null; var token: any = null;
if (isArray(param)) { if (Array.isArray(param)) {
(<any[]>param).forEach((paramEntry) => { param.forEach((paramEntry) => {
if (paramEntry instanceof Host) { if (paramEntry instanceof Host) {
isHost = true; isHost = true;
} else if (paramEntry instanceof Self) { } else if (paramEntry instanceof Self) {
@ -518,14 +542,15 @@ export class CompileMetadataResolver {
hasUnknownDeps = true; hasUnknownDeps = true;
return null; return null;
} }
return new cpl.CompileDiDependencyMetadata({ return new cpl.CompileDiDependencyMetadata({
isAttribute: isAttribute, isAttribute,
isHost: isHost, isHost,
isSelf: isSelf, isSelf,
isSkipSelf: isSkipSelf, isSkipSelf,
isOptional: isOptional, isOptional,
query: isPresent(query) ? this.getQueryMetadata(query, null, typeOrFunc) : null, query: query ? this.getQueryMetadata(query, null, typeOrFunc) : null,
viewQuery: isPresent(viewQuery) ? this.getQueryMetadata(viewQuery, null, typeOrFunc) : null, viewQuery: viewQuery ? this.getQueryMetadata(viewQuery, null, typeOrFunc) : null,
token: this.getTokenMetadata(token) token: this.getTokenMetadata(token)
}); });
@ -533,8 +558,7 @@ export class CompileMetadataResolver {
if (hasUnknownDeps) { if (hasUnknownDeps) {
let depsTokens = let depsTokens =
dependenciesMetadata.map((dep) => { return dep ? stringify(dep.token) : '?'; }) dependenciesMetadata.map((dep) => dep ? stringify(dep.token) : '?').join(', ');
.join(', ');
throw new Error( throw new Error(
`Can't resolve all parameters for ${stringify(typeOrFunc)}: (${depsTokens}).`); `Can't resolve all parameters for ${stringify(typeOrFunc)}: (${depsTokens}).`);
} }
@ -544,7 +568,7 @@ export class CompileMetadataResolver {
getTokenMetadata(token: any): cpl.CompileTokenMetadata { getTokenMetadata(token: any): cpl.CompileTokenMetadata {
token = resolveForwardRef(token); token = resolveForwardRef(token);
var compileToken: any /** TODO #9100 */; let compileToken: cpl.CompileTokenMetadata;
if (isString(token)) { if (isString(token)) {
compileToken = new cpl.CompileTokenMetadata({value: token}); compileToken = new cpl.CompileTokenMetadata({value: token});
} else { } else {
@ -569,7 +593,7 @@ export class CompileMetadataResolver {
provider = new cpl.ProviderMeta(provider.provide, provider); provider = new cpl.ProviderMeta(provider.provide, provider);
} }
let compileProvider: cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[]; let compileProvider: cpl.CompileProviderMetadata|cpl.CompileTypeMetadata|any[];
if (isArray(provider)) { if (Array.isArray(provider)) {
compileProvider = this.getProvidersMetadata(provider, targetEntryComponents, debugInfo); compileProvider = this.getProvidersMetadata(provider, targetEntryComponents, debugInfo);
} else if (provider instanceof cpl.ProviderMeta) { } else if (provider instanceof cpl.ProviderMeta) {
let tokenMeta = this.getTokenMetadata(provider.token); let tokenMeta = this.getTokenMetadata(provider.token);
@ -607,17 +631,20 @@ export class CompileMetadataResolver {
} }
private _getEntryComponentsFromProvider(provider: cpl.ProviderMeta): cpl.CompileTypeMetadata[] { private _getEntryComponentsFromProvider(provider: cpl.ProviderMeta): cpl.CompileTypeMetadata[] {
let components: cpl.CompileTypeMetadata[] = []; const components: cpl.CompileTypeMetadata[] = [];
let collectedIdentifiers: cpl.CompileIdentifierMetadata[] = []; const collectedIdentifiers: cpl.CompileIdentifierMetadata[] = [];
if (provider.useFactory || provider.useExisting || provider.useClass) { if (provider.useFactory || provider.useExisting || provider.useClass) {
throw new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`); throw new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports useValue!`);
} }
if (!provider.multi) { if (!provider.multi) {
throw new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`); throw new Error(`The ANALYZE_FOR_ENTRY_COMPONENTS token only supports 'multi = true'!`);
} }
convertToCompileValue(provider.useValue, collectedIdentifiers); convertToCompileValue(provider.useValue, collectedIdentifiers);
collectedIdentifiers.forEach((identifier) => { collectedIdentifiers.forEach((identifier) => {
let dirMeta = this.getDirectiveMetadata(identifier.reference, false); const dirMeta = this.getDirectiveMetadata(identifier.reference, false);
if (dirMeta) { if (dirMeta) {
components.push(dirMeta.type); components.push(dirMeta.type);
} }
@ -626,15 +653,15 @@ export class CompileMetadataResolver {
} }
getProviderMetadata(provider: cpl.ProviderMeta): cpl.CompileProviderMetadata { getProviderMetadata(provider: cpl.ProviderMeta): cpl.CompileProviderMetadata {
var compileDeps: cpl.CompileDiDependencyMetadata[]; let compileDeps: cpl.CompileDiDependencyMetadata[];
var compileTypeMetadata: cpl.CompileTypeMetadata = null; let compileTypeMetadata: cpl.CompileTypeMetadata = null;
var compileFactoryMetadata: cpl.CompileFactoryMetadata = null; let compileFactoryMetadata: cpl.CompileFactoryMetadata = null;
if (isPresent(provider.useClass)) { if (provider.useClass) {
compileTypeMetadata = this.getTypeMetadata( compileTypeMetadata = this.getTypeMetadata(
provider.useClass, staticTypeModuleUrl(provider.useClass), provider.dependencies); provider.useClass, staticTypeModuleUrl(provider.useClass), provider.dependencies);
compileDeps = compileTypeMetadata.diDeps; compileDeps = compileTypeMetadata.diDeps;
} else if (isPresent(provider.useFactory)) { } else if (provider.useFactory) {
compileFactoryMetadata = this.getFactoryMetadata( compileFactoryMetadata = this.getFactoryMetadata(
provider.useFactory, staticTypeModuleUrl(provider.useFactory), provider.dependencies); provider.useFactory, staticTypeModuleUrl(provider.useFactory), provider.dependencies);
compileDeps = compileFactoryMetadata.diDeps; compileDeps = compileFactoryMetadata.diDeps;
@ -645,8 +672,7 @@ export class CompileMetadataResolver {
useClass: compileTypeMetadata, useClass: compileTypeMetadata,
useValue: convertToCompileValue(provider.useValue, []), useValue: convertToCompileValue(provider.useValue, []),
useFactory: compileFactoryMetadata, useFactory: compileFactoryMetadata,
useExisting: isPresent(provider.useExisting) ? this.getTokenMetadata(provider.useExisting) : useExisting: provider.useExisting ? this.getTokenMetadata(provider.useExisting) : null,
null,
deps: compileDeps, deps: compileDeps,
multi: provider.multi multi: provider.multi
}); });
@ -655,38 +681,38 @@ export class CompileMetadataResolver {
getQueriesMetadata( getQueriesMetadata(
queries: {[key: string]: Query}, isViewQuery: boolean, queries: {[key: string]: Query}, isViewQuery: boolean,
directiveType: Type<any>): cpl.CompileQueryMetadata[] { directiveType: Type<any>): cpl.CompileQueryMetadata[] {
var res: cpl.CompileQueryMetadata[] = []; const res: cpl.CompileQueryMetadata[] = [];
StringMapWrapper.forEach(queries, (query: Query, propertyName: string) => {
Object.keys(queries).forEach((propertyName: string) => {
const query = queries[propertyName];
if (query.isViewQuery === isViewQuery) { if (query.isViewQuery === isViewQuery) {
res.push(this.getQueryMetadata(query, propertyName, directiveType)); res.push(this.getQueryMetadata(query, propertyName, directiveType));
} }
}); });
return res; return res;
} }
private _queryVarBindings(selector: any): string[] { private _queryVarBindings(selector: any): string[] { return selector.split(/\s*,\s*/); }
return StringWrapper.split(selector, /\s*,\s*/g);
}
getQueryMetadata(q: Query, propertyName: string, typeOrFunc: Type<any>|Function): getQueryMetadata(q: Query, propertyName: string, typeOrFunc: Type<any>|Function):
cpl.CompileQueryMetadata { cpl.CompileQueryMetadata {
var selectors: cpl.CompileTokenMetadata[]; var selectors: cpl.CompileTokenMetadata[];
if (isString(q.selector)) { if (typeof q.selector === 'string') {
selectors = this._queryVarBindings(q.selector).map(varName => this.getTokenMetadata(varName)); selectors = this._queryVarBindings(q.selector).map(varName => this.getTokenMetadata(varName));
} else { } else {
if (!isPresent(q.selector)) { if (!q.selector) {
throw new Error( throw new Error(
`Can't construct a query for the property "${propertyName}" of "${stringify(typeOrFunc)}" since the query selector wasn't defined.`); `Can't construct a query for the property "${propertyName}" of "${stringify(typeOrFunc)}" since the query selector wasn't defined.`);
} }
selectors = [this.getTokenMetadata(q.selector)]; selectors = [this.getTokenMetadata(q.selector)];
} }
return new cpl.CompileQueryMetadata({ return new cpl.CompileQueryMetadata({
selectors: selectors, selectors,
first: q.first, first: q.first,
descendants: q.descendants, descendants: q.descendants, propertyName,
propertyName: propertyName, read: q.read ? this.getTokenMetadata(q.read) : null
read: isPresent(q.read) ? this.getTokenMetadata(q.read) : null
}); });
} }
} }
@ -713,9 +739,9 @@ function getTransitiveModules(
function flattenArray(tree: any[], out: Array<any> = []): Array<any> { function flattenArray(tree: any[], out: Array<any> = []): Array<any> {
if (tree) { if (tree) {
for (var i = 0; i < tree.length; i++) { for (let i = 0; i < tree.length; i++) {
var item = resolveForwardRef(tree[i]); const item = resolveForwardRef(tree[i]);
if (isArray(item)) { if (Array.isArray(item)) {
flattenArray(item, out); flattenArray(item, out);
} else { } else {
out.push(item); out.push(item);
@ -733,16 +759,15 @@ function staticTypeModuleUrl(value: any): string {
return cpl.isStaticSymbol(value) ? value.filePath : null; return cpl.isStaticSymbol(value) ? value.filePath : null;
} }
function componentModuleUrl(reflector: ReflectorReader, type: any, cmpMetadata: Component): string { function componentModuleUrl(reflector: ReflectorReader, type: Type<any>, cmpMetadata: Component): string {
if (cpl.isStaticSymbol(type)) { if (cpl.isStaticSymbol(type)) {
return staticTypeModuleUrl(type); return staticTypeModuleUrl(type);
} }
if (isPresent(cmpMetadata.moduleId)) { if (isPresent(cmpMetadata.moduleId)) {
var moduleId = cmpMetadata.moduleId; const moduleId = cmpMetadata.moduleId;
var scheme = getUrlScheme(moduleId); const scheme = getUrlScheme(moduleId);
return isPresent(scheme) && scheme.length > 0 ? moduleId : return scheme ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`;
`package:${moduleId}${MODULE_SUFFIX}`;
} }
return reflector.importUri(type); return reflector.importUri(type);

View File

@ -7,7 +7,7 @@
*/ */
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings'; import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings';
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, Component, Directive, DoCheck, Injectable, NgModule, OnChanges, OnDestroy, OnInit, Pipe, SimpleChanges, ViewEncapsulation} from '@angular/core'; import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, Component, DoCheck, Injectable, NgModule, OnChanges, OnDestroy, OnInit, Pipe, SimpleChanges, ViewEncapsulation} from '@angular/core';
import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks'; import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks';
import {TestBed, inject} from '@angular/core/testing'; import {TestBed, inject} from '@angular/core/testing';
@ -23,7 +23,7 @@ export function main() {
describe('getDirectiveMetadata', () => { describe('getDirectiveMetadata', () => {
it('should read metadata', it('should read metadata',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => { inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
var meta = resolver.getDirectiveMetadata(ComponentWithEverything); const meta = resolver.getDirectiveMetadata(ComponentWithEverything);
expect(meta.selector).toEqual('someSelector'); expect(meta.selector).toEqual('someSelector');
expect(meta.exportAs).toEqual('someExportAs'); expect(meta.exportAs).toEqual('someExportAs');
expect(meta.isComponent).toBe(true); expect(meta.isComponent).toBe(true);
@ -175,14 +175,6 @@ export function main() {
}); });
} }
@Directive({selector: 'a-directive'})
class ADirective {
}
@Directive({selector: 'someSelector'})
class SomeDirective {
}
@Component({selector: 'someComponent', template: ''}) @Component({selector: 'someComponent', template: ''})
class ComponentWithoutModuleId { class ComponentWithoutModuleId {
} }