refactor(core): change module semantics

This contains major changes to the compiler, bootstrap of the platforms
and test environment initialization.

Main part of #10043
Closes #10164

BREAKING CHANGE:
- Semantics and name of `@AppModule` (now `@NgModule`) changed quite a bit.
  This is actually not breaking as `@AppModules` were not part of rc.4.
  We will have detailed docs on `@NgModule` separately.
- `coreLoadAndBootstrap` and `coreBootstrap` can't be used any more (without migration support).
  Use `bootstrapModule` / `bootstrapModuleFactory` instead.
- All Components listed in routes have to be part of the `declarations` of an NgModule.
  Either directly on the bootstrap module / lazy loaded module, or in an NgModule imported by them.
This commit is contained in:
Tobias Bosch
2016-07-18 03:50:31 -07:00
parent ca16fc29a6
commit 46b212706b
129 changed files with 3580 additions and 3366 deletions

View File

@ -22,139 +22,55 @@ import {sanitizeIdentifier, splitAtColon} from './util';
// group 1: "prop" from "[prop]"
// group 2: "event" from "(event)"
// group 3: "@trigger" from "@trigger"
var HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/g;
const HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/g;
const UNDEFINED = new Object();
export abstract class CompileMetadataWithIdentifier {
abstract toJson(): {[key: string]: any};
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
}
export abstract class CompileMetadataWithType extends CompileMetadataWithIdentifier {
abstract toJson(): {[key: string]: any};
get runtimeCacheKey(): any { return unimplemented(); }
get type(): CompileTypeMetadata { return <CompileTypeMetadata>unimplemented(); }
get assetCacheKey(): any { return unimplemented(); }
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
}
export function metadataFromJson(data: {[key: string]: any}): any {
return (_COMPILE_METADATA_FROM_JSON as any)[data['class']](data);
equalsTo(id2: CompileMetadataWithIdentifier): boolean { return unimplemented(); }
}
export class CompileAnimationEntryMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationEntryMetadata {
var value = data['value'];
var defs = _arrayFromJson(value['definitions'], metadataFromJson);
return new CompileAnimationEntryMetadata(value['name'], defs);
}
constructor(
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationEntryMetadata',
'value': {'name': this.name, 'definitions': _arrayToJson(this.definitions)}
};
}
}
export abstract class CompileAnimationStateMetadata {}
export class CompileAnimationStateDeclarationMetadata extends CompileAnimationStateMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationStateDeclarationMetadata {
var value = data['value'];
var styles = _objFromJson(value['styles'], metadataFromJson);
return new CompileAnimationStateDeclarationMetadata(value['stateNameExpr'], styles);
}
constructor(public stateNameExpr: string, public styles: CompileAnimationStyleMetadata) {
super();
}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationStateDeclarationMetadata',
'value': {'stateNameExpr': this.stateNameExpr, 'styles': this.styles.toJson()}
};
}
}
export class CompileAnimationStateTransitionMetadata extends CompileAnimationStateMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationStateTransitionMetadata {
var value = data['value'];
var steps = _objFromJson(value['steps'], metadataFromJson);
return new CompileAnimationStateTransitionMetadata(value['stateChangeExpr'], steps);
}
constructor(public stateChangeExpr: string, public steps: CompileAnimationMetadata) { super(); }
toJson(): {[key: string]: any} {
return {
'class': 'AnimationStateTransitionMetadata',
'value': {'stateChangeExpr': this.stateChangeExpr, 'steps': this.steps.toJson()}
};
}
}
export abstract class CompileAnimationMetadata { abstract toJson(): {[key: string]: any}; }
export abstract class CompileAnimationMetadata {}
export class CompileAnimationKeyframesSequenceMetadata extends CompileAnimationMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationKeyframesSequenceMetadata {
var steps = _arrayFromJson(data['value'], metadataFromJson);
return new CompileAnimationKeyframesSequenceMetadata(<CompileAnimationStyleMetadata[]>steps);
}
constructor(public steps: CompileAnimationStyleMetadata[] = []) { super(); }
toJson(): {[key: string]: any} {
return {'class': 'AnimationKeyframesSequenceMetadata', 'value': _arrayToJson(this.steps)};
}
}
export class CompileAnimationStyleMetadata extends CompileAnimationMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationStyleMetadata {
var value = data['value'];
var offsetVal = value['offset'];
var offset = isPresent(offsetVal) ? NumberWrapper.parseFloat(offsetVal) : null;
var styles = <Array<string|{[key: string]: string | number}>>value['styles'];
return new CompileAnimationStyleMetadata(offset, styles);
}
constructor(
public offset: number, public styles: Array<string|{[key: string]: string | number}> = null) {
super();
}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationStyleMetadata',
'value': {'offset': this.offset, 'styles': this.styles}
};
}
}
export class CompileAnimationAnimateMetadata extends CompileAnimationMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationAnimateMetadata {
var value = data['value'];
var timings = <string|number>value['timings'];
var styles = _objFromJson(value['styles'], metadataFromJson);
return new CompileAnimationAnimateMetadata(timings, styles);
}
constructor(
public timings: string|number = 0, public styles: CompileAnimationStyleMetadata|
CompileAnimationKeyframesSequenceMetadata = null) {
super();
}
toJson(): {[key: string]: any} {
return {
'class': 'AnimationAnimateMetadata',
'value': {'timings': this.timings, 'styles': _objToJson(this.styles)}
};
}
}
export abstract class CompileAnimationWithStepsMetadata extends CompileAnimationMetadata {
@ -162,29 +78,11 @@ export abstract class CompileAnimationWithStepsMetadata extends CompileAnimation
}
export class CompileAnimationSequenceMetadata extends CompileAnimationWithStepsMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationSequenceMetadata {
var steps = _arrayFromJson(data['value'], metadataFromJson);
return new CompileAnimationSequenceMetadata(steps);
}
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
toJson(): {[key: string]: any} {
return {'class': 'AnimationSequenceMetadata', 'value': _arrayToJson(this.steps)};
}
}
export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMetadata {
static fromJson(data: {[key: string]: any}): CompileAnimationGroupMetadata {
var steps = _arrayFromJson(data['value'], metadataFromJson);
return new CompileAnimationGroupMetadata(steps);
}
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
toJson(): {[key: string]: any} {
return {'class': 'AnimationGroupMetadata', 'value': _arrayToJson(this.steps)};
}
}
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
@ -193,6 +91,7 @@ export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier
prefix: string;
moduleUrl: string;
value: any;
private _assetCacheKey: any = UNDEFINED;
constructor(
{runtime, name, moduleUrl, prefix, value}:
@ -204,26 +103,28 @@ export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier
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'], 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,
'value': value
};
}
get identifier(): CompileIdentifierMetadata { return this; }
get runtimeCacheKey(): any { return this.identifier.runtime; }
get assetCacheKey(): any {
if (this._assetCacheKey === UNDEFINED) {
if (isPresent(this.moduleUrl) && isPresent(getUrlScheme(this.moduleUrl))) {
var uri = reflector.importUri({'filePath': this.moduleUrl, 'name': this.name});
this._assetCacheKey = `${this.name}|${uri}`;
} else {
this._assetCacheKey = null;
}
}
return this._assetCacheKey;
}
equalsTo(id2: CompileIdentifierMetadata): boolean {
var rk = this.runtimeCacheKey;
var ak = this.assetCacheKey;
return (isPresent(rk) && rk == id2.runtimeCacheKey) ||
(isPresent(ak) && ak == id2.assetCacheKey);
}
}
export class CompileDiDependencyMetadata {
@ -263,36 +164,6 @@ export class CompileDiDependencyMetadata {
this.token = token;
this.value = value;
}
static fromJson(data: {[key: string]: any}): CompileDiDependencyMetadata {
return new CompileDiDependencyMetadata({
token: _objFromJson(data['token'], CompileTokenMetadata.fromJson),
query: _objFromJson(data['query'], CompileQueryMetadata.fromJson),
viewQuery: _objFromJson(data['viewQuery'], CompileQueryMetadata.fromJson),
value: data['value'],
isAttribute: data['isAttribute'],
isSelf: data['isSelf'],
isHost: data['isHost'],
isSkipSelf: data['isSkipSelf'],
isOptional: data['isOptional'],
isValue: data['isValue']
});
}
toJson(): {[key: string]: any} {
return {
'token': _objToJson(this.token),
'query': _objToJson(this.query),
'viewQuery': _objToJson(this.viewQuery),
'value': this.value,
'isAttribute': this.isAttribute,
'isSelf': this.isSelf,
'isHost': this.isHost,
'isSkipSelf': this.isSkipSelf,
'isOptional': this.isOptional,
'isValue': this.isValue
};
}
}
export class CompileProviderMetadata {
@ -321,41 +192,9 @@ export class CompileProviderMetadata {
this.deps = normalizeBlank(deps);
this.multi = normalizeBool(multi);
}
static fromJson(data: {[key: string]: any}): CompileProviderMetadata {
return new CompileProviderMetadata({
token: _objFromJson(data['token'], CompileTokenMetadata.fromJson),
useClass: _objFromJson(data['useClass'], CompileTypeMetadata.fromJson),
useExisting: _objFromJson(data['useExisting'], CompileTokenMetadata.fromJson),
useValue: _objFromJson(data['useValue'], CompileIdentifierMetadata.fromJson),
useFactory: _objFromJson(data['useFactory'], CompileFactoryMetadata.fromJson),
multi: data['multi'],
deps: _arrayFromJson(data['deps'], CompileDiDependencyMetadata.fromJson)
});
}
toJson(): {[key: string]: any} {
return {
// Note: Runtime type can't be serialized...
'class': 'Provider',
'token': _objToJson(this.token),
'useClass': _objToJson(this.useClass),
'useExisting': _objToJson(this.useExisting),
'useValue': _objToJson(this.useValue),
'useFactory': _objToJson(this.useFactory),
'multi': this.multi,
'deps': _arrayToJson(this.deps)
};
}
}
export class CompileFactoryMetadata implements CompileIdentifierMetadata,
CompileMetadataWithIdentifier {
runtime: Function;
name: string;
prefix: string;
moduleUrl: string;
value: any;
export class CompileFactoryMetadata extends CompileIdentifierMetadata {
diDeps: CompileDiDependencyMetadata[];
constructor({runtime, name, moduleUrl, prefix, diDeps, value}: {
@ -366,45 +205,15 @@ export class CompileFactoryMetadata implements CompileIdentifierMetadata,
value?: boolean,
diDeps?: CompileDiDependencyMetadata[]
}) {
this.runtime = runtime;
this.name = name;
this.prefix = prefix;
this.moduleUrl = moduleUrl;
super({runtime: runtime, name: name, prefix: prefix, moduleUrl: moduleUrl, value: value});
this.diDeps = _normalizeArray(diDeps);
this.value = value;
}
get identifier(): CompileIdentifierMetadata { return this; }
static fromJson(data: {[key: string]: any}): CompileFactoryMetadata {
return new CompileFactoryMetadata({
name: data['name'],
prefix: data['prefix'],
moduleUrl: data['moduleUrl'],
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,
'value': this.value,
'diDeps': _arrayToJson(this.diDeps)
};
}
}
var UNDEFINED = new Object();
export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
value: any;
identifier: CompileIdentifierMetadata;
identifierIsInstance: boolean;
private _assetCacheKey = UNDEFINED;
constructor(
{value, identifier, identifierIsInstance}:
@ -414,46 +223,20 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
this.identifierIsInstance = normalizeBool(identifierIsInstance);
}
static fromJson(data: {[key: string]: any}): CompileTokenMetadata {
return new CompileTokenMetadata({
value: data['value'],
identifier: _objFromJson(data['identifier'], CompileIdentifierMetadata.fromJson),
identifierIsInstance: data['identifierIsInstance']
});
}
toJson(): {[key: string]: any} {
return {
'value': this.value,
'identifier': _objToJson(this.identifier),
'identifierIsInstance': this.identifierIsInstance
};
}
get runtimeCacheKey(): any {
if (isPresent(this.identifier)) {
return this.identifier.runtime;
return this.identifier.runtimeCacheKey;
} else {
return this.value;
}
}
get assetCacheKey(): any {
if (this._assetCacheKey === UNDEFINED) {
if (isPresent(this.identifier)) {
if (isPresent(this.identifier.moduleUrl) &&
isPresent(getUrlScheme(this.identifier.moduleUrl))) {
var uri = reflector.importUri(
{'filePath': this.identifier.moduleUrl, 'name': this.identifier.name});
this._assetCacheKey = `${this.identifier.name}|${uri}|${this.identifierIsInstance}`;
} else {
this._assetCacheKey = null;
}
} else {
this._assetCacheKey = this.value;
}
if (isPresent(this.identifier)) {
return this.identifier.assetCacheKey;
} else {
return this.value;
}
return this._assetCacheKey;
}
equalsTo(token2: CompileTokenMetadata): boolean {
@ -468,15 +251,24 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
}
}
export class CompileTokenMap<VALUE> {
/**
* Note: We only need this in places where we need to support identifiers that
* don't have a `runtime` value given by the `StaticReflector`. E.g. see the `identifiers`
* file where we have some identifiers hard coded by name/module path.
*
* TODO(tbosch): Eventually, all of these places should go through the static reflector
* as well, providing them with a valid `StaticSymbol` that is again a singleton.
*/
export class CompileIdentifierMap<KEY extends CompileMetadataWithIdentifier, VALUE> {
private _valueMap = new Map<any, VALUE>();
private _values: VALUE[] = [];
private _tokens: CompileTokenMetadata[] = [];
private _tokens: KEY[] = [];
add(token: CompileTokenMetadata, value: VALUE) {
add(token: KEY, value: VALUE) {
var existing = this.get(token);
if (isPresent(existing)) {
throw new BaseException(`Can only add to a TokenMap! Token: ${token.name}`);
throw new BaseException(
`Cannot overwrite in a CompileIdentifierMap! Token: ${token.identifier.name}`);
}
this._tokens.push(token);
this._values.push(value);
@ -489,7 +281,7 @@ export class CompileTokenMap<VALUE> {
this._valueMap.set(ak, value);
}
}
get(token: CompileTokenMetadata): VALUE {
get(token: KEY): VALUE {
var rk = token.runtimeCacheKey;
var ak = token.assetCacheKey;
var result: VALUE;
@ -501,7 +293,7 @@ export class CompileTokenMap<VALUE> {
}
return result;
}
keys(): CompileTokenMetadata[] { return this._tokens; }
keys(): KEY[] { return this._tokens; }
values(): VALUE[] { return this._values; }
get size(): number { return this._values.length; }
}
@ -509,13 +301,8 @@ export class CompileTokenMap<VALUE> {
/**
* Metadata regarding compilation of a type.
*/
export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMetadataWithType {
runtime: Type;
name: string;
prefix: string;
moduleUrl: string;
export class CompileTypeMetadata extends CompileIdentifierMetadata {
isHost: boolean;
value: any;
diDeps: CompileDiDependencyMetadata[];
constructor({runtime, name, moduleUrl, prefix, isHost, value, diDeps}: {
@ -527,41 +314,10 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
value?: any,
diDeps?: CompileDiDependencyMetadata[]
} = {}) {
this.runtime = runtime;
this.name = name;
this.moduleUrl = moduleUrl;
this.prefix = prefix;
super({runtime: runtime, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value});
this.isHost = normalizeBool(isHost);
this.value = value;
this.diDeps = _normalizeArray(diDeps);
}
static fromJson(data: {[key: string]: any}): CompileTypeMetadata {
return new CompileTypeMetadata({
name: data['name'],
moduleUrl: data['moduleUrl'],
prefix: data['prefix'],
isHost: data['isHost'],
value: data['value'],
diDeps: _arrayFromJson(data['diDeps'], CompileDiDependencyMetadata.fromJson)
});
}
get identifier(): CompileIdentifierMetadata { return this; }
get type(): CompileTypeMetadata { return this; }
toJson(): {[key: string]: any} {
return {
// Note: Runtime type can't be serialized...
'class': 'Type',
'name': this.name,
'moduleUrl': this.moduleUrl,
'prefix': this.prefix,
'isHost': this.isHost,
'value': this.value,
'diDeps': _arrayToJson(this.diDeps)
};
}
}
export class CompileQueryMetadata {
@ -584,26 +340,6 @@ export class CompileQueryMetadata {
this.propertyName = propertyName;
this.read = read;
}
static fromJson(data: {[key: string]: any}): CompileQueryMetadata {
return new CompileQueryMetadata({
selectors: _arrayFromJson(data['selectors'], CompileTokenMetadata.fromJson),
descendants: data['descendants'],
first: data['first'],
propertyName: data['propertyName'],
read: _objFromJson(data['read'], CompileTokenMetadata.fromJson)
});
}
toJson(): {[key: string]: any} {
return {
'selectors': _arrayToJson(this.selectors),
'descendants': this.descendants,
'first': this.first,
'propertyName': this.propertyName,
'read': _objToJson(this.read)
};
}
}
/**
@ -620,15 +356,6 @@ export class CompileStylesheetMetadata {
this.styles = _normalizeArray(styles);
this.styleUrls = _normalizeArray(styleUrls);
}
static fromJson(data: {[key: string]: any}): CompileStylesheetMetadata {
return new CompileStylesheetMetadata(
{moduleUrl: data['moduleUrl'], styles: data['styles'], styleUrls: data['styleUrls']});
}
toJson(): {[key: string]: any} {
return {'moduleUrl': this.moduleUrl, 'styles': this.styles, 'styleUrls': this.styleUrls};
}
}
/**
@ -670,46 +397,12 @@ export class CompileTemplateMetadata {
}
this.interpolation = interpolation;
}
static fromJson(data: {[key: string]: any}): CompileTemplateMetadata {
var animations =
<CompileAnimationEntryMetadata[]>_arrayFromJson(data['animations'], metadataFromJson);
return new CompileTemplateMetadata({
encapsulation: isPresent(data['encapsulation']) ?
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
data['encapsulation'],
template: data['template'],
templateUrl: data['templateUrl'],
styles: data['styles'],
styleUrls: data['styleUrls'],
externalStylesheets:
_arrayFromJson(data['externalStylesheets'], CompileStylesheetMetadata.fromJson),
animations: animations,
ngContentSelectors: data['ngContentSelectors'],
interpolation: data['interpolation']
});
}
toJson(): {[key: string]: any} {
return {
'encapsulation': isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) :
this.encapsulation,
'template': this.template,
'templateUrl': this.templateUrl,
'styles': this.styles,
'styleUrls': this.styleUrls,
'externalStylesheets': _objToJson(this.externalStylesheets),
'animations': _objToJson(this.animations),
'ngContentSelectors': this.ngContentSelectors,
'interpolation': this.interpolation
};
}
}
/**
* Metadata regarding compilation of a directive.
*/
export class CompileDirectiveMetadata implements CompileMetadataWithType {
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
lifecycleHooks, providers, viewProviders, queries, viewQueries, precompile, template}: {
@ -796,6 +489,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
viewProviders: CompileProviderMetadata[];
queries: CompileQueryMetadata[];
viewQueries: CompileQueryMetadata[];
// Note: Need to keep types here to prevent cycles!
precompile: CompileTypeMetadata[];
template: CompileTemplateMetadata;
@ -844,68 +538,26 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
get identifier(): CompileIdentifierMetadata { return this.type; }
static fromJson(data: {[key: string]: any}): CompileDirectiveMetadata {
return new CompileDirectiveMetadata({
isComponent: data['isComponent'],
selector: data['selector'],
exportAs: data['exportAs'],
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
changeDetection: isPresent(data['changeDetection']) ?
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
data['changeDetection'],
inputs: data['inputs'],
outputs: data['outputs'],
hostListeners: data['hostListeners'],
hostProperties: data['hostProperties'],
hostAttributes: data['hostAttributes'],
lifecycleHooks:
(<any[]>data['lifecycleHooks']).map(hookValue => LIFECYCLE_HOOKS_VALUES[hookValue]),
template: isPresent(data['template']) ? CompileTemplateMetadata.fromJson(data['template']) :
data['template'],
providers: _arrayFromJson(data['providers'], metadataFromJson),
viewProviders: _arrayFromJson(data['viewProviders'], metadataFromJson),
queries: _arrayFromJson(data['queries'], CompileQueryMetadata.fromJson),
viewQueries: _arrayFromJson(data['viewQueries'], CompileQueryMetadata.fromJson),
precompile: _arrayFromJson(data['precompile'], CompileTypeMetadata.fromJson)
});
}
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
toJson(): {[key: string]: any} {
return {
'class': 'Directive',
'isComponent': this.isComponent,
'selector': this.selector,
'exportAs': this.exportAs,
'type': isPresent(this.type) ? this.type.toJson() : this.type,
'changeDetection': isPresent(this.changeDetection) ? serializeEnum(this.changeDetection) :
this.changeDetection,
'inputs': this.inputs,
'outputs': this.outputs,
'hostListeners': this.hostListeners,
'hostProperties': this.hostProperties,
'hostAttributes': this.hostAttributes,
'lifecycleHooks': this.lifecycleHooks.map(hook => serializeEnum(hook)),
'template': isPresent(this.template) ? this.template.toJson() : this.template,
'providers': _arrayToJson(this.providers),
'viewProviders': _arrayToJson(this.viewProviders),
'queries': _arrayToJson(this.queries),
'viewQueries': _arrayToJson(this.viewQueries),
'precompile': _arrayToJson(this.precompile)
};
get assetCacheKey(): any { return this.type.assetCacheKey; }
equalsTo(other: CompileMetadataWithIdentifier): boolean {
return this.type.equalsTo(other.identifier);
}
}
/**
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
*/
export function createHostComponentMeta(
componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
export function createHostComponentMeta(compMeta: CompileDirectiveMetadata):
CompileDirectiveMetadata {
var template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
return CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({
runtime: Object,
name: `${componentType.name}_Host`,
moduleUrl: componentType.moduleUrl,
name: `${compMeta.type.name}_Host`,
moduleUrl: compMeta.type.moduleUrl,
isHost: true
}),
template: new CompileTemplateMetadata({
@ -931,7 +583,7 @@ export function createHostComponentMeta(
}
export class CompilePipeMetadata implements CompileMetadataWithType {
export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
type: CompileTypeMetadata;
name: string;
pure: boolean;
@ -949,114 +601,91 @@ export class CompilePipeMetadata implements CompileMetadataWithType {
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
}
get identifier(): CompileIdentifierMetadata { return this.type; }
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
static fromJson(data: {[key: string]: any}): CompilePipeMetadata {
return new CompilePipeMetadata({
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
name: data['name'],
pure: data['pure']
});
}
get assetCacheKey(): any { return this.type.assetCacheKey; }
toJson(): {[key: string]: any} {
return {
'class': 'Pipe',
'type': isPresent(this.type) ? this.type.toJson() : null,
'name': this.name,
'pure': this.pure
};
equalsTo(other: CompileMetadataWithIdentifier): boolean {
return this.type.equalsTo(other.identifier);
}
}
/**
* Metadata regarding compilation of a directive.
*/
export class CompileAppModuleMetadata implements CompileMetadataWithType {
export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
type: CompileTypeMetadata;
providers: CompileProviderMetadata[];
directives: CompileTypeMetadata[];
pipes: CompileTypeMetadata[];
declaredDirectives: CompileDirectiveMetadata[];
exportedDirectives: CompileDirectiveMetadata[];
declaredPipes: CompilePipeMetadata[];
exportedPipes: CompilePipeMetadata[];
// Note: See CompileDirectiveMetadata.precompile why this has to be a type.
precompile: CompileTypeMetadata[];
modules: CompileTypeMetadata[];
providers: CompileProviderMetadata[];
constructor({type, providers, directives, pipes, precompile, modules}: {
type?: CompileTypeMetadata,
providers?: Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
directives?: CompileTypeMetadata[],
pipes?: CompileTypeMetadata[],
precompile?: CompileTypeMetadata[],
modules?: CompileTypeMetadata[]
} = {}) {
importedModules: CompileNgModuleMetadata[];
exportedModules: CompileNgModuleMetadata[];
transitiveModule: TransitiveCompileNgModuleMetadata;
constructor(
{type, providers, declaredDirectives, exportedDirectives, declaredPipes, exportedPipes,
precompile, importedModules, exportedModules, transitiveModule}: {
type?: CompileTypeMetadata,
providers?:
Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
declaredDirectives?: CompileDirectiveMetadata[],
exportedDirectives?: CompileDirectiveMetadata[],
declaredPipes?: CompilePipeMetadata[],
exportedPipes?: CompilePipeMetadata[],
precompile?: CompileTypeMetadata[],
importedModules?: CompileNgModuleMetadata[],
exportedModules?: CompileNgModuleMetadata[],
transitiveModule?: TransitiveCompileNgModuleMetadata
} = {}) {
this.type = type;
this.directives = _normalizeArray(directives);
this.pipes = _normalizeArray(pipes);
this.declaredDirectives = _normalizeArray(declaredDirectives);
this.exportedDirectives = _normalizeArray(exportedDirectives);
this.declaredPipes = _normalizeArray(declaredPipes);
this.exportedPipes = _normalizeArray(exportedPipes);
this.providers = _normalizeArray(providers);
this.precompile = _normalizeArray(precompile);
this.modules = _normalizeArray(modules);
this.importedModules = _normalizeArray(importedModules);
this.exportedModules = _normalizeArray(exportedModules);
this.transitiveModule = transitiveModule;
}
get identifier(): CompileIdentifierMetadata { return this.type; }
get runtimeCacheKey(): any { return this.type.runtimeCacheKey; }
static fromJson(data: {[key: string]: any}): CompileAppModuleMetadata {
return new CompileAppModuleMetadata({
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
providers: _arrayFromJson(data['providers'], metadataFromJson),
directives: _arrayFromJson(data['directives'], metadataFromJson),
pipes: _arrayFromJson(data['pipes'], metadataFromJson),
precompile: _arrayFromJson(data['precompile'], CompileTypeMetadata.fromJson),
modules: _arrayFromJson(data['modules'], CompileTypeMetadata.fromJson)
});
}
get assetCacheKey(): any { return this.type.assetCacheKey; }
toJson(): {[key: string]: any} {
return {
'class': 'AppModule',
'type': isPresent(this.type) ? this.type.toJson() : this.type,
'providers': _arrayToJson(this.providers),
'directives': _arrayToJson(this.directives),
'pipes': _arrayToJson(this.pipes),
'precompile': _arrayToJson(this.precompile),
'modules': _arrayToJson(this.modules)
};
equalsTo(other: CompileMetadataWithIdentifier): boolean {
return this.type.equalsTo(other.identifier);
}
}
var _COMPILE_METADATA_FROM_JSON = {
'AppModule': CompileAppModuleMetadata.fromJson,
'Directive': CompileDirectiveMetadata.fromJson,
'Pipe': CompilePipeMetadata.fromJson,
'Type': CompileTypeMetadata.fromJson,
'Provider': CompileProviderMetadata.fromJson,
'Identifier': CompileIdentifierMetadata.fromJson,
'Factory': CompileFactoryMetadata.fromJson,
'AnimationEntryMetadata': CompileAnimationEntryMetadata.fromJson,
'AnimationStateDeclarationMetadata': CompileAnimationStateDeclarationMetadata.fromJson,
'AnimationStateTransitionMetadata': CompileAnimationStateTransitionMetadata.fromJson,
'AnimationSequenceMetadata': CompileAnimationSequenceMetadata.fromJson,
'AnimationGroupMetadata': CompileAnimationGroupMetadata.fromJson,
'AnimationAnimateMetadata': CompileAnimationAnimateMetadata.fromJson,
'AnimationStyleMetadata': CompileAnimationStyleMetadata.fromJson,
'AnimationKeyframesSequenceMetadata': CompileAnimationKeyframesSequenceMetadata.fromJson
};
function _arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
return isBlank(obj) ? null : obj.map(o => _objFromJson(o, fn));
export class TransitiveCompileNgModuleMetadata {
directivesSet = new Set<Type>();
pipesSet = new Set<Type>();
constructor(
public modules: CompileNgModuleMetadata[], public providers: CompileProviderMetadata[],
public precompile: CompileTypeMetadata[], public directives: CompileDirectiveMetadata[],
public pipes: CompilePipeMetadata[]) {
directives.forEach(dir => this.directivesSet.add(dir.type.runtime));
pipes.forEach(pipe => this.pipesSet.add(pipe.type.runtime));
}
}
function _arrayToJson(obj: any[]): string|{[key: string]: any} {
return isBlank(obj) ? null : obj.map(_objToJson);
}
function _objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {
if (isArray(obj)) return _arrayFromJson(obj, fn);
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
return fn(obj);
}
function _objToJson(obj: any): string|{[key: string]: any} {
if (isArray(obj)) return _arrayToJson(obj);
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
return obj.toJson();
export function removeIdentifierDuplicates<T extends CompileMetadataWithIdentifier>(items: T[]):
T[] {
const map = new CompileIdentifierMap<T, T>();
items.forEach((item) => {
if (!map.get(item)) {
map.add(item, item);
}
});
return map.keys();
}
function _normalizeArray(obj: any[]): any[] {