feat(transformers): changes transformers to collect information about providers and resolve identifiers during linking

Closes #7380
This commit is contained in:
vsavkin
2016-04-04 10:32:28 -07:00
committed by Victor Savkin
parent bd8a4215dd
commit 4e9809bcb2
45 changed files with 2424 additions and 979 deletions

View File

@ -1,13 +1,16 @@
import {
isPresent,
isBlank,
isNumber,
isBoolean,
normalizeBool,
normalizeBlank,
serializeEnum,
Type,
isString,
RegExpWrapper,
StringWrapper
StringWrapper,
isArray
} from 'angular2/src/facade/lang';
import {unimplemented} from 'angular2/src/facade/exceptions';
import {StringMapWrapper} from 'angular2/src/facade/collection';
@ -25,20 +28,12 @@ import {LifecycleHooks, LIFECYCLE_HOOKS_VALUES} from 'angular2/src/core/linker/i
var HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))$/g;
export abstract class CompileMetadataWithIdentifier {
static fromJson(data: {[key: string]: any}): CompileMetadataWithIdentifier {
return _COMPILE_METADATA_FROM_JSON[data['class']](data);
}
abstract toJson(): {[key: string]: any};
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
}
export abstract class CompileMetadataWithType extends CompileMetadataWithIdentifier {
static fromJson(data: {[key: string]: any}): CompileMetadataWithType {
return _COMPILE_METADATA_FROM_JSON[data['class']](data);
}
abstract toJson(): {[key: string]: any};
get type(): CompileTypeMetadata { return <CompileTypeMetadata>unimplemented(); }
@ -46,43 +41,57 @@ export abstract class CompileMetadataWithType extends CompileMetadataWithIdentif
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
}
export function metadataFromJson(data: {[key: string]: any}): any {
return _COMPILE_METADATA_FROM_JSON[data['class']](data);
}
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
runtime: any;
name: string;
prefix: string;
moduleUrl: string;
constConstructor: boolean;
constructor({runtime, name, moduleUrl, prefix, constConstructor}: {
value: any;
constructor({runtime, name, moduleUrl, prefix, constConstructor, value}: {
runtime?: any,
name?: string,
staticMethodName?: string,
moduleUrl?: string,
prefix?: string,
constConstructor?: boolean
constConstructor?: boolean,
value?: any
} = {}) {
this.runtime = runtime;
this.name = name;
this.prefix = prefix;
this.moduleUrl = moduleUrl;
this.constConstructor = constConstructor;
this.value = value;
}
static fromJson(data: {[key: string]: any}): CompileIdentifierMetadata {
let value = isArray(data['value']) ? arrayFromJson(data['value'], metadataFromJson) :
objFromJson(data['value'], metadataFromJson);
return new CompileIdentifierMetadata({
name: data['name'],
prefix: data['prefix'],
moduleUrl: data['moduleUrl'],
constConstructor: data['constConstructor']
constConstructor: data['constConstructor'],
value: value
});
}
toJson(): {[key: string]: any} {
let value = isArray(this.value) ? arrayToJson(this.value) : objToJson(this.value);
return {
// Note: Runtime type can't be serialized...
'class': 'Identifier',
'name': this.name,
'moduleUrl': this.moduleUrl,
'prefix': this.prefix,
'constConstructor': this.constConstructor
'constConstructor': this.constConstructor,
'value': value
};
}
@ -177,44 +186,78 @@ export class CompileProviderMetadata {
static fromJson(data: {[key: string]: any}): CompileProviderMetadata {
return new CompileProviderMetadata({
token: objFromJson(data['token'], CompileIdentifierMetadata.fromJson),
useClass: objFromJson(data['useClass'], CompileTypeMetadata.fromJson)
useClass: objFromJson(data['useClass'], CompileTypeMetadata.fromJson),
useExisting: objFromJson(data['useExisting'], CompileIdentifierMetadata.fromJson),
useValue: objFromJson(data['useValue'], CompileIdentifierMetadata.fromJson),
useFactory: objFromJson(data['useFactory'], CompileFactoryMetadata.fromJson)
});
}
toJson(): {[key: string]: any} {
return {
// Note: Runtime type can't be serialized...
'class': 'Provider',
'token': objToJson(this.token),
'useClass': objToJson(this.useClass)
'useClass': objToJson(this.useClass),
'useExisting': objToJson(this.useExisting),
'useValue': objToJson(this.useValue),
'useFactory': objToJson(this.useFactory)
};
}
}
export class CompileFactoryMetadata implements CompileIdentifierMetadata {
export class CompileFactoryMetadata implements CompileIdentifierMetadata,
CompileMetadataWithIdentifier {
runtime: Function;
name: string;
prefix: string;
moduleUrl: string;
constConstructor: boolean;
value: any;
diDeps: CompileDiDependencyMetadata[];
constructor({runtime, name, moduleUrl, constConstructor, diDeps}: {
constructor({runtime, name, moduleUrl, prefix, constConstructor, diDeps, value}: {
runtime?: Function,
name?: string,
prefix?: string,
moduleUrl?: string,
constConstructor?: boolean,
value?: boolean,
diDeps?: CompileDiDependencyMetadata[]
}) {
this.runtime = runtime;
this.name = name;
this.prefix = prefix;
this.moduleUrl = moduleUrl;
this.diDeps = diDeps;
this.constConstructor = constConstructor;
this.value = value;
}
get identifier(): CompileIdentifierMetadata { return this; }
toJson() { return null; }
static fromJson(data: {[key: string]: any}): CompileFactoryMetadata {
return new CompileFactoryMetadata({
name: data['name'],
prefix: data['prefix'],
moduleUrl: data['moduleUrl'],
constConstructor: data['constConstructor'],
value: data['value'],
diDeps: arrayFromJson(data['diDeps'], CompileDiDependencyMetadata.fromJson)
});
}
toJson(): {[key: string]: any} {
return {
'class': 'Factory',
'name': this.name,
'prefix': this.prefix,
'moduleUrl': this.moduleUrl,
'constConstructor': this.constConstructor,
'value': this.value,
'diDeps': arrayToJson(this.diDeps)
};
}
}
/**
@ -227,15 +270,17 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
moduleUrl: string;
isHost: boolean;
constConstructor: boolean;
value: any;
diDeps: CompileDiDependencyMetadata[];
constructor({runtime, name, moduleUrl, prefix, isHost, constConstructor, diDeps}: {
constructor({runtime, name, moduleUrl, prefix, isHost, constConstructor, value, diDeps}: {
runtime?: Type,
name?: string,
moduleUrl?: string,
prefix?: string,
isHost?: boolean,
constConstructor?: boolean,
value?: any,
diDeps?: CompileDiDependencyMetadata[]
} = {}) {
this.runtime = runtime;
@ -244,6 +289,7 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
this.prefix = prefix;
this.isHost = normalizeBool(isHost);
this.constConstructor = constConstructor;
this.value = value;
this.diDeps = normalizeBlank(diDeps);
}
@ -254,6 +300,7 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
prefix: data['prefix'],
isHost: data['isHost'],
constConstructor: data['constConstructor'],
value: data['value'],
diDeps: arrayFromJson(data['diDeps'], CompileDiDependencyMetadata.fromJson)
});
}
@ -270,6 +317,7 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
'prefix': this.prefix,
'isHost': this.isHost,
'constConstructor': this.constConstructor,
'value': this.value,
'diDeps': arrayToJson(this.diDeps)
};
}
@ -382,8 +430,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
outputs?: string[],
host?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>,
viewProviders?: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>,
providers?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
viewProviders?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata
@ -474,8 +524,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
hostProperties?: {[key: string]: string},
hostAttributes?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[],
providers?: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>,
viewProviders?: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>,
providers?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
viewProviders?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>,
queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata
@ -494,8 +546,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
this.lifecycleHooks = lifecycleHooks;
this.providers = normalizeBlank(providers);
this.viewProviders = normalizeBlank(viewProviders);
this.queries = queries;
this.viewQueries = viewQueries;
this.queries = normalizeBlank(queries);
this.viewQueries = normalizeBlank(viewQueries);
this.template = template;
}
@ -520,7 +572,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
(<any[]>data['lifecycleHooks']).map(hookValue => LIFECYCLE_HOOKS_VALUES[hookValue]),
template: isPresent(data['template']) ? CompileTemplateMetadata.fromJson(data['template']) :
data['template'],
providers: arrayFromJson(data['providers'], CompileProviderMetadata.fromJson)
providers: arrayFromJson(data['providers'], metadataFromJson),
viewProviders: arrayFromJson(data['viewProviders'], metadataFromJson),
queries: arrayFromJson(data['queries'], CompileQueryMetadata.fromJson),
viewQueries: arrayFromJson(data['viewQueries'], CompileQueryMetadata.fromJson)
});
}
@ -541,7 +596,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
'hostAttributes': this.hostAttributes,
'lifecycleHooks': this.lifecycleHooks.map(hook => serializeEnum(hook)),
'template': isPresent(this.template) ? this.template.toJson() : this.template,
'providers': arrayToJson(this.providers)
'providers': arrayToJson(this.providers),
'viewProviders': arrayToJson(this.viewProviders),
'queries': arrayToJson(this.queries),
'viewQueries': arrayToJson(this.viewQueries)
};
}
}
@ -611,7 +669,9 @@ var _COMPILE_METADATA_FROM_JSON = {
'Directive': CompileDirectiveMetadata.fromJson,
'Pipe': CompilePipeMetadata.fromJson,
'Type': CompileTypeMetadata.fromJson,
'Identifier': CompileIdentifierMetadata.fromJson
'Provider': CompileProviderMetadata.fromJson,
'Identifier': CompileIdentifierMetadata.fromJson,
'Factory': CompileFactoryMetadata.fromJson
};
function arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
@ -623,9 +683,9 @@ function arrayToJson(obj: any[]): string | {[key: string]: any} {
}
function objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {
return (isString(obj) || isBlank(obj)) ? obj : fn(obj);
return (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) ? obj : fn(obj);
}
function objToJson(obj: any): string | {[key: string]: any} {
return (isString(obj) || isBlank(obj)) ? obj : obj.toJson();
return (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) ? obj : obj.toJson();
}

View File

@ -110,6 +110,9 @@ export class TemplateCompiler {
hostAttributes: directive.hostAttributes,
lifecycleHooks: directive.lifecycleHooks,
providers: directive.providers,
viewProviders: directive.viewProviders,
queries: directive.queries,
viewQueries: directive.viewQueries,
template: normalizedTemplate
}));
}

View File

@ -33,6 +33,7 @@ bool isStringMap(Object obj) => obj is Map;
bool isArray(Object obj) => obj is List;
bool isPromise(Object obj) => obj is Future;
bool isNumber(Object obj) => obj is num;
bool isBoolean(Object obj) => obj is bool;
bool isDate(Object obj) => obj is DateTime;
String stringify(obj) {

View File

@ -124,6 +124,14 @@ export function isBlank(obj: any): boolean {
return obj === undefined || obj === null;
}
export function isBoolean(obj: any): boolean {
return typeof obj === "boolean";
}
export function isNumber(obj: any): boolean {
return typeof obj === "number";
}
export function isString(obj: any): boolean {
return typeof obj === "string";
}
@ -148,10 +156,6 @@ export function isArray(obj: any): boolean {
return Array.isArray(obj);
}
export function isNumber(obj): boolean {
return typeof obj === 'number';
}
export function isDate(obj): boolean {
return obj instanceof Date && !isNaN(obj.valueOf());
}