refactor(compiler): remove unneeded fields from metadata

Removes `CompileIdentifierMetadata.name` / `.moduleUrl`,
as well as `CompileTypeMetadata.name / moduleUrl` and
`CompileFactoryMetadata.name / moduleUrl`.
This commit is contained in:
Tobias Bosch 2016-11-23 09:42:19 -08:00 committed by vsavkin
parent 2452cd14e0
commit 2f7492c986
47 changed files with 857 additions and 936 deletions

View File

@ -8,7 +8,7 @@
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {ANY_STATE, DEFAULT_STATE, EMPTY_STATE} from '../private_import_core'; import {ANY_STATE, DEFAULT_STATE, EMPTY_STATE} from '../private_import_core';
@ -69,8 +69,8 @@ class _AnimationBuilder implements AnimationAstVisitor {
stylesArr.push(o.literalMap(entries)); stylesArr.push(o.literalMap(entries));
}); });
return o.importExpr(resolveIdentifier(Identifiers.AnimationStyles)).instantiate([ return o.importExpr(createIdentifier(Identifiers.AnimationStyles)).instantiate([
o.importExpr(resolveIdentifier(Identifiers.collectAndResolveStyles)).callFn([ o.importExpr(createIdentifier(Identifiers.collectAndResolveStyles)).callFn([
_ANIMATION_COLLECTED_STYLES, o.literalArr(stylesArr) _ANIMATION_COLLECTED_STYLES, o.literalArr(stylesArr)
]) ])
]); ]);
@ -78,7 +78,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
visitAnimationKeyframe(ast: AnimationKeyframeAst, context: _AnimationBuilderContext): visitAnimationKeyframe(ast: AnimationKeyframeAst, context: _AnimationBuilderContext):
o.Expression { o.Expression {
return o.importExpr(resolveIdentifier(Identifiers.AnimationKeyframe)).instantiate([ return o.importExpr(createIdentifier(Identifiers.AnimationKeyframe)).instantiate([
o.literal(ast.offset), ast.styles.visit(this, context) o.literal(ast.offset), ast.styles.visit(this, context)
]); ]);
} }
@ -100,7 +100,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
const startingStylesExpr = ast.startingStyles.visit(this, context); const startingStylesExpr = ast.startingStyles.visit(this, context);
const keyframeExpressions = ast.keyframes.map(keyframe => keyframe.visit(this, context)); const keyframeExpressions = ast.keyframes.map(keyframe => keyframe.visit(this, context));
const keyframesExpr = const keyframesExpr =
o.importExpr(resolveIdentifier(Identifiers.balanceAnimationKeyframes)).callFn([ o.importExpr(createIdentifier(Identifiers.balanceAnimationKeyframes)).callFn([
_ANIMATION_COLLECTED_STYLES, _ANIMATION_END_STATE_STYLES_VAR, _ANIMATION_COLLECTED_STYLES, _ANIMATION_END_STATE_STYLES_VAR,
o.literalArr(keyframeExpressions) o.literalArr(keyframeExpressions)
]); ]);
@ -127,14 +127,14 @@ class _AnimationBuilder implements AnimationAstVisitor {
visitAnimationSequence(ast: AnimationSequenceAst, context: _AnimationBuilderContext): visitAnimationSequence(ast: AnimationSequenceAst, context: _AnimationBuilderContext):
o.Expression { o.Expression {
const playerExprs = ast.steps.map(step => step.visit(this, context)); const playerExprs = ast.steps.map(step => step.visit(this, context));
return o.importExpr(resolveIdentifier(Identifiers.AnimationSequencePlayer)).instantiate([ return o.importExpr(createIdentifier(Identifiers.AnimationSequencePlayer)).instantiate([
o.literalArr(playerExprs) o.literalArr(playerExprs)
]); ]);
} }
visitAnimationGroup(ast: AnimationGroupAst, context: _AnimationBuilderContext): o.Expression { visitAnimationGroup(ast: AnimationGroupAst, context: _AnimationBuilderContext): o.Expression {
const playerExprs = ast.steps.map(step => step.visit(this, context)); const playerExprs = ast.steps.map(step => step.visit(this, context));
return o.importExpr(resolveIdentifier(Identifiers.AnimationGroupPlayer)).instantiate([ return o.importExpr(createIdentifier(Identifiers.AnimationGroupPlayer)).instantiate([
o.literalArr(playerExprs) o.literalArr(playerExprs)
]); ]);
} }
@ -228,7 +228,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
_ANIMATION_END_STATE_STYLES_VAR.equals(o.NULL_EXPR), _ANIMATION_END_STATE_STYLES_VAR.equals(o.NULL_EXPR),
[_ANIMATION_END_STATE_STYLES_VAR.set(_ANIMATION_DEFAULT_STATE_VAR).toStmt()])); [_ANIMATION_END_STATE_STYLES_VAR.set(_ANIMATION_DEFAULT_STATE_VAR).toStmt()]));
const RENDER_STYLES_FN = o.importExpr(resolveIdentifier(Identifiers.renderStyles)); const RENDER_STYLES_FN = o.importExpr(createIdentifier(Identifiers.renderStyles));
ast.stateTransitions.forEach(transAst => statements.push(transAst.visit(this, context))); ast.stateTransitions.forEach(transAst => statements.push(transAst.visit(this, context)));
@ -237,7 +237,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
statements.push(new o.IfStmt( statements.push(new o.IfStmt(
_ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR), _ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR),
[_ANIMATION_PLAYER_VAR [_ANIMATION_PLAYER_VAR
.set(o.importExpr(resolveIdentifier(Identifiers.NoOpAnimationPlayer)).instantiate([])) .set(o.importExpr(createIdentifier(Identifiers.NoOpAnimationPlayer)).instantiate([]))
.toStmt()])); .toStmt()]));
// once complete we want to apply the styles on the element // once complete we want to apply the styles on the element
@ -255,17 +255,18 @@ class _AnimationBuilder implements AnimationAstVisitor {
.callFn([ .callFn([
_ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR, _ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr( o.importExpr(
resolveIdentifier(Identifiers.prepareFinalAnimationStyles)) createIdentifier(Identifiers.prepareFinalAnimationStyles))
.callFn([ .callFn(
_ANIMATION_START_STATE_STYLES_VAR, [
_ANIMATION_END_STATE_STYLES_VAR _ANIMATION_START_STATE_STYLES_VAR,
]) _ANIMATION_END_STATE_STYLES_VAR
])
]) ])
.toStmt() .toStmt()
])]) ])])
.toStmt()); .toStmt());
statements.push(o.importExpr(resolveIdentifier(Identifiers.AnimationSequencePlayer)) statements.push(o.importExpr(createIdentifier(Identifiers.AnimationSequencePlayer))
.instantiate([_PREVIOUS_ANIMATION_PLAYERS]) .instantiate([_PREVIOUS_ANIMATION_PLAYERS])
.callMethod('destroy', []) .callMethod('destroy', [])
.toStmt()); .toStmt());
@ -276,7 +277,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
statements.push(RENDER_STYLES_FN statements.push(RENDER_STYLES_FN
.callFn([ .callFn([
_ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR, _ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(resolveIdentifier(Identifiers.clearStyles)) o.importExpr(createIdentifier(Identifiers.clearStyles))
.callFn([_ANIMATION_START_STATE_STYLES_VAR]) .callFn([_ANIMATION_START_STATE_STYLES_VAR])
]) ])
.toStmt()); .toStmt());
@ -291,7 +292,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
.toStmt()); .toStmt());
statements.push(new o.ReturnStatement( statements.push(new o.ReturnStatement(
o.importExpr(resolveIdentifier(Identifiers.AnimationTransition)).instantiate([ o.importExpr(createIdentifier(Identifiers.AnimationTransition)).instantiate([
_ANIMATION_PLAYER_VAR, _ANIMATION_CURRENT_STATE_VAR, _ANIMATION_NEXT_STATE_VAR, _ANIMATION_PLAYER_VAR, _ANIMATION_CURRENT_STATE_VAR, _ANIMATION_NEXT_STATE_VAR,
_ANIMATION_TIME_VAR _ANIMATION_TIME_VAR
]))); ])));
@ -300,12 +301,12 @@ class _AnimationBuilder implements AnimationAstVisitor {
[ [
new o.FnParam( new o.FnParam(
_ANIMATION_FACTORY_VIEW_VAR.name, _ANIMATION_FACTORY_VIEW_VAR.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(_ANIMATION_FACTORY_ELEMENT_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(_ANIMATION_FACTORY_ELEMENT_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(_ANIMATION_CURRENT_STATE_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(_ANIMATION_CURRENT_STATE_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(_ANIMATION_NEXT_STATE_VAR.name, o.DYNAMIC_TYPE) new o.FnParam(_ANIMATION_NEXT_STATE_VAR.name, o.DYNAMIC_TYPE)
], ],
statements, o.importType(resolveIdentifier(Identifiers.AnimationTransition))); statements, o.importType(createIdentifier(Identifiers.AnimationTransition)));
} }
build(ast: AnimationAst): AnimationEntryCompileResult { build(ast: AnimationAst): AnimationEntryCompileResult {

View File

@ -8,7 +8,7 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {CompileAnimationAnimateMetadata, CompileAnimationEntryMetadata, CompileAnimationGroupMetadata, CompileAnimationKeyframesSequenceMetadata, CompileAnimationMetadata, CompileAnimationSequenceMetadata, CompileAnimationStateDeclarationMetadata, CompileAnimationStateTransitionMetadata, CompileAnimationStyleMetadata, CompileAnimationWithStepsMetadata, CompileDirectiveMetadata} from '../compile_metadata'; import {CompileAnimationAnimateMetadata, CompileAnimationEntryMetadata, CompileAnimationGroupMetadata, CompileAnimationKeyframesSequenceMetadata, CompileAnimationMetadata, CompileAnimationSequenceMetadata, CompileAnimationStateDeclarationMetadata, CompileAnimationStateTransitionMetadata, CompileAnimationStyleMetadata, CompileAnimationWithStepsMetadata, CompileDirectiveMetadata, identifierName} from '../compile_metadata';
import {StringMapWrapper} from '../facade/collection'; import {StringMapWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang'; import {isBlank, isPresent} from '../facade/lang';
import {ParseError} from '../parse_util'; import {ParseError} from '../parse_util';
@ -41,7 +41,7 @@ export class AnimationParser {
parseComponent(component: CompileDirectiveMetadata): AnimationEntryAst[] { parseComponent(component: CompileDirectiveMetadata): AnimationEntryAst[] {
const errors: string[] = []; const errors: string[] = [];
const componentName = component.type.name; const componentName = identifierName(component.type);
const animationTriggerNames = new Set<string>(); const animationTriggerNames = new Set<string>();
const asts = component.template.animations.map(entry => { const asts = component.template.animations.map(entry => {
const result = this.parseEntry(entry); const result = this.parseEntry(entry);

View File

@ -10,11 +10,11 @@ import {SchemaMetadata} from '@angular/core';
import {AnimationCompiler} from '../animation/animation_compiler'; import {AnimationCompiler} from '../animation/animation_compiler';
import {AnimationParser} from '../animation/animation_parser'; import {AnimationParser} from '../animation/animation_parser';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, CompileProviderMetadata, createHostComponentMeta} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, CompileProviderMetadata, createHostComponentMeta, identifierModuleUrl, identifierName} from '../compile_metadata';
import {DirectiveNormalizer} from '../directive_normalizer'; import {DirectiveNormalizer} from '../directive_normalizer';
import {DirectiveWrapperCompileResult, DirectiveWrapperCompiler} from '../directive_wrapper_compiler'; import {DirectiveWrapperCompileResult, DirectiveWrapperCompiler} from '../directive_wrapper_compiler';
import {ListWrapper} from '../facade/collection'; import {ListWrapper} from '../facade/collection';
import {Identifiers, resolveIdentifier, resolveIdentifierToken} from '../identifiers'; import {Identifiers, createIdentifier, createIdentifierToken} from '../identifiers';
import {CompileMetadataResolver} from '../metadata_resolver'; import {CompileMetadataResolver} from '../metadata_resolver';
import {NgModuleCompiler} from '../ng_module_compiler'; import {NgModuleCompiler} from '../ng_module_compiler';
import {OutputEmitter} from '../output/abstract_emitter'; import {OutputEmitter} from '../output/abstract_emitter';
@ -82,7 +82,7 @@ export class AotCompiler {
const ngModule = ngModuleByPipeOrDirective.get(dirType); const ngModule = ngModuleByPipeOrDirective.get(dirType);
if (!ngModule) { if (!ngModule) {
throw new Error( throw new Error(
`Internal Error: cannot determine the module for component ${compMeta.type.name}!`); `Internal Error: cannot determine the module for component ${identifierName(compMeta.type)}!`);
} }
_assertComponent(compMeta); _assertComponent(compMeta);
@ -114,14 +114,14 @@ export class AotCompiler {
if (this._localeId) { if (this._localeId) {
providers.push(new CompileProviderMetadata({ providers.push(new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.LOCALE_ID), token: createIdentifierToken(Identifiers.LOCALE_ID),
useValue: this._localeId, useValue: this._localeId,
})); }));
} }
if (this._translationFormat) { if (this._translationFormat) {
providers.push(new CompileProviderMetadata({ providers.push(new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.TRANSLATIONS_FORMAT), token: createIdentifierToken(Identifiers.TRANSLATIONS_FORMAT),
useValue: this._translationFormat useValue: this._translationFormat
})); }));
} }
@ -129,8 +129,8 @@ export class AotCompiler {
const appCompileResult = this._ngModuleCompiler.compile(ngModule, providers); const appCompileResult = this._ngModuleCompiler.compile(ngModule, providers);
appCompileResult.dependencies.forEach((dep) => { appCompileResult.dependencies.forEach((dep) => {
dep.placeholder.name = _componentFactoryName(dep.comp); dep.placeholder.reference = this._staticReflector.getStaticSymbol(
dep.placeholder.moduleUrl = _ngfactoryModuleUrl(dep.comp.moduleUrl); _ngfactoryModuleUrl(identifierModuleUrl(dep.comp)), _componentFactoryName(dep.comp));
}); });
targetStatements.push(...appCompileResult.statements); targetStatements.push(...appCompileResult.statements);
@ -149,14 +149,17 @@ export class AotCompiler {
private _compileComponentFactory( private _compileComponentFactory(
compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata, fileSuffix: string, compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata, fileSuffix: string,
targetStatements: o.Statement[]): string { targetStatements: o.Statement[]): string {
const hostMeta = createHostComponentMeta(compMeta); const hostMeta = createHostComponentMeta(
this._staticReflector.getStaticSymbol(
identifierModuleUrl(compMeta.type), `${identifierName(compMeta.type)}_Host`),
compMeta);
const hostViewFactoryVar = this._compileComponent( const hostViewFactoryVar = this._compileComponent(
hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements); hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements);
const compFactoryVar = _componentFactoryName(compMeta.type); const compFactoryVar = _componentFactoryName(compMeta.type);
targetStatements.push( targetStatements.push(
o.variable(compFactoryVar) o.variable(compFactoryVar)
.set(o.importExpr(resolveIdentifier(Identifiers.ComponentFactory), [o.importType( .set(o.importExpr(
compMeta.type)]) createIdentifier(Identifiers.ComponentFactory), [o.importType(compMeta.type)])
.instantiate( .instantiate(
[ [
o.literal(compMeta.selector), o.literal(compMeta.selector),
@ -164,7 +167,7 @@ export class AotCompiler {
o.importExpr(compMeta.type), o.importExpr(compMeta.type),
], ],
o.importType( o.importType(
resolveIdentifier(Identifiers.ComponentFactory), createIdentifier(Identifiers.ComponentFactory),
[o.importType(compMeta.type)], [o.TypeModifier.Const]))) [o.importType(compMeta.type)], [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final])); .toDeclStmt(null, [o.StmtModifier.Final]));
return compFactoryVar; return compFactoryVar;
@ -182,23 +185,24 @@ export class AotCompiler {
const parsedTemplate = this._templateParser.parse( const parsedTemplate = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, ngModule.schemas, compMeta, compMeta.template.template, directives, pipes, ngModule.schemas,
compMeta.type.name); identifierName(compMeta.type));
const stylesExpr = componentStyles ? o.variable(componentStyles.stylesVar) : o.literalArr([]); const stylesExpr = componentStyles ? o.variable(componentStyles.stylesVar) : o.literalArr([]);
const compiledAnimations = const compiledAnimations =
this._animationCompiler.compile(compMeta.type.name, parsedAnimations); this._animationCompiler.compile(identifierName(compMeta.type), parsedAnimations);
const viewResult = this._viewCompiler.compileComponent( const viewResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, stylesExpr, pipes, compiledAnimations); compMeta, parsedTemplate, stylesExpr, pipes, compiledAnimations);
if (componentStyles) { if (componentStyles) {
targetStatements.push(..._resolveStyleStatements(componentStyles, fileSuffix)); targetStatements.push(
..._resolveStyleStatements(this._staticReflector, componentStyles, fileSuffix));
} }
compiledAnimations.forEach(entry => targetStatements.push(...entry.statements)); compiledAnimations.forEach(entry => targetStatements.push(...entry.statements));
targetStatements.push(..._resolveViewStatements(viewResult)); targetStatements.push(..._resolveViewStatements(this._staticReflector, viewResult));
return viewResult.viewClassVar; return viewResult.viewClassVar;
} }
private _codgenStyles( private _codgenStyles(
fileUrl: string, stylesCompileResult: CompiledStylesheet, fileSuffix: string): SourceModule { fileUrl: string, stylesCompileResult: CompiledStylesheet, fileSuffix: string): SourceModule {
_resolveStyleStatements(stylesCompileResult, fileSuffix); _resolveStyleStatements(this._staticReflector, stylesCompileResult, fileSuffix);
return this._codegenSourceModule( return this._codegenSourceModule(
fileUrl, _stylesModuleUrl( fileUrl, _stylesModuleUrl(
stylesCompileResult.meta.moduleUrl, stylesCompileResult.isShimmed, fileSuffix), stylesCompileResult.meta.moduleUrl, stylesCompileResult.isShimmed, fileSuffix),
@ -214,18 +218,21 @@ export class AotCompiler {
} }
} }
function _resolveViewStatements(compileResult: ViewCompileResult): o.Statement[] { function _resolveViewStatements(
reflector: StaticReflector, compileResult: ViewCompileResult): o.Statement[] {
compileResult.dependencies.forEach((dep) => { compileResult.dependencies.forEach((dep) => {
if (dep instanceof ViewClassDependency) { if (dep instanceof ViewClassDependency) {
const vfd = <ViewClassDependency>dep; const vfd = <ViewClassDependency>dep;
vfd.placeholder.moduleUrl = _ngfactoryModuleUrl(vfd.comp.moduleUrl); vfd.placeholder.reference =
reflector.getStaticSymbol(_ngfactoryModuleUrl(identifierModuleUrl(vfd.comp)), dep.name);
} else if (dep instanceof ComponentFactoryDependency) { } else if (dep instanceof ComponentFactoryDependency) {
const cfd = <ComponentFactoryDependency>dep; const cfd = <ComponentFactoryDependency>dep;
cfd.placeholder.name = _componentFactoryName(cfd.comp); cfd.placeholder.reference = reflector.getStaticSymbol(
cfd.placeholder.moduleUrl = _ngfactoryModuleUrl(cfd.comp.moduleUrl); _ngfactoryModuleUrl(identifierModuleUrl(cfd.comp)), _componentFactoryName(cfd.comp));
} else if (dep instanceof DirectiveWrapperDependency) { } else if (dep instanceof DirectiveWrapperDependency) {
const dwd = <DirectiveWrapperDependency>dep; const dwd = <DirectiveWrapperDependency>dep;
dwd.placeholder.moduleUrl = _ngfactoryModuleUrl(dwd.dir.moduleUrl); dwd.placeholder.reference =
reflector.getStaticSymbol(_ngfactoryModuleUrl(identifierModuleUrl(dwd.dir)), dwd.name);
} }
}); });
return compileResult.statements; return compileResult.statements;
@ -233,9 +240,11 @@ function _resolveViewStatements(compileResult: ViewCompileResult): o.Statement[]
function _resolveStyleStatements( function _resolveStyleStatements(
compileResult: CompiledStylesheet, fileSuffix: string): o.Statement[] { reflector: StaticReflector, compileResult: CompiledStylesheet,
fileSuffix: string): o.Statement[] {
compileResult.dependencies.forEach((dep) => { compileResult.dependencies.forEach((dep) => {
dep.valuePlaceholder.moduleUrl = _stylesModuleUrl(dep.moduleUrl, dep.isShimmed, fileSuffix); dep.valuePlaceholder.reference = reflector.getStaticSymbol(
_stylesModuleUrl(dep.moduleUrl, dep.isShimmed, fileSuffix), dep.name);
}); });
return compileResult.statements; return compileResult.statements;
} }
@ -246,7 +255,7 @@ function _ngfactoryModuleUrl(dirUrl: string): string {
} }
function _componentFactoryName(comp: CompileIdentifierMetadata): string { function _componentFactoryName(comp: CompileIdentifierMetadata): string {
return `${comp.name}NgFactory`; return `${identifierName(comp)}NgFactory`;
} }
function _stylesModuleUrl(stylesheetUrl: string, shim: boolean, suffix: string): string { function _stylesModuleUrl(stylesheetUrl: string, shim: boolean, suffix: string): string {
@ -255,7 +264,8 @@ function _stylesModuleUrl(stylesheetUrl: string, shim: boolean, suffix: string):
function _assertComponent(meta: CompileDirectiveMetadata) { function _assertComponent(meta: CompileDirectiveMetadata) {
if (!meta.isComponent) { if (!meta.isComponent) {
throw new Error(`Could not compile '${meta.type.name}' because it is not a component.`); throw new Error(
`Could not compile '${identifierName(meta.type)}' because it is not a component.`);
} }
} }

View File

@ -8,11 +8,12 @@
import {ChangeDetectionStrategy, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core'; import {ChangeDetectionStrategy, SchemaMetadata, Type, ViewEncapsulation} from '@angular/core';
import {StaticSymbol, isStaticSymbol} from './aot/static_symbol';
import {ListWrapper} from './facade/collection'; import {ListWrapper} from './facade/collection';
import {isPresent} from './facade/lang'; import {isPresent, stringify} from './facade/lang';
import {LifecycleHooks} from './private_import_core'; import {LifecycleHooks, reflector} from './private_import_core';
import {CssSelector} from './selector'; import {CssSelector} from './selector';
import {sanitizeIdentifier, splitAtColon} from './util'; import {splitAtColon} from './util';
function unimplemented(): any { function unimplemented(): any {
throw new Error('unimplemented'); throw new Error('unimplemented');
@ -24,10 +25,6 @@ function unimplemented(): any {
// group 3: "@trigger" from "@trigger" // group 3: "@trigger" from "@trigger"
const HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/; const HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/;
export abstract class CompileMetadataWithIdentifier {
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
}
export class CompileAnimationEntryMetadata { export class CompileAnimationEntryMetadata {
constructor( constructor(
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {} public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
@ -78,24 +75,47 @@ export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMeta
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); } constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
} }
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
reference: any;
name: string;
prefix: string;
moduleUrl: string;
value: any;
constructor( function _sanitizeIdentifier(name: string): string {
{reference, name, moduleUrl, prefix, value}: return name.replace(/\W/g, '_');
{reference?: any, name?: string, moduleUrl?: string, prefix?: string, value?: any} = {}) { }
this.reference = reference;
this.name = name; let _anonymousTypeIndex = 0;
this.prefix = prefix;
this.moduleUrl = moduleUrl; export function identifierName(compileIdentifier: CompileIdentifierMetadata): string {
this.value = value; if (!compileIdentifier || !compileIdentifier.reference) {
return null;
} }
const ref = compileIdentifier.reference;
if (isStaticSymbol(ref)) {
return ref.name;
}
if (ref['__anonymousType']) {
return ref['__anonymousType'];
}
let identifier = stringify(ref);
if (identifier.indexOf('(') >= 0) {
// case: anonymous functions!
identifier = `anonymous_${_anonymousTypeIndex++}`;
ref['__anonymousType'] = identifier;
} else {
identifier = _sanitizeIdentifier(identifier);
}
return identifier;
}
get identifier(): CompileIdentifierMetadata { return this; } export function identifierModuleUrl(compileIdentifier: CompileIdentifierMetadata): string {
const ref = compileIdentifier.reference;
if (isStaticSymbol(ref)) {
return ref.filePath;
}
return reflector.importUri(ref);
}
export class CompileIdentifierMetadata {
reference: any;
constructor({reference}: {reference?: any} = {}) { this.reference = reference; }
} }
/** /**
@ -171,42 +191,32 @@ export class CompileProviderMetadata {
export class CompileFactoryMetadata extends CompileIdentifierMetadata { export class CompileFactoryMetadata extends CompileIdentifierMetadata {
diDeps: CompileDiDependencyMetadata[]; diDeps: CompileDiDependencyMetadata[];
constructor({reference, name, moduleUrl, prefix, diDeps, value}: { constructor({reference, diDeps}: {reference?: Function, diDeps?: CompileDiDependencyMetadata[]}) {
reference?: Function, super({reference: reference});
name?: string,
prefix?: string,
moduleUrl?: string,
value?: boolean,
diDeps?: CompileDiDependencyMetadata[]
}) {
super({reference: reference, name: name, prefix: prefix, moduleUrl: moduleUrl, value: value});
this.diDeps = _normalizeArray(diDeps); this.diDeps = _normalizeArray(diDeps);
} }
} }
export class CompileTokenMetadata implements CompileMetadataWithIdentifier { export function tokenName(token: CompileTokenMetadata) {
return isPresent(token.value) ? _sanitizeIdentifier(token.value) :
identifierName(token.identifier);
}
export function tokenReference(token: CompileTokenMetadata) {
if (isPresent(token.identifier)) {
return token.identifier.reference;
} else {
return token.value;
}
}
export class CompileTokenMetadata {
value: any; value: any;
identifier: CompileIdentifierMetadata; identifier: CompileIdentifierMetadata;
identifierIsInstance: boolean;
constructor( constructor({value, identifier}: {value?: any, identifier?: CompileIdentifierMetadata}) {
{value, identifier, identifierIsInstance}:
{value?: any, identifier?: CompileIdentifierMetadata, identifierIsInstance?: boolean}) {
this.value = value; this.value = value;
this.identifier = identifier; this.identifier = identifier;
this.identifierIsInstance = !!identifierIsInstance;
}
get reference(): any {
if (isPresent(this.identifier)) {
return this.identifier.reference;
} else {
return this.value;
}
}
get name(): string {
return isPresent(this.value) ? sanitizeIdentifier(this.value) : this.identifier.name;
} }
} }
@ -214,22 +224,15 @@ export class CompileTokenMetadata implements CompileMetadataWithIdentifier {
* Metadata regarding compilation of a type. * Metadata regarding compilation of a type.
*/ */
export class CompileTypeMetadata extends CompileIdentifierMetadata { export class CompileTypeMetadata extends CompileIdentifierMetadata {
isHost: boolean;
diDeps: CompileDiDependencyMetadata[]; diDeps: CompileDiDependencyMetadata[];
lifecycleHooks: LifecycleHooks[]; lifecycleHooks: LifecycleHooks[];
constructor({reference, name, moduleUrl, prefix, isHost, value, diDeps, lifecycleHooks}: { constructor({reference, diDeps, lifecycleHooks}: {
reference?: Type<any>, reference?: Type<any>| StaticSymbol,
name?: string,
moduleUrl?: string,
prefix?: string,
isHost?: boolean,
value?: any,
diDeps?: CompileDiDependencyMetadata[], diDeps?: CompileDiDependencyMetadata[],
lifecycleHooks?: LifecycleHooks[]; lifecycleHooks?: LifecycleHooks[];
} = {}) { } = {}) {
super({reference: reference, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value}); super({reference: reference});
this.isHost = !!isHost;
this.diDeps = _normalizeArray(diDeps); this.diDeps = _normalizeArray(diDeps);
this.lifecycleHooks = _normalizeArray(lifecycleHooks); this.lifecycleHooks = _normalizeArray(lifecycleHooks);
} }
@ -355,10 +358,11 @@ export interface CompileDirectiveSummary extends CompileSummary {
/** /**
* Metadata regarding compilation of a directive. * Metadata regarding compilation of a directive.
*/ */
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier { export class CompileDirectiveMetadata {
static create( static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host, providers, {isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
viewProviders, queries, viewQueries, entryComponents, template}: { providers, viewProviders, queries, viewQueries, entryComponents, template}: {
isHost?: boolean,
type?: CompileTypeMetadata, type?: CompileTypeMetadata,
isComponent?: boolean, isComponent?: boolean,
selector?: string, selector?: string,
@ -412,6 +416,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
} }
return new CompileDirectiveMetadata({ return new CompileDirectiveMetadata({
isHost,
type, type,
isComponent: !!isComponent, selector, exportAs, changeDetection, isComponent: !!isComponent, selector, exportAs, changeDetection,
inputs: inputsMap, inputs: inputsMap,
@ -427,6 +432,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
template, template,
}); });
} }
isHost: boolean;
type: CompileTypeMetadata; type: CompileTypeMetadata;
isComponent: boolean; isComponent: boolean;
selector: string; selector: string;
@ -446,9 +452,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
template: CompileTemplateMetadata; template: CompileTemplateMetadata;
constructor( constructor(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners, {isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs,
hostProperties, hostAttributes, providers, viewProviders, queries, viewQueries, hostListeners, hostProperties, hostAttributes, providers, viewProviders, queries,
entryComponents, template}: { viewQueries, entryComponents, template}: {
isHost?: boolean,
type?: CompileTypeMetadata, type?: CompileTypeMetadata,
isComponent?: boolean, isComponent?: boolean,
selector?: string, selector?: string,
@ -468,6 +475,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
entryComponents?: CompileIdentifierMetadata[], entryComponents?: CompileIdentifierMetadata[],
template?: CompileTemplateMetadata, template?: CompileTemplateMetadata,
} = {}) { } = {}) {
this.isHost = !!isHost;
this.type = type; this.type = type;
this.isComponent = isComponent; this.isComponent = isComponent;
this.selector = selector; this.selector = selector;
@ -487,8 +495,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
this.template = template; this.template = template;
} }
get identifier(): CompileIdentifierMetadata { return this.type; }
toSummary(): CompileDirectiveSummary { toSummary(): CompileDirectiveSummary {
return { return {
isSummary: true, isSummary: true,
@ -514,16 +520,12 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
/** /**
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector. * Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
*/ */
export function createHostComponentMeta(compMeta: CompileDirectiveMetadata): export function createHostComponentMeta(
CompileDirectiveMetadata { typeReference: any, compMeta: CompileDirectiveMetadata): CompileDirectiveMetadata {
const template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate(); const template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
return CompileDirectiveMetadata.create({ return CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({ isHost: true,
reference: Object, type: new CompileTypeMetadata({reference: typeReference}),
name: `${compMeta.type.name}_Host`,
moduleUrl: compMeta.type.moduleUrl,
isHost: true
}),
template: new CompileTemplateMetadata({ template: new CompileTemplateMetadata({
encapsulation: ViewEncapsulation.None, encapsulation: ViewEncapsulation.None,
template: template, template: template,
@ -553,7 +555,7 @@ export interface CompilePipeSummary extends CompileSummary {
pure: boolean; pure: boolean;
} }
export class CompilePipeMetadata implements CompileMetadataWithIdentifier { export class CompilePipeMetadata {
type: CompileTypeMetadata; type: CompileTypeMetadata;
name: string; name: string;
pure: boolean; pure: boolean;
@ -567,7 +569,6 @@ export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
this.name = name; this.name = name;
this.pure = !!pure; this.pure = !!pure;
} }
get identifier(): CompileIdentifierMetadata { return this.type; }
toSummary(): CompilePipeSummary { toSummary(): CompilePipeSummary {
return {isSummary: true, type: this.type, name: this.name, pure: this.pure}; return {isSummary: true, type: this.type, name: this.name, pure: this.pure};
@ -598,7 +599,7 @@ export type CompileNgModuleSummary =
/** /**
* Metadata regarding compilation of a module. * Metadata regarding compilation of a module.
*/ */
export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier { export class CompileNgModuleMetadata {
type: CompileTypeMetadata; type: CompileTypeMetadata;
declaredDirectives: CompileIdentifierMetadata[]; declaredDirectives: CompileIdentifierMetadata[];
exportedDirectives: CompileIdentifierMetadata[]; exportedDirectives: CompileIdentifierMetadata[];
@ -649,8 +650,6 @@ export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
this.transitiveModule = transitiveModule; this.transitiveModule = transitiveModule;
} }
get identifier(): CompileIdentifierMetadata { return this.type; }
toSummary(): CompileNgModuleSummary { toSummary(): CompileNgModuleSummary {
return { return {
isSummary: true, isSummary: true,
@ -701,19 +700,6 @@ export class TransitiveCompileNgModuleMetadata {
} }
} }
export function removeIdentifierDuplicates<T extends CompileMetadataWithIdentifier>(items: T[]):
T[] {
const map = new Map<any, T>();
items.forEach((item) => {
if (!map.get(item.identifier.reference)) {
map.set(item.identifier.reference, item);
}
});
return Array.from(map.values());
}
function _normalizeArray(obj: any[]): any[] { function _normalizeArray(obj: any[]): any[] {
return obj || []; return obj || [];
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import {ClassBuilder} from '../output/class_builder'; import {ClassBuilder} from '../output/class_builder';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
@ -22,7 +22,7 @@ export function createCheckBindingField(builder: ClassBuilder): CheckBindingFiel
// private is fine here as no child view will reference the cached value... // private is fine here as no child view will reference the cached value...
builder.fields.push(new o.ClassField(fieldExpr.name, null, [o.StmtModifier.Private])); builder.fields.push(new o.ClassField(fieldExpr.name, null, [o.StmtModifier.Private]));
builder.ctorStmts.push(o.THIS_EXPR.prop(fieldExpr.name) builder.ctorStmts.push(o.THIS_EXPR.prop(fieldExpr.name)
.set(o.importExpr(resolveIdentifier(Identifiers.UNINITIALIZED))) .set(o.importExpr(createIdentifier(Identifiers.UNINITIALIZED)))
.toStmt()); .toStmt());
return new CheckBindingField(fieldExpr, bindingId); return new CheckBindingField(fieldExpr, bindingId);
} }
@ -30,7 +30,7 @@ export function createCheckBindingField(builder: ClassBuilder): CheckBindingFiel
export function createCheckBindingStmt( export function createCheckBindingStmt(
evalResult: ConvertPropertyBindingResult, fieldExpr: o.ReadPropExpr, evalResult: ConvertPropertyBindingResult, fieldExpr: o.ReadPropExpr,
throwOnChangeVar: o.Expression, actions: o.Statement[]): o.Statement[] { throwOnChangeVar: o.Expression, actions: o.Statement[]): o.Statement[] {
let condition: o.Expression = o.importExpr(resolveIdentifier(Identifiers.checkBinding)).callFn([ let condition: o.Expression = o.importExpr(createIdentifier(Identifiers.checkBinding)).callFn([
throwOnChangeVar, fieldExpr, evalResult.currValExpr throwOnChangeVar, fieldExpr, evalResult.currValExpr
]); ]);
if (evalResult.forceUpdate) { if (evalResult.forceUpdate) {

View File

@ -9,7 +9,7 @@
import * as cdAst from '../expression_parser/ast'; import * as cdAst from '../expression_parser/ast';
import {isBlank, isPresent} from '../facade/lang'; import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import {ClassBuilder} from '../output/class_builder'; import {ClassBuilder} from '../output/class_builder';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
@ -116,7 +116,7 @@ export function createSharedBindingVariablesIfNeeded(stmts: o.Statement[]): o.St
if (readVars.has(VAL_UNWRAPPER_VAR.name)) { if (readVars.has(VAL_UNWRAPPER_VAR.name)) {
unwrapperStmts.push( unwrapperStmts.push(
VAL_UNWRAPPER_VAR VAL_UNWRAPPER_VAR
.set(o.importExpr(resolveIdentifier(Identifiers.ValueUnwrapper)).instantiate([])) .set(o.importExpr(createIdentifier(Identifiers.ValueUnwrapper)).instantiate([]))
.toDeclStmt(null, [o.StmtModifier.Final])); .toDeclStmt(null, [o.StmtModifier.Final]));
} }
return unwrapperStmts; return unwrapperStmts;
@ -277,8 +277,8 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
args.push(o.literal(ast.strings[ast.strings.length - 1])); args.push(o.literal(ast.strings[ast.strings.length - 1]));
return ast.expressions.length <= 9 ? return ast.expressions.length <= 9 ?
o.importExpr(resolveIdentifier(Identifiers.inlineInterpolate)).callFn(args) : o.importExpr(createIdentifier(Identifiers.inlineInterpolate)).callFn(args) :
o.importExpr(resolveIdentifier(Identifiers.interpolate)).callFn([ o.importExpr(createIdentifier(Identifiers.interpolate)).callFn([
args[0], o.literalArr(args.slice(1)) args[0], o.literalArr(args.slice(1))
]); ]);
} }
@ -578,7 +578,7 @@ function flattenStatements(arg: any, output: o.Statement[]) {
function createCachedLiteralArray(builder: ClassBuilder, values: o.Expression[]): o.Expression { function createCachedLiteralArray(builder: ClassBuilder, values: o.Expression[]): o.Expression {
if (values.length === 0) { if (values.length === 0) {
return o.importExpr(resolveIdentifier(Identifiers.EMPTY_ARRAY)); return o.importExpr(createIdentifier(Identifiers.EMPTY_ARRAY));
} }
const proxyExpr = o.THIS_EXPR.prop(`_arr_${builder.fields.length}`); const proxyExpr = o.THIS_EXPR.prop(`_arr_${builder.fields.length}`);
const proxyParams: o.FnParam[] = []; const proxyParams: o.FnParam[] = [];
@ -599,7 +599,7 @@ function createCachedLiteralArray(builder: ClassBuilder, values: o.Expression[])
function createCachedLiteralMap( function createCachedLiteralMap(
builder: ClassBuilder, entries: [string, o.Expression][]): o.Expression { builder: ClassBuilder, entries: [string, o.Expression][]): o.Expression {
if (entries.length === 0) { if (entries.length === 0) {
return o.importExpr(resolveIdentifier(Identifiers.EMPTY_MAP)); return o.importExpr(createIdentifier(Identifiers.EMPTY_MAP));
} }
const proxyExpr = o.THIS_EXPR.prop(`_map_${builder.fields.length}`); const proxyExpr = o.THIS_EXPR.prop(`_map_${builder.fields.length}`);
const proxyParams: o.FnParam[] = []; const proxyParams: o.FnParam[] = [];

View File

@ -8,15 +8,12 @@
import {CompileTokenMetadata} from '../compile_metadata'; import {CompileTokenMetadata} from '../compile_metadata';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {IdentifierSpec, Identifiers, resolveEnumIdentifier, resolveIdentifier} from '../identifiers'; import {IdentifierSpec, Identifiers, createEnumIdentifier, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
export function createDiTokenExpression(token: CompileTokenMetadata): o.Expression { export function createDiTokenExpression(token: CompileTokenMetadata): o.Expression {
if (isPresent(token.value)) { if (isPresent(token.value)) {
return o.literal(token.value); return o.literal(token.value);
} else if (token.identifierIsInstance) {
return o.importExpr(token.identifier)
.instantiate([], o.importType(token.identifier, [], [o.TypeModifier.Const]));
} else { } else {
return o.importExpr(token.identifier); return o.importExpr(token.identifier);
} }
@ -24,13 +21,13 @@ export function createDiTokenExpression(token: CompileTokenMetadata): o.Expressi
export function createInlineArray(values: o.Expression[]): o.Expression { export function createInlineArray(values: o.Expression[]): o.Expression {
if (values.length === 0) { if (values.length === 0) {
return o.importExpr(resolveIdentifier(Identifiers.EMPTY_INLINE_ARRAY)); return o.importExpr(createIdentifier(Identifiers.EMPTY_INLINE_ARRAY));
} }
const log2 = Math.log(values.length) / Math.log(2); const log2 = Math.log(values.length) / Math.log(2);
const index = Math.ceil(log2); const index = Math.ceil(log2);
const identifierSpec = index < Identifiers.inlineArrays.length ? Identifiers.inlineArrays[index] : const identifierSpec = index < Identifiers.inlineArrays.length ? Identifiers.inlineArrays[index] :
Identifiers.InlineArrayDynamic; Identifiers.InlineArrayDynamic;
const identifier = resolveIdentifier(identifierSpec); const identifier = createIdentifier(identifierSpec);
return o.importExpr(identifier).instantiate([ return o.importExpr(identifier).instantiate([
<o.Expression>o.literal(values.length) <o.Expression>o.literal(values.length)
].concat(values)); ].concat(values));
@ -46,7 +43,7 @@ export function createPureProxy(
throw new Error(`Unsupported number of argument for pure functions: ${argCount}`); throw new Error(`Unsupported number of argument for pure functions: ${argCount}`);
} }
builder.ctorStmts.push(o.THIS_EXPR.prop(pureProxyProp.name) builder.ctorStmts.push(o.THIS_EXPR.prop(pureProxyProp.name)
.set(o.importExpr(resolveIdentifier(pureProxyId)).callFn([fn])) .set(o.importExpr(createIdentifier(pureProxyId)).callFn([fn]))
.toStmt()); .toStmt());
} }
@ -56,5 +53,5 @@ export function createEnumExpression(enumType: IdentifierSpec, enumValue: any):
if (!enumName) { if (!enumName) {
throw new Error(`Unknown enum value ${enumValue} in ${enumType.name}`); throw new Error(`Unknown enum value ${enumValue} in ${enumType.name}`);
} }
return o.importExpr(resolveEnumIdentifier(resolveIdentifier(enumType), enumName)); return o.importExpr(createEnumIdentifier(enumType, enumName));
} }

View File

@ -8,7 +8,7 @@
import {SecurityContext} from '@angular/core'; import {SecurityContext} from '@angular/core';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {EMPTY_STATE as EMPTY_ANIMATION_STATE} from '../private_import_core'; import {EMPTY_STATE as EMPTY_ANIMATION_STATE} from '../private_import_core';
import {BoundElementPropertyAst, BoundEventAst, PropertyBindingType} from '../template_parser/template_ast'; import {BoundElementPropertyAst, BoundEventAst, PropertyBindingType} from '../template_parser/template_ast';
@ -26,7 +26,7 @@ export function writeToRenderer(
case PropertyBindingType.Property: case PropertyBindingType.Property:
if (logBindingUpdate) { if (logBindingUpdate) {
updateStmts.push( updateStmts.push(
o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfo)) o.importExpr(createIdentifier(Identifiers.setBindingDebugInfo))
.callFn([renderer, renderElement, o.literal(boundProp.name), renderValue]) .callFn([renderer, renderElement, o.literal(boundProp.name), renderValue])
.toStmt()); .toStmt());
} }
@ -104,7 +104,7 @@ export function triggerAnimation(
// it's important to normalize the void value as `void` explicitly // it's important to normalize the void value as `void` explicitly
// so that the styles data can be obtained from the stringmap // so that the styles data can be obtained from the stringmap
const emptyStateValue = o.literal(EMPTY_ANIMATION_STATE); const emptyStateValue = o.literal(EMPTY_ANIMATION_STATE);
const unitializedValue = o.importExpr(resolveIdentifier(Identifiers.UNINITIALIZED)); const unitializedValue = o.importExpr(createIdentifier(Identifiers.UNINITIALIZED));
const animationTransitionVar = o.variable('animationTransition_' + animationName); const animationTransitionVar = o.variable('animationTransition_' + animationName);
updateStmts.push( updateStmts.push(

View File

@ -9,7 +9,7 @@
import {ViewEncapsulation, isDevMode} from '@angular/core'; import {ViewEncapsulation, isDevMode} from '@angular/core';
import {CompileIdentifierMetadata} from './compile_metadata'; import {CompileIdentifierMetadata} from './compile_metadata';
import {Identifiers, resolveIdentifier} from './identifiers'; import {Identifiers, createIdentifier} from './identifiers';
function unimplemented(): any { function unimplemented(): any {
throw new Error('unimplemented'); throw new Error('unimplemented');
@ -61,7 +61,7 @@ export abstract class RenderTypes {
} }
export class DefaultRenderTypes implements RenderTypes { export class DefaultRenderTypes implements RenderTypes {
get renderer() { return resolveIdentifier(Identifiers.Renderer); }; get renderer() { return createIdentifier(Identifiers.Renderer); };
renderText: any = null; renderText: any = null;
renderElement: any = null; renderElement: any = null;
renderComment: any = null; renderComment: any = null;

View File

@ -8,13 +8,13 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata} from './compile_metadata'; import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, identifierModuleUrl, identifierName} from './compile_metadata';
import {createCheckBindingField, createCheckBindingStmt} from './compiler_util/binding_util'; import {createCheckBindingField, createCheckBindingStmt} from './compiler_util/binding_util';
import {EventHandlerVars, convertActionBinding, convertPropertyBinding} from './compiler_util/expression_converter'; import {EventHandlerVars, convertActionBinding, convertPropertyBinding} from './compiler_util/expression_converter';
import {triggerAnimation, writeToRenderer} from './compiler_util/render_util'; import {triggerAnimation, writeToRenderer} from './compiler_util/render_util';
import {CompilerConfig} from './config'; import {CompilerConfig} from './config';
import {Parser} from './expression_parser/parser'; import {Parser} from './expression_parser/parser';
import {Identifiers, resolveIdentifier} from './identifiers'; import {Identifiers, createIdentifier} from './identifiers';
import {DEFAULT_INTERPOLATION_CONFIG} from './ml_parser/interpolation_config'; import {DEFAULT_INTERPOLATION_CONFIG} from './ml_parser/interpolation_config';
import {ClassBuilder, createClassStmt} from './output/class_builder'; import {ClassBuilder, createClassStmt} from './output/class_builder';
import * as o from './output/output_ast'; import * as o from './output/output_ast';
@ -53,7 +53,9 @@ const RESET_CHANGES_STMT = o.THIS_EXPR.prop(CHANGES_FIELD_NAME).set(o.literalMap
*/ */
@Injectable() @Injectable()
export class DirectiveWrapperCompiler { export class DirectiveWrapperCompiler {
static dirWrapperClassName(id: CompileIdentifierMetadata) { return `Wrapper_${id.name}`; } static dirWrapperClassName(id: CompileIdentifierMetadata) {
return `Wrapper_${identifierName(id)}`;
}
constructor( constructor(
private compilerConfig: CompilerConfig, private _exprParser: Parser, private compilerConfig: CompilerConfig, private _exprParser: Parser,
@ -117,10 +119,10 @@ class DirectiveWrapperBuilder implements ClassBuilder {
[ [
new o.FnParam( new o.FnParam(
VIEW_VAR.name, VIEW_VAR.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam( new o.FnParam(
COMPONENT_VIEW_VAR.name, COMPONENT_VIEW_VAR.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE),
], ],
this.detachStmts), this.detachStmts),
@ -172,7 +174,7 @@ function addNgDoCheckMethod(builder: DirectiveWrapperBuilder) {
} }
if (builder.compilerConfig.logBindingUpdate) { if (builder.compilerConfig.logBindingUpdate) {
onChangesStmts.push( onChangesStmts.push(
o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfoForChanges)) o.importExpr(createIdentifier(Identifiers.setBindingDebugInfoForChanges))
.callFn( .callFn(
[VIEW_VAR.prop('renderer'), RENDER_EL_VAR, o.THIS_EXPR.prop(CHANGES_FIELD_NAME)]) [VIEW_VAR.prop('renderer'), RENDER_EL_VAR, o.THIS_EXPR.prop(CHANGES_FIELD_NAME)])
.toStmt()); .toStmt());
@ -198,7 +200,7 @@ function addNgDoCheckMethod(builder: DirectiveWrapperBuilder) {
'ngDoCheck', 'ngDoCheck',
[ [
new o.FnParam( new o.FnParam(
VIEW_VAR.name, o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), VIEW_VAR.name, o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE), new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
], ],
@ -214,7 +216,7 @@ function addCheckInputMethod(input: string, builder: DirectiveWrapperBuilder) {
if (builder.genChanges) { if (builder.genChanges) {
onChangeStatements.push(o.THIS_EXPR.prop(CHANGES_FIELD_NAME) onChangeStatements.push(o.THIS_EXPR.prop(CHANGES_FIELD_NAME)
.key(o.literal(input)) .key(o.literal(input))
.set(o.importExpr(resolveIdentifier(Identifiers.SimpleChange)) .set(o.importExpr(createIdentifier(Identifiers.SimpleChange))
.instantiate([field.expression, CURR_VALUE_VAR])) .instantiate([field.expression, CURR_VALUE_VAR]))
.toStmt()); .toStmt());
} }
@ -237,10 +239,10 @@ function addCheckHostMethod(
const stmts: o.Statement[] = []; const stmts: o.Statement[] = [];
const methodParams: o.FnParam[] = [ const methodParams: o.FnParam[] = [
new o.FnParam( new o.FnParam(
VIEW_VAR.name, o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), VIEW_VAR.name, o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam( new o.FnParam(
COMPONENT_VIEW_VAR.name, COMPONENT_VIEW_VAR.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE), new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE),
new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE), new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
]; ];
@ -255,14 +257,14 @@ function addCheckHostMethod(
if (hostProp.needsRuntimeSecurityContext) { if (hostProp.needsRuntimeSecurityContext) {
securityContextExpr = o.variable(`secCtx_${methodParams.length}`); securityContextExpr = o.variable(`secCtx_${methodParams.length}`);
methodParams.push(new o.FnParam( methodParams.push(new o.FnParam(
securityContextExpr.name, o.importType(resolveIdentifier(Identifiers.SecurityContext)))); securityContextExpr.name, o.importType(createIdentifier(Identifiers.SecurityContext))));
} }
let checkBindingStmts: o.Statement[]; let checkBindingStmts: o.Statement[];
if (hostProp.isAnimation) { if (hostProp.isAnimation) {
const {updateStmts, detachStmts} = triggerAnimation( const {updateStmts, detachStmts} = triggerAnimation(
VIEW_VAR, COMPONENT_VIEW_VAR, hostProp, VIEW_VAR, COMPONENT_VIEW_VAR, hostProp,
o.THIS_EXPR.prop(EVENT_HANDLER_FIELD_NAME) o.THIS_EXPR.prop(EVENT_HANDLER_FIELD_NAME)
.or(o.importExpr(resolveIdentifier(Identifiers.noop))), .or(o.importExpr(createIdentifier(Identifiers.noop))),
RENDER_EL_VAR, evalResult.currValExpr, field.expression); RENDER_EL_VAR, evalResult.currValExpr, field.expression);
checkBindingStmts = updateStmts; checkBindingStmts = updateStmts;
builder.detachStmts.push(...detachStmts); builder.detachStmts.push(...detachStmts);
@ -306,7 +308,7 @@ function addHandleEventMethod(hostListeners: BoundEventAst[], builder: Directive
function addSubscribeMethod(dirMeta: CompileDirectiveMetadata, builder: DirectiveWrapperBuilder) { function addSubscribeMethod(dirMeta: CompileDirectiveMetadata, builder: DirectiveWrapperBuilder) {
const methodParams: o.FnParam[] = [ const methodParams: o.FnParam[] = [
new o.FnParam( new o.FnParam(
VIEW_VAR.name, o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), VIEW_VAR.name, o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(EVENT_HANDLER_FIELD_NAME, o.DYNAMIC_TYPE) new o.FnParam(EVENT_HANDLER_FIELD_NAME, o.DYNAMIC_TYPE)
]; ];
const stmts: o.Statement[] = [ const stmts: o.Statement[] = [
@ -348,9 +350,10 @@ function parseHostBindings(
const errors: ParseError[] = []; const errors: ParseError[] = [];
const parser = const parser =
new BindingParser(exprParser, DEFAULT_INTERPOLATION_CONFIG, schemaRegistry, [], errors); new BindingParser(exprParser, DEFAULT_INTERPOLATION_CONFIG, schemaRegistry, [], errors);
const sourceFileName = dirMeta.type.moduleUrl ? const moduleUrl = identifierModuleUrl(dirMeta.type);
`in Directive ${dirMeta.type.name} in ${dirMeta.type.moduleUrl}` : const sourceFileName = moduleUrl ?
`in Directive ${dirMeta.type.name}`; `in Directive ${identifierName(dirMeta.type)} in ${moduleUrl}` :
`in Directive ${identifierName(dirMeta.type)}`;
const sourceFile = new ParseSourceFile('', sourceFileName); const sourceFile = new ParseSourceFile('', sourceFileName);
const sourceSpan = new ParseSourceSpan( const sourceSpan = new ParseSourceSpan(
new ParseLocation(sourceFile, null, null, null), new ParseLocation(sourceFile, null, null, null),

View File

@ -9,7 +9,7 @@
import {ANALYZE_FOR_ENTRY_COMPONENTS, AnimationTransitionEvent, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, Injector, LOCALE_ID, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core'; import {ANALYZE_FOR_ENTRY_COMPONENTS, AnimationTransitionEvent, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, Injector, LOCALE_ID, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
import {StaticSymbol, isStaticSymbol} from './aot/static_symbol'; import {StaticSymbol, isStaticSymbol} from './aot/static_symbol';
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata'; import {CompileIdentifierMetadata, CompileTokenMetadata, identifierModuleUrl, identifierName} from './compile_metadata';
import {AnimationGroupPlayer, AnimationKeyframe, AnimationSequencePlayer, AnimationStyles, AnimationTransition, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, ComponentRef_, DebugAppView, DebugContext, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewContainer, ViewType, balanceAnimationKeyframes, clearStyles, collectAndResolveStyles, devModeEqual, prepareFinalAnimationStyles, reflector, registerModuleFactory, renderStyles, view_utils} from './private_import_core'; import {AnimationGroupPlayer, AnimationKeyframe, AnimationSequencePlayer, AnimationStyles, AnimationTransition, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, ComponentRef_, DebugAppView, DebugContext, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewContainer, ViewType, balanceAnimationKeyframes, clearStyles, collectAndResolveStyles, devModeEqual, prepareFinalAnimationStyles, reflector, registerModuleFactory, renderStyles, view_utils} from './private_import_core';
const APP_VIEW_MODULE_URL = assetUrl('core', 'linker/view'); const APP_VIEW_MODULE_URL = assetUrl('core', 'linker/view');
@ -347,27 +347,25 @@ export function assetUrl(pkg: string, path: string = null, type: string = 'src')
} }
export function resolveIdentifier(identifier: IdentifierSpec) { export function resolveIdentifier(identifier: IdentifierSpec) {
let moduleUrl = identifier.moduleUrl; return reflector.resolveIdentifier(identifier.name, identifier.moduleUrl, identifier.runtime);
}
export function createIdentifier(identifier: IdentifierSpec) {
const reference = const reference =
reflector.resolveIdentifier(identifier.name, identifier.moduleUrl, identifier.runtime); reflector.resolveIdentifier(identifier.name, identifier.moduleUrl, identifier.runtime);
if (isStaticSymbol(reference)) { return new CompileIdentifierMetadata({reference: reference});
moduleUrl = reference.filePath;
}
return new CompileIdentifierMetadata(
{name: identifier.name, moduleUrl: moduleUrl, reference: reference});
} }
export function identifierToken(identifier: CompileIdentifierMetadata): CompileTokenMetadata { export function identifierToken(identifier: CompileIdentifierMetadata): CompileTokenMetadata {
return new CompileTokenMetadata({identifier: identifier}); return new CompileTokenMetadata({identifier: identifier});
} }
export function resolveIdentifierToken(identifier: IdentifierSpec): CompileTokenMetadata { export function createIdentifierToken(identifier: IdentifierSpec): CompileTokenMetadata {
return identifierToken(resolveIdentifier(identifier)); return identifierToken(createIdentifier(identifier));
} }
export function resolveEnumIdentifier( export function createEnumIdentifier(
enumType: CompileIdentifierMetadata, name: string): CompileIdentifierMetadata { enumType: IdentifierSpec, name: string): CompileIdentifierMetadata {
const resolvedEnum = reflector.resolveEnum(enumType.reference, name); const resolvedEnum = reflector.resolveEnum(resolveIdentifier(enumType), name);
return new CompileIdentifierMetadata( return new CompileIdentifierMetadata({reference: resolvedEnum});
{name: `${enumType.name}.${name}`, moduleUrl: enumType.moduleUrl, reference: resolvedEnum});
} }

View File

@ -10,7 +10,7 @@ import {Compiler, ComponentFactory, Injectable, Injector, ModuleWithComponentFac
import {AnimationCompiler} from '../animation/animation_compiler'; import {AnimationCompiler} from '../animation/animation_compiler';
import {AnimationParser} from '../animation/animation_parser'; import {AnimationParser} from '../animation/animation_parser';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, ProviderMeta, createHostComponentMeta} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompilePipeMetadata, ProviderMeta, createHostComponentMeta, identifierName} from '../compile_metadata';
import {CompilerConfig} from '../config'; import {CompilerConfig} from '../config';
import {DirectiveNormalizer} from '../directive_normalizer'; import {DirectiveNormalizer} from '../directive_normalizer';
import {DirectiveWrapperCompiler} from '../directive_wrapper_compiler'; import {DirectiveWrapperCompiler} from '../directive_wrapper_compiler';
@ -126,14 +126,13 @@ export class JitCompiler implements Compiler {
compileResult.dependencies.forEach((dep) => { compileResult.dependencies.forEach((dep) => {
dep.placeholder.reference = dep.placeholder.reference =
this._assertComponentKnown(dep.comp.reference, true).proxyComponentFactory; this._assertComponentKnown(dep.comp.reference, true).proxyComponentFactory;
dep.placeholder.name = `compFactory_${dep.comp.name}`;
}); });
if (!this._compilerConfig.useJit) { if (!this._compilerConfig.useJit) {
ngModuleFactory = ngModuleFactory =
interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar); interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar);
} else { } else {
ngModuleFactory = jitStatements( ngModuleFactory = jitStatements(
`/${moduleMeta.type.name}/module.ngfactory.js`, compileResult.statements, `/${identifierName(moduleMeta.type)}/module.ngfactory.js`, compileResult.statements,
compileResult.ngModuleFactoryVar); compileResult.ngModuleFactoryVar);
} }
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory); this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
@ -215,7 +214,12 @@ export class JitCompiler implements Compiler {
if (!compiledTemplate) { if (!compiledTemplate) {
const compMeta = this._metadataResolver.getDirectiveMetadata(compType); const compMeta = this._metadataResolver.getDirectiveMetadata(compType);
assertComponent(compMeta); assertComponent(compMeta);
const hostMeta = createHostComponentMeta(compMeta);
class HostClass {
static overriddenName = `${identifierName(compMeta.type)}_Host`;
}
const hostMeta = createHostComponentMeta(HostClass, compMeta);
compiledTemplate = new CompiledTemplate( compiledTemplate = new CompiledTemplate(
true, compMeta.selector, compMeta.type, hostMeta, ngModule, [compMeta.type]); true, compMeta.selector, compMeta.type, hostMeta, ngModule, [compMeta.type]);
this._compiledHostTemplateCache.set(compType, compiledTemplate); this._compiledHostTemplateCache.set(compType, compiledTemplate);
@ -264,8 +268,8 @@ export class JitCompiler implements Compiler {
directiveWrapperClass = interpretStatements(statements, compileResult.dirWrapperClassVar); directiveWrapperClass = interpretStatements(statements, compileResult.dirWrapperClassVar);
} else { } else {
directiveWrapperClass = jitStatements( directiveWrapperClass = jitStatements(
`/${moduleMeta.type.name}/${dirMeta.type.name}/wrapper.ngfactory.js`, statements, `/${identifierName(moduleMeta.type)}/${identifierName(dirMeta.type)}/wrapper.ngfactory.js`,
compileResult.dirWrapperClassVar); statements, compileResult.dirWrapperClassVar);
} }
this._compiledDirectiveWrapperCache.set(dirMeta.type.reference, directiveWrapperClass); this._compiledDirectiveWrapperCache.set(dirMeta.type.reference, directiveWrapperClass);
} }
@ -288,9 +292,9 @@ export class JitCompiler implements Compiler {
pipe => this._metadataResolver.getPipeSummary(pipe.reference)); pipe => this._metadataResolver.getPipeSummary(pipe.reference));
const parsedTemplate = this._templateParser.parse( const parsedTemplate = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, template.ngModule.schemas, compMeta, compMeta.template.template, directives, pipes, template.ngModule.schemas,
compMeta.type.name); identifierName(compMeta.type));
const compiledAnimations = const compiledAnimations =
this._animationCompiler.compile(compMeta.type.name, parsedAnimations); this._animationCompiler.compile(identifierName(compMeta.type), parsedAnimations);
const compileResult = this._viewCompiler.compileComponent( const compileResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, ir.variable(stylesCompileResult.componentStylesheet.stylesVar), compMeta, parsedTemplate, ir.variable(stylesCompileResult.componentStylesheet.stylesVar),
pipes, compiledAnimations); pipes, compiledAnimations);
@ -300,12 +304,10 @@ export class JitCompiler implements Compiler {
const vfd = <ViewClassDependency>dep; const vfd = <ViewClassDependency>dep;
depTemplate = this._assertComponentKnown(vfd.comp.reference, false); depTemplate = this._assertComponentKnown(vfd.comp.reference, false);
vfd.placeholder.reference = depTemplate.proxyViewClass; vfd.placeholder.reference = depTemplate.proxyViewClass;
vfd.placeholder.name = `View_${vfd.comp.name}`;
} else if (dep instanceof ComponentFactoryDependency) { } else if (dep instanceof ComponentFactoryDependency) {
const cfd = <ComponentFactoryDependency>dep; const cfd = <ComponentFactoryDependency>dep;
depTemplate = this._assertComponentKnown(cfd.comp.reference, true); depTemplate = this._assertComponentKnown(cfd.comp.reference, true);
cfd.placeholder.reference = depTemplate.proxyComponentFactory; cfd.placeholder.reference = depTemplate.proxyComponentFactory;
cfd.placeholder.name = `compFactory_${cfd.comp.name}`;
} else if (dep instanceof DirectiveWrapperDependency) { } else if (dep instanceof DirectiveWrapperDependency) {
const dwd = <DirectiveWrapperDependency>dep; const dwd = <DirectiveWrapperDependency>dep;
dwd.placeholder.reference = this._assertDirectiveWrapper(dwd.dir.reference); dwd.placeholder.reference = this._assertDirectiveWrapper(dwd.dir.reference);
@ -319,7 +321,7 @@ export class JitCompiler implements Compiler {
viewClass = interpretStatements(statements, compileResult.viewClassVar); viewClass = interpretStatements(statements, compileResult.viewClassVar);
} else { } else {
viewClass = jitStatements( viewClass = jitStatements(
`/${template.ngModule.type.name}/${template.compType.name}/${template.isHost?'host':'component'}.ngfactory.js`, `/${identifierName(template.ngModule.type)}/${identifierName(template.compType)}/${template.isHost?'host':'component'}.ngfactory.js`,
statements, compileResult.viewClassVar); statements, compileResult.viewClassVar);
} }
template.compiled(viewClass); template.compiled(viewClass);
@ -332,7 +334,6 @@ export class JitCompiler implements Compiler {
const nestedStylesArr = this._resolveAndEvalStylesCompileResult( const nestedStylesArr = this._resolveAndEvalStylesCompileResult(
nestedCompileResult, externalStylesheetsByModuleUrl); nestedCompileResult, externalStylesheetsByModuleUrl);
dep.valuePlaceholder.reference = nestedStylesArr; dep.valuePlaceholder.reference = nestedStylesArr;
dep.valuePlaceholder.name = `importedStyles${i}`;
}); });
} }
@ -380,7 +381,8 @@ class CompiledTemplate {
function assertComponent(meta: CompileDirectiveMetadata) { function assertComponent(meta: CompileDirectiveMetadata) {
if (!meta.isComponent) { if (!meta.isComponent) {
throw new Error(`Could not compile '${meta.type.name}' because it is not a component.`); throw new Error(
`Could not compile '${identifierName(meta.type)}' because it is not a component.`);
} }
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
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, Directive, Host, Inject, Injectable, ModuleWithProviders, Optional, Provider, Query, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef} from '@angular/core';
import {isStaticSymbol} from './aot/static_symbol'; import {isStaticSymbol} from './aot/static_symbol';
import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions'; import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
@ -15,14 +15,14 @@ import {DirectiveNormalizer} from './directive_normalizer';
import {DirectiveResolver} from './directive_resolver'; import {DirectiveResolver} from './directive_resolver';
import {ListWrapper, StringMapWrapper} from './facade/collection'; import {ListWrapper, StringMapWrapper} from './facade/collection';
import {isBlank, isPresent, stringify} from './facade/lang'; import {isBlank, isPresent, stringify} from './facade/lang';
import {Identifiers, resolveIdentifierToken} from './identifiers'; import {Identifiers, createIdentifierToken, resolveIdentifier} from './identifiers';
import {hasLifecycleHook} from './lifecycle_reflector'; import {hasLifecycleHook} from './lifecycle_reflector';
import {NgModuleResolver} from './ng_module_resolver'; import {NgModuleResolver} from './ng_module_resolver';
import {PipeResolver} from './pipe_resolver'; import {PipeResolver} from './pipe_resolver';
import {ComponentStillLoadingError, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from './private_import_core'; import {ComponentStillLoadingError, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from './private_import_core';
import {ElementSchemaRegistry} from './schema/element_schema_registry'; import {ElementSchemaRegistry} from './schema/element_schema_registry';
import {getUrlScheme} from './url_resolver'; import {getUrlScheme} from './url_resolver';
import {MODULE_SUFFIX, SyncAsyncResult, ValueTransformer, sanitizeIdentifier, visitValue} from './util'; import {MODULE_SUFFIX, SyncAsyncResult, ValueTransformer, visitValue} from './util';
@ -41,8 +41,6 @@ export class CompileMetadataResolver {
private _pipeSummaryCache = new Map<Type<any>, cpl.CompilePipeSummary>(); private _pipeSummaryCache = new Map<Type<any>, cpl.CompilePipeSummary>();
private _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>(); private _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>();
private _ngModuleOfTypes = new Map<Type<any>, Type<any>>(); private _ngModuleOfTypes = new Map<Type<any>, Type<any>>();
private _anonymousTypes = new Map<Object, number>();
private _anonymousTypeIndex = 0;
constructor( constructor(
private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver, private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
@ -50,20 +48,6 @@ export class CompileMetadataResolver {
private _directiveNormalizer: DirectiveNormalizer, private _directiveNormalizer: DirectiveNormalizer,
private _reflector: ReflectorReader = reflector) {} private _reflector: ReflectorReader = reflector) {}
private sanitizeTokenName(token: any): string {
let identifier = stringify(token);
if (identifier.indexOf('(') >= 0) {
// case: anonymous functions!
let found = this._anonymousTypes.get(token);
if (!found) {
this._anonymousTypes.set(token, this._anonymousTypeIndex++);
found = this._anonymousTypes.get(token);
}
identifier = `anonymous_token_${found}_`;
}
return sanitizeIdentifier(identifier);
}
clearCacheFor(type: Type<any>) { clearCacheFor(type: Type<any>) {
const dirMeta = this._directiveCache.get(type); const dirMeta = this._directiveCache.get(type);
this._directiveCache.delete(type); this._directiveCache.delete(type);
@ -147,25 +131,25 @@ export class CompileMetadataResolver {
return; return;
} }
directiveType = resolveForwardRef(directiveType); directiveType = resolveForwardRef(directiveType);
const nonNormalizedMetadata = this.getNonNormalizedDirectiveMetadata(directiveType); const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType);
const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata) => { const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata) => {
const normalizedDirMeta = new cpl.CompileDirectiveMetadata({ const normalizedDirMeta = new cpl.CompileDirectiveMetadata({
type: nonNormalizedMetadata.type, type: metadata.type,
isComponent: nonNormalizedMetadata.isComponent, isComponent: metadata.isComponent,
selector: nonNormalizedMetadata.selector, selector: metadata.selector,
exportAs: nonNormalizedMetadata.exportAs, exportAs: metadata.exportAs,
changeDetection: nonNormalizedMetadata.changeDetection, changeDetection: metadata.changeDetection,
inputs: nonNormalizedMetadata.inputs, inputs: metadata.inputs,
outputs: nonNormalizedMetadata.outputs, outputs: metadata.outputs,
hostListeners: nonNormalizedMetadata.hostListeners, hostListeners: metadata.hostListeners,
hostProperties: nonNormalizedMetadata.hostProperties, hostProperties: metadata.hostProperties,
hostAttributes: nonNormalizedMetadata.hostAttributes, hostAttributes: metadata.hostAttributes,
providers: nonNormalizedMetadata.providers, providers: metadata.providers,
viewProviders: nonNormalizedMetadata.viewProviders, viewProviders: metadata.viewProviders,
queries: nonNormalizedMetadata.queries, queries: metadata.queries,
viewQueries: nonNormalizedMetadata.viewQueries, viewQueries: metadata.viewQueries,
entryComponents: nonNormalizedMetadata.entryComponents, entryComponents: metadata.entryComponents,
template: templateMetadata template: templateMetadata
}); });
this._directiveCache.set(directiveType, normalizedDirMeta); this._directiveCache.set(directiveType, normalizedDirMeta);
@ -173,17 +157,17 @@ export class CompileMetadataResolver {
return normalizedDirMeta; return normalizedDirMeta;
}; };
if (nonNormalizedMetadata.isComponent) { if (metadata.isComponent) {
const templateMeta = this._directiveNormalizer.normalizeTemplate({ const templateMeta = this._directiveNormalizer.normalizeTemplate({
componentType: directiveType, componentType: directiveType,
moduleUrl: nonNormalizedMetadata.type.moduleUrl, moduleUrl: componentModuleUrl(this._reflector, directiveType, annotation),
encapsulation: nonNormalizedMetadata.template.encapsulation, encapsulation: metadata.template.encapsulation,
template: nonNormalizedMetadata.template.template, template: metadata.template.template,
templateUrl: nonNormalizedMetadata.template.templateUrl, templateUrl: metadata.template.templateUrl,
styles: nonNormalizedMetadata.template.styles, styles: metadata.template.styles,
styleUrls: nonNormalizedMetadata.template.styleUrls, styleUrls: metadata.template.styleUrls,
animations: nonNormalizedMetadata.template.animations, animations: metadata.template.animations,
interpolation: nonNormalizedMetadata.template.interpolation interpolation: metadata.template.interpolation
}); });
if (templateMeta.syncResult) { if (templateMeta.syncResult) {
createDirectiveMetadata(templateMeta.syncResult); createDirectiveMetadata(templateMeta.syncResult);
@ -201,18 +185,17 @@ export class CompileMetadataResolver {
} }
} }
getNonNormalizedDirectiveMetadata(directiveType: any): cpl.CompileDirectiveMetadata { getNonNormalizedDirectiveMetadata(directiveType: any):
{annotation: Directive, metadata: cpl.CompileDirectiveMetadata} {
directiveType = resolveForwardRef(directiveType); directiveType = resolveForwardRef(directiveType);
const dirMeta = this._directiveResolver.resolve(directiveType); const dirMeta = this._directiveResolver.resolve(directiveType);
if (!dirMeta) { if (!dirMeta) {
return null; return null;
} }
let moduleUrl = staticTypeModuleUrl(directiveType);
let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata; let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata;
if (dirMeta instanceof Component) { if (dirMeta instanceof Component) {
// component // component
moduleUrl = componentModuleUrl(this._reflector, directiveType, dirMeta);
assertArrayOfStrings('styles', dirMeta.styles); assertArrayOfStrings('styles', dirMeta.styles);
assertArrayOfStrings('styleUrls', dirMeta.styleUrls); assertArrayOfStrings('styleUrls', dirMeta.styleUrls);
assertInterpolationSymbols('interpolation', dirMeta.interpolation); assertInterpolationSymbols('interpolation', dirMeta.interpolation);
@ -246,10 +229,9 @@ export class CompileMetadataResolver {
`viewProviders for "${stringify(directiveType)}"`); `viewProviders for "${stringify(directiveType)}"`);
} }
if (dirMeta.entryComponents) { if (dirMeta.entryComponents) {
entryComponentMetadata = entryComponentMetadata = flattenAndDedupeArray(dirMeta.entryComponents)
flattenAndDedupeArray(dirMeta.entryComponents) .map((type) => this._getIdentifierMetadata(type))
.map((type) => this._getIdentifierMetadata(type, staticTypeModuleUrl(type))) .concat(entryComponentMetadata);
.concat(entryComponentMetadata);
} }
if (!selector) { if (!selector) {
selector = this._schemaRegistry.getDefaultComponentElementName(); selector = this._schemaRegistry.getDefaultComponentElementName();
@ -273,11 +255,11 @@ export class CompileMetadataResolver {
viewQueries = this._getQueriesMetadata(dirMeta.queries, true, directiveType); viewQueries = this._getQueriesMetadata(dirMeta.queries, true, directiveType);
} }
return cpl.CompileDirectiveMetadata.create({ const metadata = cpl.CompileDirectiveMetadata.create({
selector: selector, selector: selector,
exportAs: dirMeta.exportAs, exportAs: dirMeta.exportAs,
isComponent: !!nonNormalizedTemplateMetadata, isComponent: !!nonNormalizedTemplateMetadata,
type: this._getTypeMetadata(directiveType, moduleUrl), type: this._getTypeMetadata(directiveType),
template: nonNormalizedTemplateMetadata, template: nonNormalizedTemplateMetadata,
changeDetection: changeDetectionStrategy, changeDetection: changeDetectionStrategy,
inputs: dirMeta.inputs, inputs: dirMeta.inputs,
@ -289,6 +271,7 @@ export class CompileMetadataResolver {
viewQueries: viewQueries, viewQueries: viewQueries,
entryComponents: entryComponentMetadata entryComponents: entryComponentMetadata
}); });
return {metadata, annotation: dirMeta};
} }
/** /**
@ -420,8 +403,7 @@ export class CompileMetadataResolver {
if (exportedModuleSummary) { if (exportedModuleSummary) {
exportedModules.push(exportedModuleSummary); exportedModules.push(exportedModuleSummary);
} else { } else {
exportedNonModuleIdentifiers.push( exportedNonModuleIdentifiers.push(this._getIdentifierMetadata(exportedType));
this._getIdentifierMetadata(exportedType, staticTypeModuleUrl(exportedType)));
} }
}); });
} }
@ -435,8 +417,7 @@ export class CompileMetadataResolver {
throw new Error( throw new Error(
`Unexpected value '${stringify(declaredType)}' declared by the module '${stringify(moduleType)}'`); `Unexpected value '${stringify(declaredType)}' declared by the module '${stringify(moduleType)}'`);
} }
const declaredIdentifier = const declaredIdentifier = this._getIdentifierMetadata(declaredType);
this._getIdentifierMetadata(declaredType, staticTypeModuleUrl(declaredType));
if (this._directiveResolver.isDirective(declaredType)) { if (this._directiveResolver.isDirective(declaredType)) {
transitiveModule.directivesSet.add(declaredType); transitiveModule.directivesSet.add(declaredType);
transitiveModule.directives.push(declaredIdentifier); transitiveModule.directives.push(declaredIdentifier);
@ -479,8 +460,7 @@ export class CompileMetadataResolver {
if (meta.entryComponents) { if (meta.entryComponents) {
entryComponents.push( entryComponents.push(
...flattenAndDedupeArray(meta.entryComponents) ...flattenAndDedupeArray(meta.entryComponents).map(type => this._getTypeMetadata(type)));
.map(type => this._getTypeMetadata(type, staticTypeModuleUrl(type))));
} }
if (meta.bootstrap) { if (meta.bootstrap) {
@ -489,7 +469,7 @@ export class CompileMetadataResolver {
throw new Error( throw new Error(
`Unexpected value '${stringify(type)}' used in the bootstrap property of module '${stringify(moduleType)}'`); `Unexpected value '${stringify(type)}' used in the bootstrap property of module '${stringify(moduleType)}'`);
} }
return this._getTypeMetadata(type, staticTypeModuleUrl(type)); return this._getTypeMetadata(type);
}); });
bootstrapComponents.push(...typeMetadata); bootstrapComponents.push(...typeMetadata);
} }
@ -504,7 +484,7 @@ export class CompileMetadataResolver {
transitiveModule.providers.push(...providers); transitiveModule.providers.push(...providers);
compileMeta = new cpl.CompileNgModuleMetadata({ compileMeta = new cpl.CompileNgModuleMetadata({
type: this._getTypeMetadata(moduleType, staticTypeModuleUrl(moduleType)), type: this._getTypeMetadata(moduleType),
providers, providers,
entryComponents, entryComponents,
bootstrapComponents, bootstrapComponents,
@ -575,19 +555,14 @@ export class CompileMetadataResolver {
transitiveModules, providers, entryComponents, directives, pipes, directiveLoaders); transitiveModules, providers, entryComponents, directives, pipes, directiveLoaders);
} }
private _getIdentifierMetadata(type: Type<any>, moduleUrl: string): private _getIdentifierMetadata(type: Type<any>): cpl.CompileIdentifierMetadata {
cpl.CompileIdentifierMetadata {
type = resolveForwardRef(type); type = resolveForwardRef(type);
return new cpl.CompileIdentifierMetadata( return new cpl.CompileIdentifierMetadata({reference: type});
{name: this.sanitizeTokenName(type), moduleUrl, reference: type});
} }
private _getTypeMetadata(type: Type<any>, moduleUrl: string, dependencies: any[] = null): private _getTypeMetadata(type: Type<any>, dependencies: any[] = null): cpl.CompileTypeMetadata {
cpl.CompileTypeMetadata { const identifier = this._getIdentifierMetadata(type);
const identifier = this._getIdentifierMetadata(type, moduleUrl);
return new cpl.CompileTypeMetadata({ return new cpl.CompileTypeMetadata({
name: identifier.name,
moduleUrl: identifier.moduleUrl,
reference: identifier.reference, reference: identifier.reference,
diDeps: this._getDependenciesMetadata(identifier.reference, dependencies), diDeps: this._getDependenciesMetadata(identifier.reference, dependencies),
lifecycleHooks: lifecycleHooks:
@ -595,15 +570,11 @@ export class CompileMetadataResolver {
}); });
} }
private _getFactoryMetadata(factory: Function, moduleUrl: string, dependencies: any[] = null): private _getFactoryMetadata(factory: Function, dependencies: any[] = null):
cpl.CompileFactoryMetadata { cpl.CompileFactoryMetadata {
factory = resolveForwardRef(factory); factory = resolveForwardRef(factory);
return new cpl.CompileFactoryMetadata({ return new cpl.CompileFactoryMetadata(
name: this.sanitizeTokenName(factory), {reference: factory, diDeps: this._getDependenciesMetadata(factory, dependencies)});
moduleUrl,
reference: factory,
diDeps: this._getDependenciesMetadata(factory, dependencies)
});
} }
/** /**
@ -641,7 +612,7 @@ export class CompileMetadataResolver {
const pipeAnnotation = this._pipeResolver.resolve(pipeType); const pipeAnnotation = this._pipeResolver.resolve(pipeType);
const pipeMeta = new cpl.CompilePipeMetadata({ const pipeMeta = new cpl.CompilePipeMetadata({
type: this._getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)), type: this._getTypeMetadata(pipeType),
name: pipeAnnotation.name, name: pipeAnnotation.name,
pure: pipeAnnotation.pure pure: pipeAnnotation.pure
}); });
@ -716,13 +687,8 @@ export class CompileMetadataResolver {
if (typeof token === 'string') { if (typeof token === 'string') {
compileToken = new cpl.CompileTokenMetadata({value: token}); compileToken = new cpl.CompileTokenMetadata({value: token});
} else { } else {
compileToken = new cpl.CompileTokenMetadata({ compileToken = new cpl.CompileTokenMetadata(
identifier: new cpl.CompileIdentifierMetadata({ {identifier: new cpl.CompileIdentifierMetadata({reference: token})});
reference: token,
name: this.sanitizeTokenName(token),
moduleUrl: staticTypeModuleUrl(token)
})
});
} }
return compileToken; return compileToken;
} }
@ -741,14 +707,14 @@ export class CompileMetadataResolver {
compileProvider = this._getProvidersMetadata(provider, targetEntryComponents, debugInfo); compileProvider = this._getProvidersMetadata(provider, targetEntryComponents, debugInfo);
} else if (provider instanceof cpl.ProviderMeta) { } else if (provider instanceof cpl.ProviderMeta) {
const tokenMeta = this._getTokenMetadata(provider.token); const tokenMeta = this._getTokenMetadata(provider.token);
if (tokenMeta.reference === if (cpl.tokenReference(tokenMeta) ===
resolveIdentifierToken(Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS).reference) { resolveIdentifier(Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS)) {
targetEntryComponents.push(...this._getEntryComponentsFromProvider(provider)); targetEntryComponents.push(...this._getEntryComponentsFromProvider(provider));
} else { } else {
compileProvider = this.getProviderMetadata(provider); compileProvider = this.getProviderMetadata(provider);
} }
} else if (isValidType(provider)) { } else if (isValidType(provider)) {
compileProvider = this._getTypeMetadata(provider, staticTypeModuleUrl(provider)); compileProvider = this._getTypeMetadata(provider);
} else { } else {
const providersInfo = const providersInfo =
(<string[]>providers.reduce( (<string[]>providers.reduce(
@ -803,12 +769,10 @@ export class CompileMetadataResolver {
let compileFactoryMetadata: cpl.CompileFactoryMetadata = null; let compileFactoryMetadata: cpl.CompileFactoryMetadata = null;
if (provider.useClass) { if (provider.useClass) {
compileTypeMetadata = this._getTypeMetadata( compileTypeMetadata = this._getTypeMetadata(provider.useClass, provider.dependencies);
provider.useClass, staticTypeModuleUrl(provider.useClass), provider.dependencies);
compileDeps = compileTypeMetadata.diDeps; compileDeps = compileTypeMetadata.diDeps;
} else if (provider.useFactory) { } else if (provider.useFactory) {
compileFactoryMetadata = this._getFactoryMetadata( compileFactoryMetadata = this._getFactoryMetadata(provider.useFactory, provider.dependencies);
provider.useFactory, staticTypeModuleUrl(provider.useFactory), provider.dependencies);
compileDeps = compileFactoryMetadata.diDeps; compileDeps = compileFactoryMetadata.diDeps;
} }
@ -925,14 +889,10 @@ function isValidType(value: any): boolean {
return isStaticSymbol(value) || (value instanceof Type); return isStaticSymbol(value) || (value instanceof Type);
} }
function staticTypeModuleUrl(value: any): string { export function componentModuleUrl(
return isStaticSymbol(value) ? value.filePath : null;
}
function componentModuleUrl(
reflector: ReflectorReader, type: Type<any>, cmpMetadata: Component): string { reflector: ReflectorReader, type: Type<any>, cmpMetadata: Component): string {
if (isStaticSymbol(type)) { if (isStaticSymbol(type)) {
return staticTypeModuleUrl(type); return type.filePath;
} }
const moduleId = cmpMetadata.moduleId; const moduleId = cmpMetadata.moduleId;
@ -956,13 +916,7 @@ function convertToCompileValue(
class _CompileValueConverter extends ValueTransformer { class _CompileValueConverter extends ValueTransformer {
visitOther(value: any, targetIdentifiers: cpl.CompileIdentifierMetadata[]): any { visitOther(value: any, targetIdentifiers: cpl.CompileIdentifierMetadata[]): any {
let identifier: cpl.CompileIdentifierMetadata; const identifier = new cpl.CompileIdentifierMetadata({reference: value});
if (isStaticSymbol(value)) {
identifier = new cpl.CompileIdentifierMetadata(
{name: value.name, moduleUrl: value.filePath, reference: value});
} else {
identifier = new cpl.CompileIdentifierMetadata({reference: value});
}
targetIdentifiers.push(identifier); targetIdentifiers.push(identifier);
return identifier; return identifier;
} }

View File

@ -8,10 +8,10 @@
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {CompileDiDependencyMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileTokenMetadata} from './compile_metadata'; import {CompileDiDependencyMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileTokenMetadata, identifierModuleUrl, identifierName, tokenName, tokenReference} from './compile_metadata';
import {createDiTokenExpression} from './compiler_util/identifier_util'; import {createDiTokenExpression} from './compiler_util/identifier_util';
import {isPresent} from './facade/lang'; import {isPresent} from './facade/lang';
import {Identifiers, resolveIdentifier, resolveIdentifierToken} from './identifiers'; import {Identifiers, createIdentifier, createIdentifierToken, resolveIdentifier} from './identifiers';
import {ClassBuilder, createClassStmt} from './output/class_builder'; import {ClassBuilder, createClassStmt} from './output/class_builder';
import * as o from './output/output_ast'; import * as o from './output/output_ast';
import {convertValueToOutputAst} from './output/value_util'; import {convertValueToOutputAst} from './output/value_util';
@ -35,9 +35,10 @@ export class NgModuleCompileResult {
export class NgModuleCompiler { export class NgModuleCompiler {
compile(ngModuleMeta: CompileNgModuleMetadata, extraProviders: CompileProviderMetadata[]): compile(ngModuleMeta: CompileNgModuleMetadata, extraProviders: CompileProviderMetadata[]):
NgModuleCompileResult { NgModuleCompileResult {
const sourceFileName = isPresent(ngModuleMeta.type.moduleUrl) ? const moduleUrl = identifierModuleUrl(ngModuleMeta.type);
`in NgModule ${ngModuleMeta.type.name} in ${ngModuleMeta.type.moduleUrl}` : const sourceFileName = isPresent(moduleUrl) ?
`in NgModule ${ngModuleMeta.type.name}`; `in NgModule ${identifierName(ngModuleMeta.type)} in ${moduleUrl}` :
`in NgModule ${identifierName(ngModuleMeta.type)}`;
const sourceFile = new ParseSourceFile('', sourceFileName); const sourceFile = new ParseSourceFile('', sourceFileName);
const sourceSpan = new ParseSourceSpan( const sourceSpan = new ParseSourceSpan(
new ParseLocation(sourceFile, null, null, null), new ParseLocation(sourceFile, null, null, null),
@ -46,7 +47,7 @@ export class NgModuleCompiler {
const bootstrapComponentFactories: CompileIdentifierMetadata[] = []; const bootstrapComponentFactories: CompileIdentifierMetadata[] = [];
const entryComponentFactories = const entryComponentFactories =
ngModuleMeta.transitiveModule.entryComponents.map((entryComponent) => { ngModuleMeta.transitiveModule.entryComponents.map((entryComponent) => {
const id = new CompileIdentifierMetadata({name: entryComponent.name}); const id = new CompileIdentifierMetadata();
if (ngModuleMeta.bootstrapComponents.indexOf(entryComponent) > -1) { if (ngModuleMeta.bootstrapComponents.indexOf(entryComponent) > -1) {
bootstrapComponentFactories.push(id); bootstrapComponentFactories.push(id);
} }
@ -59,21 +60,21 @@ export class NgModuleCompiler {
const providerParser = new NgModuleProviderAnalyzer(ngModuleMeta, extraProviders, sourceSpan); const providerParser = new NgModuleProviderAnalyzer(ngModuleMeta, extraProviders, sourceSpan);
providerParser.parse().forEach((provider) => builder.addProvider(provider)); providerParser.parse().forEach((provider) => builder.addProvider(provider));
const injectorClass = builder.build(); const injectorClass = builder.build();
const ngModuleFactoryVar = `${ngModuleMeta.type.name}NgFactory`; const ngModuleFactoryVar = `${identifierName(ngModuleMeta.type)}NgFactory`;
const ngModuleFactoryStmt = const ngModuleFactoryStmt =
o.variable(ngModuleFactoryVar) o.variable(ngModuleFactoryVar)
.set(o.importExpr(resolveIdentifier(Identifiers.NgModuleFactory)) .set(o.importExpr(createIdentifier(Identifiers.NgModuleFactory))
.instantiate( .instantiate(
[o.variable(injectorClass.name), o.importExpr(ngModuleMeta.type)], [o.variable(injectorClass.name), o.importExpr(ngModuleMeta.type)],
o.importType( o.importType(
resolveIdentifier(Identifiers.NgModuleFactory), createIdentifier(Identifiers.NgModuleFactory),
[o.importType(ngModuleMeta.type)], [o.TypeModifier.Const]))) [o.importType(ngModuleMeta.type)], [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]); .toDeclStmt(null, [o.StmtModifier.Final]);
const stmts: o.Statement[] = [injectorClass, ngModuleFactoryStmt]; const stmts: o.Statement[] = [injectorClass, ngModuleFactoryStmt];
if (ngModuleMeta.id) { if (ngModuleMeta.id) {
const registerFactoryStmt = const registerFactoryStmt =
o.importExpr(resolveIdentifier(Identifiers.RegisterModuleFactoryFn)) o.importExpr(createIdentifier(Identifiers.RegisterModuleFactoryFn))
.callFn([o.literal(ngModuleMeta.id), o.variable(ngModuleFactoryVar)]) .callFn([o.literal(ngModuleMeta.id), o.variable(ngModuleFactoryVar)])
.toStmt(); .toStmt();
stmts.push(registerFactoryStmt); stmts.push(registerFactoryStmt);
@ -102,7 +103,7 @@ class _InjectorBuilder implements ClassBuilder {
addProvider(resolvedProvider: ProviderAst) { addProvider(resolvedProvider: ProviderAst) {
const providerValueExpressions = const providerValueExpressions =
resolvedProvider.providers.map((provider) => this._getProviderValue(provider)); resolvedProvider.providers.map((provider) => this._getProviderValue(provider));
const propName = `_${resolvedProvider.token.name}_${this._instances.size}`; const propName = `_${tokenName(resolvedProvider.token)}_${this._instances.size}`;
const instance = this._createProviderProperty( const instance = this._createProviderProperty(
propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider, propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider,
resolvedProvider.eager); resolvedProvider.eager);
@ -110,12 +111,12 @@ class _InjectorBuilder implements ClassBuilder {
this._destroyStmts.push(instance.callMethod('ngOnDestroy', []).toStmt()); this._destroyStmts.push(instance.callMethod('ngOnDestroy', []).toStmt());
} }
this._tokens.push(resolvedProvider.token); this._tokens.push(resolvedProvider.token);
this._instances.set(resolvedProvider.token.reference, instance); this._instances.set(tokenReference(resolvedProvider.token), instance);
} }
build(): o.ClassStmt { build(): o.ClassStmt {
const getMethodStmts: o.Statement[] = this._tokens.map((token) => { const getMethodStmts: o.Statement[] = this._tokens.map((token) => {
const providerExpr = this._instances.get(token.reference); const providerExpr = this._instances.get(tokenReference(token));
return new o.IfStmt( return new o.IfStmt(
InjectMethodVars.token.identical(createDiTokenExpression(token)), InjectMethodVars.token.identical(createDiTokenExpression(token)),
[new o.ReturnStatement(providerExpr)]); [new o.ReturnStatement(providerExpr)]);
@ -143,13 +144,13 @@ class _InjectorBuilder implements ClassBuilder {
o.literalArr(this._bootstrapComponentFactories.map( o.literalArr(this._bootstrapComponentFactories.map(
(componentFactory) => o.importExpr(componentFactory))) (componentFactory) => o.importExpr(componentFactory)))
]; ];
const injClassName = `${this._ngModuleMeta.type.name}Injector`; const injClassName = `${identifierName(this._ngModuleMeta.type)}Injector`;
return createClassStmt({ return createClassStmt({
name: injClassName, name: injClassName,
ctorParams: [new o.FnParam( ctorParams: [new o.FnParam(
InjectorProps.parent.name, o.importType(resolveIdentifier(Identifiers.Injector)))], InjectorProps.parent.name, o.importType(createIdentifier(Identifiers.Injector)))],
parent: o.importExpr( parent: o.importExpr(
resolveIdentifier(Identifiers.NgModuleInjector), [o.importType(this._ngModuleMeta.type)]), createIdentifier(Identifiers.NgModuleInjector), [o.importType(this._ngModuleMeta.type)]),
parentArgs: parentArgs, parentArgs: parentArgs,
builders: [{methods}, this] builders: [{methods}, this]
}); });
@ -215,13 +216,12 @@ class _InjectorBuilder implements ClassBuilder {
} }
if (!dep.isSkipSelf) { if (!dep.isSkipSelf) {
if (dep.token && if (dep.token &&
(dep.token.reference === resolveIdentifierToken(Identifiers.Injector).reference || (tokenReference(dep.token) === resolveIdentifier(Identifiers.Injector) ||
dep.token.reference === tokenReference(dep.token) === resolveIdentifier(Identifiers.ComponentFactoryResolver))) {
resolveIdentifierToken(Identifiers.ComponentFactoryResolver).reference)) {
result = o.THIS_EXPR; result = o.THIS_EXPR;
} }
if (!result) { if (!result) {
result = this._instances.get(dep.token.reference); result = this._instances.get(tokenReference(dep.token));
} }
} }
if (!result) { if (!result) {

View File

@ -7,6 +7,7 @@
*/ */
import {identifierModuleUrl, identifierName} from '../compile_metadata';
import {isBlank, isPresent} from '../facade/lang'; import {isBlank, isPresent} from '../facade/lang';
import {EmitterVisitorContext, OutputEmitter} from './abstract_emitter'; import {EmitterVisitorContext, OutputEmitter} from './abstract_emitter';
@ -38,18 +39,21 @@ class JsEmitterVisitor extends AbstractJsEmitterVisitor {
constructor(private _moduleUrl: string) { super(); } constructor(private _moduleUrl: string) { super(); }
visitExternalExpr(ast: o.ExternalExpr, ctx: EmitterVisitorContext): any { visitExternalExpr(ast: o.ExternalExpr, ctx: EmitterVisitorContext): any {
if (isBlank(ast.value.name)) { const name = identifierName(ast.value);
const moduleUrl = identifierModuleUrl(ast.value);
if (isBlank(name)) {
console.error('>>>', ast.value);
throw new Error(`Internal error: unknown identifier ${ast.value}`); throw new Error(`Internal error: unknown identifier ${ast.value}`);
} }
if (isPresent(ast.value.moduleUrl) && ast.value.moduleUrl != this._moduleUrl) { if (isPresent(moduleUrl) && moduleUrl != this._moduleUrl) {
let prefix = this.importsWithPrefixes.get(ast.value.moduleUrl); let prefix = this.importsWithPrefixes.get(moduleUrl);
if (isBlank(prefix)) { if (isBlank(prefix)) {
prefix = `import${this.importsWithPrefixes.size}`; prefix = `import${this.importsWithPrefixes.size}`;
this.importsWithPrefixes.set(ast.value.moduleUrl, prefix); this.importsWithPrefixes.set(moduleUrl, prefix);
} }
ctx.print(`${prefix}.`); ctx.print(`${prefix}.`);
} }
ctx.print(ast.value.name); ctx.print(name);
return null; return null;
} }
visitDeclareVarStmt(stmt: o.DeclareVarStmt, ctx: EmitterVisitorContext): any { visitDeclareVarStmt(stmt: o.DeclareVarStmt, ctx: EmitterVisitorContext): any {

View File

@ -43,14 +43,14 @@ export class BuiltinType extends Type {
} }
} }
export class ExternalType extends Type { export class ExpressionType extends Type {
constructor( constructor(
public value: CompileIdentifierMetadata, public typeParams: Type[] = null, public value: Expression, public typeParams: Type[] = null,
modifiers: TypeModifier[] = null) { modifiers: TypeModifier[] = null) {
super(modifiers); super(modifiers);
} }
visitType(visitor: TypeVisitor, context: any): any { visitType(visitor: TypeVisitor, context: any): any {
return visitor.visitExternalType(this, context); return visitor.visitExpressionType(this, context);
} }
} }
@ -78,7 +78,7 @@ export var NULL_TYPE = new BuiltinType(BuiltinTypeName.Null);
export interface TypeVisitor { export interface TypeVisitor {
visitBuiltintType(type: BuiltinType, context: any): any; visitBuiltintType(type: BuiltinType, context: any): any;
visitExternalType(type: ExternalType, context: any): any; visitExpressionType(type: ExpressionType, context: any): any;
visitArrayType(type: ArrayType, context: any): any; visitArrayType(type: ArrayType, context: any): any;
visitMapType(type: MapType, context: any): any; visitMapType(type: MapType, context: any): any;
} }
@ -876,8 +876,14 @@ export function importExpr(id: CompileIdentifierMetadata, typeParams: Type[] = n
export function importType( export function importType(
id: CompileIdentifierMetadata, typeParams: Type[] = null, id: CompileIdentifierMetadata, typeParams: Type[] = null,
typeModifiers: TypeModifier[] = null): ExternalType { typeModifiers: TypeModifier[] = null): ExpressionType {
return isPresent(id) ? new ExternalType(id, typeParams, typeModifiers) : null; return isPresent(id) ? expressionType(importExpr(id), typeParams, typeModifiers) : null;
}
export function expressionType(
expr: Expression, typeParams: Type[] = null,
typeModifiers: TypeModifier[] = null): ExpressionType {
return isPresent(expr) ? new ExpressionType(expr, typeParams, typeModifiers) : null;
} }
export function literalArr(values: Expression[], type: Type = null): LiteralArrayExpr { export function literalArr(values: Expression[], type: Type = null): LiteralArrayExpr {

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {identifierName} from '../compile_metadata';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {sanitizeIdentifier} from '../util';
import {EmitterVisitorContext} from './abstract_emitter'; import {EmitterVisitorContext} from './abstract_emitter';
import {AbstractJsEmitterVisitor} from './abstract_js_emitter'; import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
@ -52,8 +52,8 @@ class JitEmitterVisitor extends AbstractJsEmitterVisitor {
if (id === -1) { if (id === -1) {
id = this._evalArgValues.length; id = this._evalArgValues.length;
this._evalArgValues.push(value); this._evalArgValues.push(value);
const name = isPresent(ast.value.name) ? sanitizeIdentifier(ast.value.name) : 'val'; const name = identifierName(ast.value) || 'val';
this._evalArgNames.push(sanitizeIdentifier(`jit_${name}${id}`)); this._evalArgNames.push(`jit_${name}${id}`);
} }
ctx.print(this._evalArgNames[id]); ctx.print(this._evalArgNames[id]);
return null; return null;

View File

@ -7,7 +7,7 @@
*/ */
import {CompileIdentifierMetadata} from '../compile_metadata'; import {CompileIdentifierMetadata, identifierModuleUrl, identifierName} from '../compile_metadata';
import {isBlank, isPresent} from '../facade/lang'; import {isBlank, isPresent} from '../facade/lang';
import {AbstractEmitterVisitor, CATCH_ERROR_VAR, CATCH_STACK_VAR, EmitterVisitorContext, OutputEmitter} from './abstract_emitter'; import {AbstractEmitterVisitor, CATCH_ERROR_VAR, CATCH_STACK_VAR, EmitterVisitorContext, OutputEmitter} from './abstract_emitter';
@ -271,8 +271,13 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
return null; return null;
} }
visitExternalType(ast: o.ExternalType, ctx: EmitterVisitorContext): any { visitExpressionType(ast: o.ExpressionType, ctx: EmitterVisitorContext): any {
this._visitIdentifier(ast.value, ast.typeParams, ctx); ast.value.visitExpression(this, ctx);
if (isPresent(ast.typeParams) && ast.typeParams.length > 0) {
ctx.print(`<`);
this.visitAllObjects(type => type.visitType(this, ctx), ast.typeParams, ctx, ',');
ctx.print(`>`);
}
return null; return null;
} }
@ -317,14 +322,16 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
private _visitIdentifier( private _visitIdentifier(
value: CompileIdentifierMetadata, typeParams: o.Type[], ctx: EmitterVisitorContext): void { value: CompileIdentifierMetadata, typeParams: o.Type[], ctx: EmitterVisitorContext): void {
if (isBlank(value.name)) { const name = identifierName(value);
const moduleUrl = identifierModuleUrl(value);
if (isBlank(name)) {
throw new Error(`Internal error: unknown identifier ${value}`); throw new Error(`Internal error: unknown identifier ${value}`);
} }
if (isPresent(value.moduleUrl) && value.moduleUrl != this._moduleUrl) { if (isPresent(moduleUrl) && moduleUrl != this._moduleUrl) {
let prefix = this.importsWithPrefixes.get(value.moduleUrl); let prefix = this.importsWithPrefixes.get(moduleUrl);
if (isBlank(prefix)) { if (isBlank(prefix)) {
prefix = `import${this.importsWithPrefixes.size}`; prefix = `import${this.importsWithPrefixes.size}`;
this.importsWithPrefixes.set(value.moduleUrl, prefix); this.importsWithPrefixes.set(moduleUrl, prefix);
} }
ctx.print(`${prefix}.`); ctx.print(`${prefix}.`);
} }
@ -333,7 +340,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
ctx.print('.'); ctx.print('.');
ctx.print(value.reference.members.join('.')); ctx.print(value.reference.members.join('.'));
} else { } else {
ctx.print(value.name); ctx.print(name);
} }
if (isPresent(typeParams) && typeParams.length > 0) { if (isPresent(typeParams) && typeParams.length > 0) {
ctx.print(`<`); ctx.print(`<`);

View File

@ -7,9 +7,9 @@
*/ */
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompileNgModuleMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata} from './compile_metadata'; import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompileNgModuleMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata, tokenName, tokenReference} from './compile_metadata';
import {isBlank, isPresent} from './facade/lang'; import {isBlank, isPresent} from './facade/lang';
import {Identifiers, resolveIdentifierToken} from './identifiers'; import {Identifiers, createIdentifierToken, resolveIdentifier} from './identifiers';
import {ParseError, ParseSourceSpan} from './parse_util'; import {ParseError, ParseSourceSpan} from './parse_util';
import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst} from './template_parser/template_ast'; import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst} from './template_parser/template_ast';
@ -32,8 +32,8 @@ export class ProviderViewContext {
this.viewQueries = _getViewQueries(component); this.viewQueries = _getViewQueries(component);
this.viewProviders = new Map<any, boolean>(); this.viewProviders = new Map<any, boolean>();
_normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => { _normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => {
if (isBlank(this.viewProviders.get(provider.token.reference))) { if (isBlank(this.viewProviders.get(tokenReference(provider.token)))) {
this.viewProviders.set(provider.token.reference, true); this.viewProviders.set(tokenReference(provider.token), true);
} }
}); });
} }
@ -65,14 +65,13 @@ export class ProviderElementContext {
refs.forEach((refAst) => { refs.forEach((refAst) => {
this._addQueryReadsTo(new CompileTokenMetadata({value: refAst.name}), queriedTokens); this._addQueryReadsTo(new CompileTokenMetadata({value: refAst.name}), queriedTokens);
}); });
if (isPresent( if (isPresent(queriedTokens.get(resolveIdentifier(Identifiers.ViewContainerRef)))) {
queriedTokens.get(resolveIdentifierToken(Identifiers.ViewContainerRef).reference))) {
this._hasViewContainer = true; this._hasViewContainer = true;
} }
// create the providers that we know are eager first // create the providers that we know are eager first
Array.from(this._allProviders.values()).forEach((provider) => { Array.from(this._allProviders.values()).forEach((provider) => {
const eager = provider.eager || isPresent(queriedTokens.get(provider.token.reference)); const eager = provider.eager || isPresent(queriedTokens.get(tokenReference(provider.token)));
if (eager) { if (eager) {
this._getOrCreateLocalProvider(provider.providerType, provider.token, true); this._getOrCreateLocalProvider(provider.providerType, provider.token, true);
} }
@ -104,8 +103,8 @@ export class ProviderElementContext {
private _addQueryReadsTo(token: CompileTokenMetadata, queryReadTokens: Map<any, boolean>) { private _addQueryReadsTo(token: CompileTokenMetadata, queryReadTokens: Map<any, boolean>) {
this._getQueriesFor(token).forEach((query) => { this._getQueriesFor(token).forEach((query) => {
const queryReadToken = query.read || token; const queryReadToken = query.read || token;
if (isBlank(queryReadTokens.get(queryReadToken.reference))) { if (isBlank(queryReadTokens.get(tokenReference(queryReadToken)))) {
queryReadTokens.set(queryReadToken.reference, true); queryReadTokens.set(tokenReference(queryReadToken), true);
} }
}); });
} }
@ -116,7 +115,7 @@ export class ProviderElementContext {
let distance = 0; let distance = 0;
let queries: CompileQueryMetadata[]; let queries: CompileQueryMetadata[];
while (currentEl !== null) { while (currentEl !== null) {
queries = currentEl._contentQueries.get(token.reference); queries = currentEl._contentQueries.get(tokenReference(token));
if (isPresent(queries)) { if (isPresent(queries)) {
result.push(...queries.filter((query) => query.descendants || distance <= 1)); result.push(...queries.filter((query) => query.descendants || distance <= 1));
} }
@ -125,7 +124,7 @@ export class ProviderElementContext {
} }
currentEl = currentEl._parent; currentEl = currentEl._parent;
} }
queries = this.viewContext.viewQueries.get(token.reference); queries = this.viewContext.viewQueries.get(tokenReference(token));
if (isPresent(queries)) { if (isPresent(queries)) {
result.push(...queries); result.push(...queries);
} }
@ -136,7 +135,7 @@ export class ProviderElementContext {
private _getOrCreateLocalProvider( private _getOrCreateLocalProvider(
requestingProviderType: ProviderAstType, token: CompileTokenMetadata, requestingProviderType: ProviderAstType, token: CompileTokenMetadata,
eager: boolean): ProviderAst { eager: boolean): ProviderAst {
const resolvedProvider = this._allProviders.get(token.reference); const resolvedProvider = this._allProviders.get(tokenReference(token));
if (!resolvedProvider || ((requestingProviderType === ProviderAstType.Directive || if (!resolvedProvider || ((requestingProviderType === ProviderAstType.Directive ||
requestingProviderType === ProviderAstType.PublicService) && requestingProviderType === ProviderAstType.PublicService) &&
resolvedProvider.providerType === ProviderAstType.PrivateService) || resolvedProvider.providerType === ProviderAstType.PrivateService) ||
@ -145,16 +144,16 @@ export class ProviderElementContext {
resolvedProvider.providerType === ProviderAstType.Builtin)) { resolvedProvider.providerType === ProviderAstType.Builtin)) {
return null; return null;
} }
let transformedProviderAst = this._transformedProviders.get(token.reference); let transformedProviderAst = this._transformedProviders.get(tokenReference(token));
if (isPresent(transformedProviderAst)) { if (isPresent(transformedProviderAst)) {
return transformedProviderAst; return transformedProviderAst;
} }
if (isPresent(this._seenProviders.get(token.reference))) { if (isPresent(this._seenProviders.get(tokenReference(token)))) {
this.viewContext.errors.push(new ProviderError( this.viewContext.errors.push(new ProviderError(
`Cannot instantiate cyclic dependency! ${token.name}`, this._sourceSpan)); `Cannot instantiate cyclic dependency! ${tokenName(token)}`, this._sourceSpan));
return null; return null;
} }
this._seenProviders.set(token.reference, true); this._seenProviders.set(tokenReference(token), true);
const transformedProviders = resolvedProvider.providers.map((provider) => { const transformedProviders = resolvedProvider.providers.map((provider) => {
let transformedUseValue = provider.useValue; let transformedUseValue = provider.useValue;
let transformedUseExisting = provider.useExisting; let transformedUseExisting = provider.useExisting;
@ -186,7 +185,7 @@ export class ProviderElementContext {
}); });
transformedProviderAst = transformedProviderAst =
_transformProviderAst(resolvedProvider, {eager: eager, providers: transformedProviders}); _transformProviderAst(resolvedProvider, {eager: eager, providers: transformedProviders});
this._transformedProviders.set(token.reference, transformedProviderAst); this._transformedProviders.set(tokenReference(token), transformedProviderAst);
return transformedProviderAst; return transformedProviderAst;
} }
@ -203,20 +202,18 @@ export class ProviderElementContext {
// access builtints // access builtints
if ((requestingProviderType === ProviderAstType.Directive || if ((requestingProviderType === ProviderAstType.Directive ||
requestingProviderType === ProviderAstType.Component)) { requestingProviderType === ProviderAstType.Component)) {
if (dep.token.reference === resolveIdentifierToken(Identifiers.Renderer).reference || if (tokenReference(dep.token) === resolveIdentifier(Identifiers.Renderer) ||
dep.token.reference === resolveIdentifierToken(Identifiers.ElementRef).reference || tokenReference(dep.token) === resolveIdentifier(Identifiers.ElementRef) ||
dep.token.reference === tokenReference(dep.token) === resolveIdentifier(Identifiers.ChangeDetectorRef) ||
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference || tokenReference(dep.token) === resolveIdentifier(Identifiers.TemplateRef)) {
dep.token.reference === resolveIdentifierToken(Identifiers.TemplateRef).reference) {
return dep; return dep;
} }
if (dep.token.reference === if (tokenReference(dep.token) === resolveIdentifier(Identifiers.ViewContainerRef)) {
resolveIdentifierToken(Identifiers.ViewContainerRef).reference) {
this._hasViewContainer = true; this._hasViewContainer = true;
} }
} }
// access the injector // access the injector
if (dep.token.reference === resolveIdentifierToken(Identifiers.Injector).reference) { if (tokenReference(dep.token) === resolveIdentifier(Identifiers.Injector)) {
return dep; return dep;
} }
// access providers // access providers
@ -252,9 +249,9 @@ export class ProviderElementContext {
} }
// check @Host restriction // check @Host restriction
if (!result) { if (!result) {
if (!dep.isHost || this.viewContext.component.type.isHost || if (!dep.isHost || this.viewContext.component.isHost ||
this.viewContext.component.type.reference === dep.token.reference || this.viewContext.component.type.reference === tokenReference(dep.token) ||
isPresent(this.viewContext.viewProviders.get(dep.token.reference))) { isPresent(this.viewContext.viewProviders.get(tokenReference(dep.token)))) {
result = dep; result = dep;
} else { } else {
result = dep.isOptional ? result = dep.isOptional ?
@ -265,7 +262,7 @@ export class ProviderElementContext {
} }
if (!result) { if (!result) {
this.viewContext.errors.push( this.viewContext.errors.push(
new ProviderError(`No provider for ${dep.token.name}`, this._sourceSpan)); new ProviderError(`No provider for ${tokenName(dep.token)}`, this._sourceSpan));
} }
return result; return result;
} }
@ -308,20 +305,21 @@ export class NgModuleProviderAnalyzer {
} }
private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst { private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst {
const resolvedProvider = this._allProviders.get(token.reference); const resolvedProvider = this._allProviders.get(tokenReference(token));
if (!resolvedProvider) { if (!resolvedProvider) {
return null; return null;
} }
let transformedProviderAst = this._transformedProviders.get(token.reference); let transformedProviderAst = this._transformedProviders.get(tokenReference(token));
if (isPresent(transformedProviderAst)) { if (isPresent(transformedProviderAst)) {
return transformedProviderAst; return transformedProviderAst;
} }
if (isPresent(this._seenProviders.get(token.reference))) { if (isPresent(this._seenProviders.get(tokenReference(token)))) {
this._errors.push(new ProviderError( this._errors.push(new ProviderError(
`Cannot instantiate cyclic dependency! ${token.name}`, resolvedProvider.sourceSpan)); `Cannot instantiate cyclic dependency! ${tokenName(token)}`,
resolvedProvider.sourceSpan));
return null; return null;
} }
this._seenProviders.set(token.reference, true); this._seenProviders.set(tokenReference(token), true);
const transformedProviders = resolvedProvider.providers.map((provider) => { const transformedProviders = resolvedProvider.providers.map((provider) => {
let transformedUseValue = provider.useValue; let transformedUseValue = provider.useValue;
let transformedUseExisting = provider.useExisting; let transformedUseExisting = provider.useExisting;
@ -353,7 +351,7 @@ export class NgModuleProviderAnalyzer {
}); });
transformedProviderAst = transformedProviderAst =
_transformProviderAst(resolvedProvider, {eager: eager, providers: transformedProviders}); _transformProviderAst(resolvedProvider, {eager: eager, providers: transformedProviders});
this._transformedProviders.set(token.reference, transformedProviderAst); this._transformedProviders.set(tokenReference(token), transformedProviderAst);
return transformedProviderAst; return transformedProviderAst;
} }
@ -363,9 +361,8 @@ export class NgModuleProviderAnalyzer {
let foundLocal = false; let foundLocal = false;
if (!dep.isSkipSelf && isPresent(dep.token)) { if (!dep.isSkipSelf && isPresent(dep.token)) {
// access the injector // access the injector
if (dep.token.reference === resolveIdentifierToken(Identifiers.Injector).reference || if (tokenReference(dep.token) === resolveIdentifier(Identifiers.Injector) ||
dep.token.reference === tokenReference(dep.token) === resolveIdentifier(Identifiers.ComponentFactoryResolver)) {
resolveIdentifierToken(Identifiers.ComponentFactoryResolver).reference) {
foundLocal = true; foundLocal = true;
// access providers // access providers
} else if (isPresent(this._getOrCreateLocalProvider(dep.token, eager))) { } else if (isPresent(this._getOrCreateLocalProvider(dep.token, eager))) {
@ -378,7 +375,7 @@ export class NgModuleProviderAnalyzer {
result = new CompileDiDependencyMetadata({isValue: true, value: null}); result = new CompileDiDependencyMetadata({isValue: true, value: null});
} else { } else {
this._errors.push( this._errors.push(
new ProviderError(`No provider for ${dep.token.name}`, requestorSourceSpan)); new ProviderError(`No provider for ${tokenName(dep.token)}`, requestorSourceSpan));
} }
} }
return result; return result;
@ -471,10 +468,10 @@ function _resolveProviders(
sourceSpan: ParseSourceSpan, targetErrors: ParseError[], sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
targetProvidersByToken: Map<any, ProviderAst>) { targetProvidersByToken: Map<any, ProviderAst>) {
providers.forEach((provider) => { providers.forEach((provider) => {
let resolvedProvider = targetProvidersByToken.get(provider.token.reference); let resolvedProvider = targetProvidersByToken.get(tokenReference(provider.token));
if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) { if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) {
targetErrors.push(new ProviderError( targetErrors.push(new ProviderError(
`Mixing multi and non multi provider is not possible for token ${resolvedProvider.token.name}`, `Mixing multi and non multi provider is not possible for token ${tokenName(resolvedProvider.token)}`,
sourceSpan)); sourceSpan));
} }
if (!resolvedProvider) { if (!resolvedProvider) {
@ -485,7 +482,7 @@ function _resolveProviders(
resolvedProvider = new ProviderAst( resolvedProvider = new ProviderAst(
provider.token, provider.multi, eager || lifecycleHooks.length > 0, [provider], provider.token, provider.multi, eager || lifecycleHooks.length > 0, [provider],
providerType, lifecycleHooks, sourceSpan); providerType, lifecycleHooks, sourceSpan);
targetProvidersByToken.set(provider.token.reference, resolvedProvider); targetProvidersByToken.set(tokenReference(provider.token), resolvedProvider);
} else { } else {
if (!provider.multi) { if (!provider.multi) {
resolvedProvider.providers.length = 0; resolvedProvider.providers.length = 0;
@ -517,10 +514,10 @@ function _getContentQueries(directives: CompileDirectiveSummary[]):
function _addQueryToTokenMap(map: Map<any, CompileQueryMetadata[]>, query: CompileQueryMetadata) { function _addQueryToTokenMap(map: Map<any, CompileQueryMetadata[]>, query: CompileQueryMetadata) {
query.selectors.forEach((token: CompileTokenMetadata) => { query.selectors.forEach((token: CompileTokenMetadata) => {
let entry = map.get(token.reference); let entry = map.get(tokenReference(token));
if (!entry) { if (!entry) {
entry = []; entry = [];
map.set(token.reference, entry); map.set(tokenReference(token), entry);
} }
entry.push(query); entry.push(query);
}); });

View File

@ -7,7 +7,8 @@
*/ */
import {Injectable, ViewEncapsulation} from '@angular/core'; import {Injectable, ViewEncapsulation} from '@angular/core';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileStylesheetMetadata} from './compile_metadata';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileStylesheetMetadata, identifierModuleUrl, identifierName} from './compile_metadata';
import * as o from './output/output_ast'; import * as o from './output/output_ast';
import {ShadowCss} from './shadow_css'; import {ShadowCss} from './shadow_css';
import {UrlResolver} from './url_resolver'; import {UrlResolver} from './url_resolver';
@ -18,7 +19,7 @@ const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
export class StylesCompileDependency { export class StylesCompileDependency {
constructor( constructor(
public moduleUrl: string, public isShimmed: boolean, public name: string, public moduleUrl: string, public isShimmed: boolean,
public valuePlaceholder: CompileIdentifierMetadata) {} public valuePlaceholder: CompileIdentifierMetadata) {}
} }
@ -47,7 +48,7 @@ export class StyleCompiler {
comp, new CompileStylesheetMetadata({ comp, new CompileStylesheetMetadata({
styles: comp.template.styles, styles: comp.template.styles,
styleUrls: comp.template.styleUrls, styleUrls: comp.template.styleUrls,
moduleUrl: comp.type.moduleUrl moduleUrl: identifierModuleUrl(comp.type)
}), }),
true); true);
comp.template.externalStylesheets.forEach((stylesheetMeta) => { comp.template.externalStylesheets.forEach((stylesheetMeta) => {
@ -65,8 +66,9 @@ export class StyleCompiler {
stylesheet.styles.map(plainStyle => o.literal(this._shimIfNeeded(plainStyle, shim))); stylesheet.styles.map(plainStyle => o.literal(this._shimIfNeeded(plainStyle, shim)));
const dependencies: StylesCompileDependency[] = []; const dependencies: StylesCompileDependency[] = [];
for (let i = 0; i < stylesheet.styleUrls.length; i++) { for (let i = 0; i < stylesheet.styleUrls.length; i++) {
const identifier = new CompileIdentifierMetadata({name: getStylesVarName(null)}); const identifier = new CompileIdentifierMetadata();
dependencies.push(new StylesCompileDependency(stylesheet.styleUrls[i], shim, identifier)); dependencies.push(new StylesCompileDependency(
getStylesVarName(null), stylesheet.styleUrls[i], shim, identifier));
styleExpressions.push(new o.ExternalExpr(identifier)); styleExpressions.push(new o.ExternalExpr(identifier));
} }
// styles variable contains plain strings and arrays of other styles arrays (recursive), // styles variable contains plain strings and arrays of other styles arrays (recursive),
@ -87,7 +89,7 @@ export class StyleCompiler {
function getStylesVarName(component: CompileDirectiveMetadata): string { function getStylesVarName(component: CompileDirectiveMetadata): string {
let result = `styles`; let result = `styles`;
if (component) { if (component) {
result += `_${component.type.name}`; result += `_${identifierName(component.type)}`;
} }
return result; return result;
} }

View File

@ -8,12 +8,12 @@
import {Inject, Injectable, OpaqueToken, Optional, SchemaMetadata, SecurityContext} from '@angular/core'; import {Inject, Injectable, OpaqueToken, Optional, SchemaMetadata, SecurityContext} from '@angular/core';
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileTemplateMetadata, CompileTemplateSummary, CompileTokenMetadata, CompileTypeMetadata, removeIdentifierDuplicates} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileTemplateMetadata, CompileTemplateSummary, CompileTokenMetadata, CompileTypeMetadata, identifierName} from '../compile_metadata';
import {AST, ASTWithSource, BindingPipe, EmptyExpr, Interpolation, ParserError, RecursiveAstVisitor, TemplateBinding} from '../expression_parser/ast'; import {AST, ASTWithSource, BindingPipe, EmptyExpr, Interpolation, ParserError, RecursiveAstVisitor, TemplateBinding} from '../expression_parser/ast';
import {Parser} from '../expression_parser/parser'; import {Parser} from '../expression_parser/parser';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {I18NHtmlParser} from '../i18n/i18n_html_parser'; import {I18NHtmlParser} from '../i18n/i18n_html_parser';
import {Identifiers, identifierToken, resolveIdentifierToken} from '../identifiers'; import {Identifiers, createIdentifierToken, identifierToken} from '../identifiers';
import * as html from '../ml_parser/ast'; import * as html from '../ml_parser/ast';
import {ParseTreeResult} from '../ml_parser/html_parser'; import {ParseTreeResult} from '../ml_parser/html_parser';
import {expandNodes} from '../ml_parser/icu_ast_expander'; import {expandNodes} from '../ml_parser/icu_ast_expander';
@ -546,7 +546,8 @@ class TemplateParseVisitor implements html.Visitor {
let component: CompileDirectiveSummary = null; let component: CompileDirectiveSummary = null;
const directiveAsts = directives.map((directive) => { const directiveAsts = directives.map((directive) => {
const sourceSpan = new ParseSourceSpan( const sourceSpan = new ParseSourceSpan(
elementSourceSpan.start, elementSourceSpan.end, `Directive ${directive.type.name}`); elementSourceSpan.start, elementSourceSpan.end,
`Directive ${identifierName(directive.type)}`);
if (directive.isComponent) { if (directive.isComponent) {
component = directive; component = directive;
} }
@ -579,7 +580,7 @@ class TemplateParseVisitor implements html.Visitor {
} else if (!component) { } else if (!component) {
let refToken: CompileTokenMetadata = null; let refToken: CompileTokenMetadata = null;
if (isTemplateElement) { if (isTemplateElement) {
refToken = resolveIdentifierToken(Identifiers.TemplateRef); refToken = createIdentifierToken(Identifiers.TemplateRef);
} }
targetReferences.push(new ReferenceAst(elOrDirRef.name, refToken, elOrDirRef.sourceSpan)); targetReferences.push(new ReferenceAst(elOrDirRef.name, refToken, elOrDirRef.sourceSpan));
} }
@ -640,7 +641,7 @@ class TemplateParseVisitor implements html.Visitor {
private _findComponentDirectiveNames(directives: DirectiveAst[]): string[] { private _findComponentDirectiveNames(directives: DirectiveAst[]): string[] {
return this._findComponentDirectives(directives) return this._findComponentDirectives(directives)
.map(directive => directive.directive.type.name); .map(directive => identifierName(directive.directive.type));
} }
private _assertOnlyOneComponent(directives: DirectiveAst[], sourceSpan: ParseSourceSpan) { private _assertOnlyOneComponent(directives: DirectiveAst[], sourceSpan: ParseSourceSpan) {

View File

@ -35,10 +35,6 @@ function _splitAt(input: string, character: string, defaultValues: string[]): st
return [input.slice(0, characterIndex).trim(), input.slice(characterIndex + 1).trim()]; return [input.slice(0, characterIndex).trim(), input.slice(characterIndex + 1).trim()];
} }
export function sanitizeIdentifier(name: string): string {
return name.replace(/\W/g, '_');
}
export function visitValue(value: any, visitor: ValueVisitor, context: any): any { export function visitValue(value: any, visitor: ValueVisitor, context: any): any {
if (Array.isArray(value)) { if (Array.isArray(value)) {
return visitor.visitArray(<any[]>value, context); return visitor.visitArray(<any[]>value, context);

View File

@ -7,11 +7,11 @@
*/ */
import {CompileDiDependencyMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata'; import {CompileDiDependencyMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata, identifierName, tokenName, tokenReference} from '../compile_metadata';
import {createDiTokenExpression} from '../compiler_util/identifier_util'; import {createDiTokenExpression} from '../compiler_util/identifier_util';
import {DirectiveWrapperCompiler, DirectiveWrapperExpressions} from '../directive_wrapper_compiler'; import {DirectiveWrapperCompiler, DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, identifierToken, resolveIdentifier, resolveIdentifierToken} from '../identifiers'; import {Identifiers, createIdentifier, createIdentifierToken, identifierToken, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {convertValueToOutputAst} from '../output/value_util'; import {convertValueToOutputAst} from '../output/value_util';
import {ProviderAst, ProviderAstType, ReferenceAst, TemplateAst} from '../template_parser/template_ast'; import {ProviderAst, ProviderAstType, ReferenceAst, TemplateAst} from '../template_parser/template_ast';
@ -20,7 +20,7 @@ import {CompileMethod} from './compile_method';
import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query'; import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query';
import {CompileView, CompileViewRootNode} from './compile_view'; import {CompileView, CompileViewRootNode} from './compile_view';
import {InjectMethodVars, ViewProperties} from './constants'; import {InjectMethodVars, ViewProperties} from './constants';
import {ComponentFactoryDependency, DirectiveWrapperDependency, ViewClassDependency} from './deps'; import {ComponentFactoryDependency, DirectiveWrapperDependency} from './deps';
import {getPropertyInView, injectFromViewParentInjector} from './util'; import {getPropertyInView, injectFromViewParentInjector} from './util';
export class CompileNode { export class CompileNode {
@ -35,7 +35,7 @@ export class CompileNode {
export class CompileElement extends CompileNode { export class CompileElement extends CompileNode {
static createNull(): CompileElement { static createNull(): CompileElement {
return new CompileElement(null, null, null, null, null, null, [], [], false, false, [], []); return new CompileElement(null, null, null, null, null, null, [], [], false, false, []);
} }
public compViewExpr: o.Expression = null; public compViewExpr: o.Expression = null;
@ -57,21 +57,18 @@ export class CompileElement extends CompileNode {
sourceAst: TemplateAst, public component: CompileDirectiveSummary, sourceAst: TemplateAst, public component: CompileDirectiveSummary,
private _directives: CompileDirectiveSummary[], private _directives: CompileDirectiveSummary[],
private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean, private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean,
public hasEmbeddedView: boolean, references: ReferenceAst[], public hasEmbeddedView: boolean, references: ReferenceAst[]) {
private _targetDependencies:
Array<ViewClassDependency|ComponentFactoryDependency|DirectiveWrapperDependency>) {
super(parent, view, nodeIndex, renderNode, sourceAst); super(parent, view, nodeIndex, renderNode, sourceAst);
this.referenceTokens = {}; this.referenceTokens = {};
references.forEach(ref => this.referenceTokens[ref.name] = ref.value); references.forEach(ref => this.referenceTokens[ref.name] = ref.value);
this.elementRef = this.elementRef =
o.importExpr(resolveIdentifier(Identifiers.ElementRef)).instantiate([this.renderNode]); o.importExpr(createIdentifier(Identifiers.ElementRef)).instantiate([this.renderNode]);
this.instances.set(resolveIdentifierToken(Identifiers.ElementRef).reference, this.elementRef); this.instances.set(resolveIdentifier(Identifiers.ElementRef), this.elementRef);
this.instances.set( this.instances.set(
resolveIdentifierToken(Identifiers.Injector).reference, resolveIdentifier(Identifiers.Injector),
o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)])); o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]));
this.instances.set( this.instances.set(resolveIdentifier(Identifiers.Renderer), o.THIS_EXPR.prop('renderer'));
resolveIdentifierToken(Identifiers.Renderer).reference, o.THIS_EXPR.prop('renderer'));
if (this.hasViewContainer || this.hasEmbeddedView) { if (this.hasViewContainer || this.hasEmbeddedView) {
this._createViewContainer(); this._createViewContainer();
} }
@ -85,39 +82,38 @@ export class CompileElement extends CompileNode {
const parentNodeIndex = this.isRootElement() ? null : this.parent.nodeIndex; const parentNodeIndex = this.isRootElement() ? null : this.parent.nodeIndex;
// private is fine here as no child view will reference a ViewContainer // private is fine here as no child view will reference a ViewContainer
this.view.fields.push(new o.ClassField( this.view.fields.push(new o.ClassField(
fieldName, o.importType(resolveIdentifier(Identifiers.ViewContainer)), fieldName, o.importType(createIdentifier(Identifiers.ViewContainer)),
[o.StmtModifier.Private])); [o.StmtModifier.Private]));
const statement = const statement =
o.THIS_EXPR.prop(fieldName) o.THIS_EXPR.prop(fieldName)
.set(o.importExpr(resolveIdentifier(Identifiers.ViewContainer)).instantiate([ .set(o.importExpr(createIdentifier(Identifiers.ViewContainer)).instantiate([
o.literal(this.nodeIndex), o.literal(parentNodeIndex), o.THIS_EXPR, this.renderNode o.literal(this.nodeIndex), o.literal(parentNodeIndex), o.THIS_EXPR, this.renderNode
])) ]))
.toStmt(); .toStmt();
this.view.createMethod.addStmt(statement); this.view.createMethod.addStmt(statement);
this.viewContainer = o.THIS_EXPR.prop(fieldName); this.viewContainer = o.THIS_EXPR.prop(fieldName);
this.instances.set( this.instances.set(resolveIdentifier(Identifiers.ViewContainer), this.viewContainer);
resolveIdentifierToken(Identifiers.ViewContainer).reference, this.viewContainer);
this.view.viewContainers.push(this.viewContainer); this.view.viewContainers.push(this.viewContainer);
} }
private _createComponentFactoryResolver() { private _createComponentFactoryResolver() {
const entryComponents = const entryComponents =
this.component.entryComponents.map((entryComponent: CompileIdentifierMetadata) => { this.component.entryComponents.map((entryComponent: CompileIdentifierMetadata) => {
const id = new CompileIdentifierMetadata({name: entryComponent.name}); const id = new CompileIdentifierMetadata();
this._targetDependencies.push(new ComponentFactoryDependency(entryComponent, id)); this.view.targetDependencies.push(new ComponentFactoryDependency(entryComponent, id));
return id; return id;
}); });
if (!entryComponents || entryComponents.length === 0) { if (!entryComponents || entryComponents.length === 0) {
return; return;
} }
const createComponentFactoryResolverExpr = const createComponentFactoryResolverExpr =
o.importExpr(resolveIdentifier(Identifiers.CodegenComponentFactoryResolver)).instantiate([ o.importExpr(createIdentifier(Identifiers.CodegenComponentFactoryResolver)).instantiate([
o.literalArr(entryComponents.map((entryComponent) => o.importExpr(entryComponent))), o.literalArr(entryComponents.map((entryComponent) => o.importExpr(entryComponent))),
injectFromViewParentInjector( injectFromViewParentInjector(
this.view, resolveIdentifierToken(Identifiers.ComponentFactoryResolver), false) this.view, createIdentifierToken(Identifiers.ComponentFactoryResolver), false)
]); ]);
const provider = new CompileProviderMetadata({ const provider = new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.ComponentFactoryResolver), token: createIdentifierToken(Identifiers.ComponentFactoryResolver),
useValue: createComponentFactoryResolverExpr useValue: createComponentFactoryResolverExpr
}); });
// Add ComponentFactoryResolver as first provider as it does not have deps on other providers // Add ComponentFactoryResolver as first provider as it does not have deps on other providers
@ -141,13 +137,11 @@ export class CompileElement extends CompileNode {
this.embeddedView = embeddedView; this.embeddedView = embeddedView;
if (isPresent(embeddedView)) { if (isPresent(embeddedView)) {
const createTemplateRefExpr = const createTemplateRefExpr =
o.importExpr(resolveIdentifier(Identifiers.TemplateRef_)).instantiate([ o.importExpr(createIdentifier(Identifiers.TemplateRef_)).instantiate([
o.THIS_EXPR, o.literal(this.nodeIndex), this.renderNode o.THIS_EXPR, o.literal(this.nodeIndex), this.renderNode
]); ]);
const provider = new CompileProviderMetadata({ const provider = new CompileProviderMetadata(
token: resolveIdentifierToken(Identifiers.TemplateRef), {token: createIdentifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
useValue: createTemplateRefExpr
});
// Add TemplateRef as first provider as it does not have deps on other providers // Add TemplateRef as first provider as it does not have deps on other providers
this._resolvedProvidersArray.unshift(new ProviderAst( this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.Builtin, [], provider.token, false, true, [provider], ProviderAstType.Builtin, [],
@ -158,13 +152,12 @@ export class CompileElement extends CompileNode {
beforeChildren(): void { beforeChildren(): void {
if (this.hasViewContainer) { if (this.hasViewContainer) {
this.instances.set( this.instances.set(
resolveIdentifierToken(Identifiers.ViewContainerRef).reference, resolveIdentifier(Identifiers.ViewContainerRef), this.viewContainer.prop('vcRef'));
this.viewContainer.prop('vcRef'));
} }
this._resolvedProviders = new Map<any, ProviderAst>(); this._resolvedProviders = new Map<any, ProviderAst>();
this._resolvedProvidersArray.forEach( this._resolvedProvidersArray.forEach(
provider => this._resolvedProviders.set(provider.token.reference, provider)); provider => this._resolvedProviders.set(tokenReference(provider.token), provider));
// create all the provider instances, some in the view constructor, // create all the provider instances, some in the view constructor,
// some as getters. We rely on the fact that they are already sorted topologically. // some as getters. We rely on the fact that they are already sorted topologically.
@ -186,10 +179,10 @@ export class CompileElement extends CompileNode {
const depsExpr = const depsExpr =
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep)); deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep));
if (isDirectiveWrapper) { if (isDirectiveWrapper) {
const directiveWrapperIdentifier = new CompileIdentifierMetadata( const directiveWrapperIdentifier = new CompileIdentifierMetadata();
{name: DirectiveWrapperCompiler.dirWrapperClassName(provider.useClass)}); this.view.targetDependencies.push(new DirectiveWrapperDependency(
this._targetDependencies.push( provider.useClass, DirectiveWrapperCompiler.dirWrapperClassName(provider.useClass),
new DirectiveWrapperDependency(provider.useClass, directiveWrapperIdentifier)); directiveWrapperIdentifier));
return DirectiveWrapperExpressions.create(directiveWrapperIdentifier, depsExpr); return DirectiveWrapperExpressions.create(directiveWrapperIdentifier, depsExpr);
} else { } else {
return o.importExpr(provider.useClass) return o.importExpr(provider.useClass)
@ -199,22 +192,23 @@ export class CompileElement extends CompileNode {
return convertValueToOutputAst(provider.useValue); return convertValueToOutputAst(provider.useValue);
} }
}); });
const propName = `_${resolvedProvider.token.name}_${this.nodeIndex}_${this.instances.size}`; const propName =
`_${tokenName(resolvedProvider.token)}_${this.nodeIndex}_${this.instances.size}`;
const instance = createProviderProperty( const instance = createProviderProperty(
propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider, propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider,
resolvedProvider.eager, this); resolvedProvider.eager, this);
if (isDirectiveWrapper) { if (isDirectiveWrapper) {
this.directiveWrapperInstance.set(resolvedProvider.token.reference, instance); this.directiveWrapperInstance.set(tokenReference(resolvedProvider.token), instance);
this.instances.set( this.instances.set(
resolvedProvider.token.reference, DirectiveWrapperExpressions.context(instance)); tokenReference(resolvedProvider.token), DirectiveWrapperExpressions.context(instance));
} else { } else {
this.instances.set(resolvedProvider.token.reference, instance); this.instances.set(tokenReference(resolvedProvider.token), instance);
} }
}); });
for (let i = 0; i < this._directives.length; i++) { for (let i = 0; i < this._directives.length; i++) {
const directive = this._directives[i]; const directive = this._directives[i];
const directiveInstance = this.instances.get(identifierToken(directive.type).reference); const directiveInstance = this.instances.get(tokenReference(identifierToken(directive.type)));
directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); }); directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); });
} }
const queriesWithReads: _QueryWithRead[] = []; const queriesWithReads: _QueryWithRead[] = [];
@ -227,7 +221,7 @@ export class CompileElement extends CompileNode {
const token = this.referenceTokens[varName]; const token = this.referenceTokens[varName];
let varValue: o.Expression; let varValue: o.Expression;
if (token) { if (token) {
varValue = this.instances.get(token.reference); varValue = this.instances.get(tokenReference(token));
} else { } else {
varValue = this.renderNode; varValue = this.renderNode;
} }
@ -240,12 +234,12 @@ export class CompileElement extends CompileNode {
let value: o.Expression; let value: o.Expression;
if (isPresent(queryWithRead.read.identifier)) { if (isPresent(queryWithRead.read.identifier)) {
// query for an identifier // query for an identifier
value = this.instances.get(queryWithRead.read.reference); value = this.instances.get(tokenReference(queryWithRead.read));
} else { } else {
// query for a reference // query for a reference
const token = this.referenceTokens[queryWithRead.read.value]; const token = this.referenceTokens[queryWithRead.read.value];
if (isPresent(token)) { if (isPresent(token)) {
value = this.instances.get(token.reference); value = this.instances.get(tokenReference(token));
} else { } else {
value = this.elementRef; value = this.elementRef;
} }
@ -261,7 +255,7 @@ export class CompileElement extends CompileNode {
// Note: afterChildren is called after recursing into children. // Note: afterChildren is called after recursing into children.
// This is good so that an injector match in an element that is closer to a requesting element // This is good so that an injector match in an element that is closer to a requesting element
// matches first. // matches first.
const providerExpr = this.instances.get(resolvedProvider.token.reference); const providerExpr = this.instances.get(tokenReference(resolvedProvider.token));
// Note: view providers are only visible on the injector of that element. // Note: view providers are only visible on the injector of that element.
// This is not fully correct as the rules during codegen don't allow a directive // This is not fully correct as the rules during codegen don't allow a directive
// to get hold of a view provdier on the same element. We still do this semantic // to get hold of a view provdier on the same element. We still do this semantic
@ -285,7 +279,7 @@ export class CompileElement extends CompileNode {
getComponent(): o.Expression { getComponent(): o.Expression {
return isPresent(this.component) ? return isPresent(this.component) ?
this.instances.get(identifierToken(this.component.type).reference) : this.instances.get(tokenReference(identifierToken(this.component.type))) :
null; null;
} }
@ -300,7 +294,7 @@ export class CompileElement extends CompileNode {
let distance = 0; let distance = 0;
let queries: CompileQuery[]; let queries: CompileQuery[];
while (!currentEl.isNull()) { while (!currentEl.isNull()) {
queries = currentEl._queries.get(token.reference); queries = currentEl._queries.get(tokenReference(token));
if (isPresent(queries)) { if (isPresent(queries)) {
result.push(...queries.filter((query) => query.meta.descendants || distance <= 1)); result.push(...queries.filter((query) => query.meta.descendants || distance <= 1));
} }
@ -309,7 +303,7 @@ export class CompileElement extends CompileNode {
} }
currentEl = currentEl.parent; currentEl = currentEl.parent;
} }
queries = this.view.componentView.viewQueries.get(token.reference); queries = this.view.componentView.viewQueries.get(tokenReference(token));
if (isPresent(queries)) { if (isPresent(queries)) {
result.push(...queries); result.push(...queries);
} }
@ -319,7 +313,7 @@ export class CompileElement extends CompileNode {
private _addQuery(queryMeta: CompileQueryMetadata, directiveInstance: o.Expression): private _addQuery(queryMeta: CompileQueryMetadata, directiveInstance: o.Expression):
CompileQuery { CompileQuery {
const propName = const propName =
`_query_${queryMeta.selectors[0].name}_${this.nodeIndex}_${this._queryCount++}`; `_query_${tokenName(queryMeta.selectors[0])}_${this.nodeIndex}_${this._queryCount++}`;
const queryList = createQueryList(queryMeta, directiveInstance, propName, this.view); const queryList = createQueryList(queryMeta, directiveInstance, propName, this.view);
const query = new CompileQuery(queryMeta, queryList, directiveInstance, this.view); const query = new CompileQuery(queryMeta, queryList, directiveInstance, this.view);
addQueryToTokenMap(this._queries, query); addQueryToTokenMap(this._queries, query);
@ -332,8 +326,7 @@ export class CompileElement extends CompileNode {
if (isPresent(dep.token)) { if (isPresent(dep.token)) {
// access builtins with special visibility // access builtins with special visibility
if (!result) { if (!result) {
if (dep.token.reference === if (tokenReference(dep.token) === resolveIdentifier(Identifiers.ChangeDetectorRef)) {
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
if (requestingProviderType === ProviderAstType.Component) { if (requestingProviderType === ProviderAstType.Component) {
return this.compViewExpr.prop('ref'); return this.compViewExpr.prop('ref');
} else { } else {
@ -343,7 +336,7 @@ export class CompileElement extends CompileNode {
} }
// access regular providers on the element // access regular providers on the element
if (!result) { if (!result) {
const resolvedProvider = this._resolvedProviders.get(dep.token.reference); const resolvedProvider = this._resolvedProviders.get(tokenReference(dep.token));
// don't allow directives / public services to access private services. // don't allow directives / public services to access private services.
// only components and private services can access private services. // only components and private services can access private services.
if (resolvedProvider && (requestingProviderType === ProviderAstType.Directive || if (resolvedProvider && (requestingProviderType === ProviderAstType.Directive ||
@ -351,7 +344,7 @@ export class CompileElement extends CompileNode {
resolvedProvider.providerType === ProviderAstType.PrivateService) { resolvedProvider.providerType === ProviderAstType.PrivateService) {
return null; return null;
} }
result = this.instances.get(dep.token.reference); result = this.instances.get(tokenReference(dep.token));
} }
} }
return result; return result;

View File

@ -7,9 +7,9 @@
*/ */
import {CompilePipeSummary} from '../compile_metadata'; import {CompilePipeSummary, tokenReference} from '../compile_metadata';
import {createPureProxy} from '../compiler_util/identifier_util'; import {createPureProxy} from '../compiler_util/identifier_util';
import {Identifiers, resolveIdentifier, resolveIdentifierToken} from '../identifiers'; import {Identifiers, createIdentifier, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {CompileView} from './compile_view'; import {CompileView} from './compile_view';
@ -42,8 +42,7 @@ export class CompilePipe {
constructor(public view: CompileView, public meta: CompilePipeSummary) { constructor(public view: CompileView, public meta: CompilePipeSummary) {
this.instance = o.THIS_EXPR.prop(`_pipe_${meta.name}_${view.pipeCount++}`); this.instance = o.THIS_EXPR.prop(`_pipe_${meta.name}_${view.pipeCount++}`);
const deps = this.meta.type.diDeps.map((diDep) => { const deps = this.meta.type.diDeps.map((diDep) => {
if (diDep.token.reference === if (tokenReference(diDep.token) === resolveIdentifier(Identifiers.ChangeDetectorRef)) {
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
return getPropertyInView(o.THIS_EXPR.prop('ref'), this.view, this.view.componentView); return getPropertyInView(o.THIS_EXPR.prop('ref'), this.view, this.view.componentView);
} }
return injectFromViewParentInjector(view, diDep.token, false); return injectFromViewParentInjector(view, diDep.token, false);
@ -69,7 +68,7 @@ export class CompilePipe {
.callMethod(o.BuiltinMethod.Bind, [pipeInstanceSeenFromPureProxy]), .callMethod(o.BuiltinMethod.Bind, [pipeInstanceSeenFromPureProxy]),
args.length, purePipeProxyInstance, args.length, purePipeProxyInstance,
{fields: callingView.fields, ctorStmts: callingView.createMethod}); {fields: callingView.fields, ctorStmts: callingView.createMethod});
return o.importExpr(resolveIdentifier(Identifiers.castByValue)) return o.importExpr(createIdentifier(Identifiers.castByValue))
.callFn([purePipeProxyInstance, pipeInstanceSeenFromPureProxy.prop('transform')]) .callFn([purePipeProxyInstance, pipeInstanceSeenFromPureProxy.prop('transform')])
.callFn(args); .callFn(args);
} else { } else {

View File

@ -6,10 +6,10 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {CompileQueryMetadata} from '../compile_metadata'; import {CompileQueryMetadata, tokenReference} from '../compile_metadata';
import {ListWrapper} from '../facade/collection'; import {ListWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {CompileElement} from './compile_element'; import {CompileElement} from './compile_element';
@ -114,22 +114,22 @@ export function createQueryList(
query: CompileQueryMetadata, directiveInstance: o.Expression, propertyName: string, query: CompileQueryMetadata, directiveInstance: o.Expression, propertyName: string,
compileView: CompileView): o.Expression { compileView: CompileView): o.Expression {
compileView.fields.push(new o.ClassField( compileView.fields.push(new o.ClassField(
propertyName, o.importType(resolveIdentifier(Identifiers.QueryList), [o.DYNAMIC_TYPE]))); propertyName, o.importType(createIdentifier(Identifiers.QueryList), [o.DYNAMIC_TYPE])));
const expr = o.THIS_EXPR.prop(propertyName); const expr = o.THIS_EXPR.prop(propertyName);
compileView.createMethod.addStmt( compileView.createMethod.addStmt(
o.THIS_EXPR.prop(propertyName) o.THIS_EXPR.prop(propertyName)
.set(o.importExpr(resolveIdentifier(Identifiers.QueryList), [o.DYNAMIC_TYPE]) .set(o.importExpr(createIdentifier(Identifiers.QueryList), [o.DYNAMIC_TYPE]).instantiate([
.instantiate([])) ]))
.toStmt()); .toStmt());
return expr; return expr;
} }
export function addQueryToTokenMap(map: Map<any, CompileQuery[]>, query: CompileQuery) { export function addQueryToTokenMap(map: Map<any, CompileQuery[]>, query: CompileQuery) {
query.meta.selectors.forEach((selector) => { query.meta.selectors.forEach((selector) => {
let entry = map.get(selector.reference); let entry = map.get(tokenReference(selector));
if (!entry) { if (!entry) {
entry = []; entry = [];
map.set(selector.reference, entry); map.set(tokenReference(selector), entry);
} }
entry.push(query); entry.push(query);
}); });

View File

@ -7,12 +7,12 @@
*/ */
import {AnimationEntryCompileResult} from '../animation/animation_compiler'; import {AnimationEntryCompileResult} from '../animation/animation_compiler';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeSummary} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeSummary, tokenName} from '../compile_metadata';
import {EventHandlerVars, NameResolver} from '../compiler_util/expression_converter'; import {EventHandlerVars, NameResolver} from '../compiler_util/expression_converter';
import {createPureProxy} from '../compiler_util/identifier_util'; import {createPureProxy} from '../compiler_util/identifier_util';
import {CompilerConfig} from '../config'; import {CompilerConfig} from '../config';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {ViewType} from '../private_import_core'; import {ViewType} from '../private_import_core';
@ -20,6 +20,7 @@ import {CompileElement, CompileNode} from './compile_element';
import {CompileMethod} from './compile_method'; import {CompileMethod} from './compile_method';
import {CompilePipe} from './compile_pipe'; import {CompilePipe} from './compile_pipe';
import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query'; import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query';
import {ComponentFactoryDependency, DirectiveWrapperDependency, ViewClassDependency} from './deps';
import {getPropertyInView, getViewClassName} from './util'; import {getPropertyInView, getViewClassName} from './util';
export enum CompileViewRootNodeType { export enum CompileViewRootNodeType {
@ -84,7 +85,9 @@ export class CompileView implements NameResolver {
public component: CompileDirectiveMetadata, public genConfig: CompilerConfig, public component: CompileDirectiveMetadata, public genConfig: CompilerConfig,
public pipeMetas: CompilePipeSummary[], public styles: o.Expression, public pipeMetas: CompilePipeSummary[], public styles: o.Expression,
public animations: AnimationEntryCompileResult[], public viewIndex: number, public animations: AnimationEntryCompileResult[], public viewIndex: number,
public declarationElement: CompileElement, public templateVariableBindings: string[][]) { public declarationElement: CompileElement, public templateVariableBindings: string[][],
public targetDependencies:
Array<ViewClassDependency|ComponentFactoryDependency|DirectiveWrapperDependency>) {
this.createMethod = new CompileMethod(this); this.createMethod = new CompileMethod(this);
this.animationBindingsMethod = new CompileMethod(this); this.animationBindingsMethod = new CompileMethod(this);
this.injectorGetMethod = new CompileMethod(this); this.injectorGetMethod = new CompileMethod(this);
@ -101,7 +104,7 @@ export class CompileView implements NameResolver {
this.viewType = getViewType(component, viewIndex); this.viewType = getViewType(component, viewIndex);
this.className = getViewClassName(component, viewIndex); this.className = getViewClassName(component, viewIndex);
this.classType = o.importType(new CompileIdentifierMetadata({name: this.className})); this.classType = o.expressionType(o.variable(this.className));
this.classExpr = o.variable(this.className); this.classExpr = o.variable(this.className);
if (this.viewType === ViewType.COMPONENT || this.viewType === ViewType.HOST) { if (this.viewType === ViewType.COMPONENT || this.viewType === ViewType.HOST) {
this.componentView = this; this.componentView = this;
@ -115,7 +118,7 @@ export class CompileView implements NameResolver {
if (this.viewType === ViewType.COMPONENT) { if (this.viewType === ViewType.COMPONENT) {
const directiveInstance = o.THIS_EXPR.prop('context'); const directiveInstance = o.THIS_EXPR.prop('context');
this.component.viewQueries.forEach((queryMeta, queryIndex) => { this.component.viewQueries.forEach((queryMeta, queryIndex) => {
const propName = `_viewQuery_${queryMeta.selectors[0].name}_${queryIndex}`; const propName = `_viewQuery_${tokenName(queryMeta.selectors[0])}_${queryIndex}`;
const queryList = createQueryList(queryMeta, directiveInstance, propName, this); const queryList = createQueryList(queryMeta, directiveInstance, propName, this);
const query = new CompileQuery(queryMeta, queryList, directiveInstance, this); const query = new CompileQuery(queryMeta, queryList, directiveInstance, this);
addQueryToTokenMap(viewQueries, query); addQueryToTokenMap(viewQueries, query);
@ -164,7 +167,7 @@ function getViewType(component: CompileDirectiveMetadata, embeddedTemplateIndex:
return ViewType.EMBEDDED; return ViewType.EMBEDDED;
} }
if (component.type.isHost) { if (component.isHost) {
return ViewType.HOST; return ViewType.HOST;
} }

View File

@ -10,7 +10,8 @@ import {CompileIdentifierMetadata} from '../compile_metadata';
export class ViewClassDependency { export class ViewClassDependency {
constructor( constructor(
public comp: CompileIdentifierMetadata, public placeholder: CompileIdentifierMetadata) {} public comp: CompileIdentifierMetadata, public name: string,
public placeholder: CompileIdentifierMetadata) {}
} }
export class ComponentFactoryDependency { export class ComponentFactoryDependency {
@ -20,5 +21,6 @@ export class ComponentFactoryDependency {
export class DirectiveWrapperDependency { export class DirectiveWrapperDependency {
constructor( constructor(
public dir: CompileIdentifierMetadata, public placeholder: CompileIdentifierMetadata) {} public dir: CompileIdentifierMetadata, public name: string,
public placeholder: CompileIdentifierMetadata) {}
} }

View File

@ -9,7 +9,7 @@
import {EventHandlerVars, convertActionBinding} from '../compiler_util/expression_converter'; import {EventHandlerVars, convertActionBinding} from '../compiler_util/expression_converter';
import {createInlineArray} from '../compiler_util/identifier_util'; import {createInlineArray} from '../compiler_util/identifier_util';
import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler'; import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {BoundEventAst, DirectiveAst} from '../template_parser/template_ast'; import {BoundEventAst, DirectiveAst} from '../template_parser/template_ast';
@ -56,7 +56,7 @@ function subscribeToRenderEvents(
compileElement.view.disposables.push(disposableVar); compileElement.view.disposables.push(disposableVar);
compileElement.view.createMethod.addStmt( compileElement.view.createMethod.addStmt(
disposableVar disposableVar
.set(o.importExpr(resolveIdentifier(Identifiers.subscribeToRenderElement)).callFn([ .set(o.importExpr(createIdentifier(Identifiers.subscribeToRenderElement)).callFn([
o.THIS_EXPR, compileElement.renderNode, createInlineArray(eventAndTargetExprs), o.THIS_EXPR, compileElement.renderNode, createInlineArray(eventAndTargetExprs),
handleEventExpr(compileElement) handleEventExpr(compileElement)
])) ]))

View File

@ -13,7 +13,7 @@ import {ConvertPropertyBindingResult, convertPropertyBinding} from '../compiler_
import {createEnumExpression} from '../compiler_util/identifier_util'; import {createEnumExpression} from '../compiler_util/identifier_util';
import {triggerAnimation, writeToRenderer} from '../compiler_util/render_util'; import {triggerAnimation, writeToRenderer} from '../compiler_util/render_util';
import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler'; import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {isDefaultChangeDetectionStrategy} from '../private_import_core'; import {isDefaultChangeDetectionStrategy} from '../private_import_core';
import {ElementSchemaRegistry} from '../schema/element_schema_registry'; import {ElementSchemaRegistry} from '../schema/element_schema_registry';
@ -69,7 +69,7 @@ export function bindRenderInputs(
const {updateStmts, detachStmts} = triggerAnimation( const {updateStmts, detachStmts} = triggerAnimation(
o.THIS_EXPR, o.THIS_EXPR, boundProp, o.THIS_EXPR, o.THIS_EXPR, boundProp,
(hasEvents ? o.THIS_EXPR.prop(getHandleEventMethodName(compileElement.nodeIndex)) : (hasEvents ? o.THIS_EXPR.prop(getHandleEventMethodName(compileElement.nodeIndex)) :
o.importExpr(resolveIdentifier(Identifiers.noop))) o.importExpr(createIdentifier(Identifiers.noop)))
.callMethod(o.BuiltinMethod.Bind, [o.THIS_EXPR]), .callMethod(o.BuiltinMethod.Bind, [o.THIS_EXPR]),
compileElement.renderNode, evalResult.currValExpr, bindingField.expression); compileElement.renderNode, evalResult.currValExpr, bindingField.expression);
checkBindingStmts.push(...updateStmts); checkBindingStmts.push(...updateStmts);

View File

@ -7,10 +7,10 @@
*/ */
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileTokenMetadata} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileTokenMetadata, identifierName} from '../compile_metadata';
import {createDiTokenExpression} from '../compiler_util/identifier_util'; import {createDiTokenExpression} from '../compiler_util/identifier_util';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {ViewType} from '../private_import_core'; import {ViewType} from '../private_import_core';
@ -74,7 +74,7 @@ export function injectFromViewParentInjector(
export function getViewClassName( export function getViewClassName(
component: CompileDirectiveSummary | CompileDirectiveMetadata, component: CompileDirectiveSummary | CompileDirectiveMetadata,
embeddedTemplateIndex: number): string { embeddedTemplateIndex: number): string {
return `View_${component.type.name}${embeddedTemplateIndex}`; return `View_${identifierName(component.type)}${embeddedTemplateIndex}`;
} }
export function getHandleEventMethodName(elementIndex: number): string { export function getHandleEventMethodName(elementIndex: number): string {

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {tokenReference} from '../compile_metadata';
import {ElementSchemaRegistry} from '../schema/element_schema_registry'; import {ElementSchemaRegistry} from '../schema/element_schema_registry';
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast'; import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast';
@ -66,7 +67,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
directiveAst, directiveWrapperInstance, compileElement); directiveAst, directiveWrapperInstance, compileElement);
}); });
ast.providers.forEach((providerAst) => { ast.providers.forEach((providerAst) => {
const providerInstance = compileElement.instances.get(providerAst.token.reference); const providerInstance = compileElement.instances.get(tokenReference(providerAst.token));
bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement); bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement);
}); });
return null; return null;
@ -89,7 +90,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
directiveAst, directiveWrapperInstance, compileElement); directiveAst, directiveWrapperInstance, compileElement);
}); });
ast.providers.forEach((providerAst) => { ast.providers.forEach((providerAst) => {
const providerInstance = compileElement.instances.get(providerAst.token.reference); const providerInstance = compileElement.instances.get(tokenReference(providerAst.token));
bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement); bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement);
}); });
bindView(compileElement.embeddedView, ast.children, this._schemaRegistry); bindView(compileElement.embeddedView, ast.children, this._schemaRegistry);

View File

@ -8,11 +8,11 @@
import {ViewEncapsulation} from '@angular/core'; import {ViewEncapsulation} from '@angular/core';
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileTokenMetadata} from '../compile_metadata'; import {CompileDirectiveMetadata, CompileDirectiveSummary, CompileIdentifierMetadata, CompileTokenMetadata, identifierModuleUrl, identifierName} from '../compile_metadata';
import {createSharedBindingVariablesIfNeeded} from '../compiler_util/expression_converter'; import {createSharedBindingVariablesIfNeeded} from '../compiler_util/expression_converter';
import {createDiTokenExpression, createInlineArray} from '../compiler_util/identifier_util'; import {createDiTokenExpression, createInlineArray} from '../compiler_util/identifier_util';
import {isPresent} from '../facade/lang'; import {isPresent} from '../facade/lang';
import {Identifiers, identifierToken, resolveIdentifier} from '../identifiers'; import {Identifiers, createIdentifier, identifierToken} from '../identifiers';
import {createClassStmt} from '../output/class_builder'; import {createClassStmt} from '../output/class_builder';
import * as o from '../output/output_ast'; import * as o from '../output/output_ast';
import {ParseSourceSpan} from '../parse_util'; import {ParseSourceSpan} from '../parse_util';
@ -189,13 +189,13 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
_mergeHtmlAndDirectiveAttrs(htmlAttrs, directives).map(v => o.literal(v))); _mergeHtmlAndDirectiveAttrs(htmlAttrs, directives).map(v => o.literal(v)));
if (nodeIndex === 0 && this.view.viewType === ViewType.HOST) { if (nodeIndex === 0 && this.view.viewType === ViewType.HOST) {
createRenderNodeExpr = createRenderNodeExpr =
o.importExpr(resolveIdentifier(Identifiers.selectOrCreateRenderHostElement)).callFn([ o.importExpr(createIdentifier(Identifiers.selectOrCreateRenderHostElement)).callFn([
ViewProperties.renderer, o.literal(ast.name), attrNameAndValues, rootSelectorVar, ViewProperties.renderer, o.literal(ast.name), attrNameAndValues, rootSelectorVar,
debugContextExpr debugContextExpr
]); ]);
} else { } else {
createRenderNodeExpr = createRenderNodeExpr =
o.importExpr(resolveIdentifier(Identifiers.createRenderElement)).callFn([ o.importExpr(createIdentifier(Identifiers.createRenderElement)).callFn([
ViewProperties.renderer, this._getParentRenderNode(parent), o.literal(ast.name), ViewProperties.renderer, this._getParentRenderNode(parent), o.literal(ast.name),
attrNameAndValues, debugContextExpr attrNameAndValues, debugContextExpr
]); ]);
@ -210,19 +210,18 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
const compileElement = new CompileElement( const compileElement = new CompileElement(
parent, this.view, nodeIndex, renderNode, ast, component, directives, ast.providers, parent, this.view, nodeIndex, renderNode, ast, component, directives, ast.providers,
ast.hasViewContainer, false, ast.references, this.targetDependencies); ast.hasViewContainer, false, ast.references);
this.view.nodes.push(compileElement); this.view.nodes.push(compileElement);
let compViewExpr: o.ReadPropExpr = null; let compViewExpr: o.ReadPropExpr = null;
if (isPresent(component)) { if (isPresent(component)) {
const nestedComponentIdentifier = const nestedComponentIdentifier = new CompileIdentifierMetadata();
new CompileIdentifierMetadata({name: getViewClassName(component, 0)}); this.targetDependencies.push(new ViewClassDependency(
this.targetDependencies.push( component.type, getViewClassName(component, 0), nestedComponentIdentifier));
new ViewClassDependency(component.type, nestedComponentIdentifier));
compViewExpr = o.THIS_EXPR.prop(`compView_${nodeIndex}`); // fix highlighting: ` compViewExpr = o.THIS_EXPR.prop(`compView_${nodeIndex}`); // fix highlighting: `
this.view.fields.push(new o.ClassField( this.view.fields.push(new o.ClassField(
compViewExpr.name, compViewExpr.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.importType(component.type)]))); o.importType(createIdentifier(Identifiers.AppView), [o.importType(component.type)])));
this.view.viewChildren.push(compViewExpr); this.view.viewChildren.push(compViewExpr);
compileElement.setComponentView(compViewExpr); compileElement.setComponentView(compViewExpr);
this.view.createMethod.addStmt( this.view.createMethod.addStmt(
@ -266,14 +265,14 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
const directives = ast.directives.map(directiveAst => directiveAst.directive); const directives = ast.directives.map(directiveAst => directiveAst.directive);
const compileElement = new CompileElement( const compileElement = new CompileElement(
parent, this.view, nodeIndex, renderNode, ast, null, directives, ast.providers, parent, this.view, nodeIndex, renderNode, ast, null, directives, ast.providers,
ast.hasViewContainer, true, ast.references, this.targetDependencies); ast.hasViewContainer, true, ast.references);
this.view.nodes.push(compileElement); this.view.nodes.push(compileElement);
this.nestedViewCount++; this.nestedViewCount++;
const embeddedView = new CompileView( const embeddedView = new CompileView(
this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR, this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR,
this.view.animations, this.view.viewIndex + this.nestedViewCount, compileElement, this.view.animations, this.view.viewIndex + this.nestedViewCount, compileElement,
templateVariableBindings); templateVariableBindings, this.targetDependencies);
this.nestedViewCount += buildView(embeddedView, ast.children, this.targetDependencies); this.nestedViewCount += buildView(embeddedView, ast.children, this.targetDependencies);
compileElement.beforeChildren(); compileElement.beforeChildren();
@ -372,31 +371,33 @@ function createViewTopLevelStmts(view: CompileView, targetStatements: o.Statemen
let nodeDebugInfosVar: o.Expression = o.NULL_EXPR; let nodeDebugInfosVar: o.Expression = o.NULL_EXPR;
if (view.genConfig.genDebugInfo) { if (view.genConfig.genDebugInfo) {
nodeDebugInfosVar = o.variable( nodeDebugInfosVar = o.variable(
`nodeDebugInfos_${view.component.type.name}${view.viewIndex}`); // fix highlighting: ` `nodeDebugInfos_${identifierName(view.component.type)}${view.viewIndex}`); // fix
// highlighting:
// `
targetStatements.push( targetStatements.push(
(<o.ReadVarExpr>nodeDebugInfosVar) (<o.ReadVarExpr>nodeDebugInfosVar)
.set(o.literalArr( .set(o.literalArr(
view.nodes.map(createStaticNodeDebugInfo), view.nodes.map(createStaticNodeDebugInfo),
new o.ArrayType( new o.ArrayType(
new o.ExternalType(resolveIdentifier(Identifiers.StaticNodeDebugInfo)), o.importType(createIdentifier(Identifiers.StaticNodeDebugInfo)),
[o.TypeModifier.Const]))) [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final])); .toDeclStmt(null, [o.StmtModifier.Final]));
} }
const renderCompTypeVar: o.ReadVarExpr = const renderCompTypeVar: o.ReadVarExpr =
o.variable(`renderType_${view.component.type.name}`); // fix highlighting: ` o.variable(`renderType_${identifierName(view.component.type)}`); // fix highlighting: `
if (view.viewIndex === 0) { if (view.viewIndex === 0) {
let templateUrlInfo: string; let templateUrlInfo: string;
if (view.component.template.templateUrl == view.component.type.moduleUrl) { if (view.component.template.templateUrl == identifierModuleUrl(view.component.type)) {
templateUrlInfo = templateUrlInfo =
`${view.component.type.moduleUrl} class ${view.component.type.name} - inline template`; `${identifierModuleUrl(view.component.type)} class ${identifierName(view.component.type)} - inline template`;
} else { } else {
templateUrlInfo = view.component.template.templateUrl; templateUrlInfo = view.component.template.templateUrl;
} }
targetStatements.push( targetStatements.push(
renderCompTypeVar renderCompTypeVar
.set(o.importExpr(resolveIdentifier(Identifiers.createRenderComponentType)).callFn([ .set(o.importExpr(createIdentifier(Identifiers.createRenderComponentType)).callFn([
view.genConfig.genDebugInfo ? o.literal(templateUrlInfo) : o.literal(''), view.genConfig.genDebugInfo ? o.literal(templateUrlInfo) : o.literal(''),
o.literal(view.component.template.ngContentSelectors.length), o.literal(view.component.template.ngContentSelectors.length),
ViewEncapsulationEnum.fromValue(view.component.template.encapsulation), ViewEncapsulationEnum.fromValue(view.component.template.encapsulation),
@ -404,7 +405,7 @@ function createViewTopLevelStmts(view: CompileView, targetStatements: o.Statemen
o.literalMap(view.animations.map( o.literalMap(view.animations.map(
(entry): [string, o.Expression] => [entry.name, entry.fnExp])), (entry): [string, o.Expression] => [entry.name, entry.fnExp])),
])) ]))
.toDeclStmt(o.importType(resolveIdentifier(Identifiers.RenderComponentType)))); .toDeclStmt(o.importType(createIdentifier(Identifiers.RenderComponentType))));
} }
const viewClass = createViewClass(view, renderCompTypeVar, nodeDebugInfosVar); const viewClass = createViewClass(view, renderCompTypeVar, nodeDebugInfosVar);
@ -427,7 +428,7 @@ function createStaticNodeDebugInfo(node: CompileNode): o.Expression {
[varName, isPresent(token) ? createDiTokenExpression(token) : o.NULL_EXPR]); [varName, isPresent(token) ? createDiTokenExpression(token) : o.NULL_EXPR]);
}); });
} }
return o.importExpr(resolveIdentifier(Identifiers.StaticNodeDebugInfo)) return o.importExpr(createIdentifier(Identifiers.StaticNodeDebugInfo))
.instantiate( .instantiate(
[ [
o.literalArr(providerTokens, new o.ArrayType(o.DYNAMIC_TYPE, [o.TypeModifier.Const])), o.literalArr(providerTokens, new o.ArrayType(o.DYNAMIC_TYPE, [o.TypeModifier.Const])),
@ -435,7 +436,7 @@ function createStaticNodeDebugInfo(node: CompileNode): o.Expression {
o.literalMap(varTokenEntries, new o.MapType(o.DYNAMIC_TYPE, [o.TypeModifier.Const])) o.literalMap(varTokenEntries, new o.MapType(o.DYNAMIC_TYPE, [o.TypeModifier.Const]))
], ],
o.importType( o.importType(
resolveIdentifier(Identifiers.StaticNodeDebugInfo), null, [o.TypeModifier.Const])); createIdentifier(Identifiers.StaticNodeDebugInfo), null, [o.TypeModifier.Const]));
} }
function createViewClass( function createViewClass(
@ -443,10 +444,10 @@ function createViewClass(
nodeDebugInfosVar: o.Expression): o.ClassStmt { nodeDebugInfosVar: o.Expression): o.ClassStmt {
const viewConstructorArgs = [ const viewConstructorArgs = [
new o.FnParam( new o.FnParam(
ViewConstructorVars.viewUtils.name, o.importType(resolveIdentifier(Identifiers.ViewUtils))), ViewConstructorVars.viewUtils.name, o.importType(createIdentifier(Identifiers.ViewUtils))),
new o.FnParam( new o.FnParam(
ViewConstructorVars.parentView.name, ViewConstructorVars.parentView.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])), o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(ViewConstructorVars.parentIndex.name, o.NUMBER_TYPE), new o.FnParam(ViewConstructorVars.parentIndex.name, o.NUMBER_TYPE),
new o.FnParam(ViewConstructorVars.parentElement.name, o.DYNAMIC_TYPE) new o.FnParam(ViewConstructorVars.parentElement.name, o.DYNAMIC_TYPE)
]; ];
@ -461,14 +462,14 @@ function createViewClass(
} }
if (view.viewType === ViewType.EMBEDDED) { if (view.viewType === ViewType.EMBEDDED) {
viewConstructorArgs.push(new o.FnParam( viewConstructorArgs.push(new o.FnParam(
'declaredViewContainer', o.importType(resolveIdentifier(Identifiers.ViewContainer)))); 'declaredViewContainer', o.importType(createIdentifier(Identifiers.ViewContainer))));
superConstructorArgs.push(o.variable('declaredViewContainer')); superConstructorArgs.push(o.variable('declaredViewContainer'));
} }
const viewMethods = [ const viewMethods = [
new o.ClassMethod( new o.ClassMethod(
'createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)], 'createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)],
generateCreateMethod(view), generateCreateMethod(view),
o.importType(resolveIdentifier(Identifiers.ComponentRef), [o.DYNAMIC_TYPE])), o.importType(createIdentifier(Identifiers.ComponentRef), [o.DYNAMIC_TYPE])),
new o.ClassMethod( new o.ClassMethod(
'injectorGetInternal', 'injectorGetInternal',
[ [
@ -492,7 +493,7 @@ function createViewClass(
const viewClass = createClassStmt({ const viewClass = createClassStmt({
name: view.className, name: view.className,
parent: o.importExpr(resolveIdentifier(superClass), [getContextType(view)]), parent: o.importExpr(createIdentifier(superClass), [getContextType(view)]),
parentArgs: superConstructorArgs, parentArgs: superConstructorArgs,
ctorParams: viewConstructorArgs, ctorParams: viewConstructorArgs,
builders: [{methods: viewMethods}, view] builders: [{methods: viewMethods}, view]
@ -526,7 +527,7 @@ function generateCreateMethod(view: CompileView): o.Statement[] {
if (view.viewType === ViewType.HOST) { if (view.viewType === ViewType.HOST) {
const hostEl = <CompileElement>view.nodes[0]; const hostEl = <CompileElement>view.nodes[0];
resultExpr = resultExpr =
o.importExpr(resolveIdentifier(Identifiers.ComponentRef_), [o.DYNAMIC_TYPE]).instantiate([ o.importExpr(createIdentifier(Identifiers.ComponentRef_), [o.DYNAMIC_TYPE]).instantiate([
o.literal(hostEl.nodeIndex), o.THIS_EXPR, hostEl.renderNode, hostEl.getComponent() o.literal(hostEl.nodeIndex), o.THIS_EXPR, hostEl.renderNode, hostEl.getComponent()
]); ]);
} else { } else {
@ -591,7 +592,7 @@ function generateDetectChangesMethod(view: CompileView): o.Statement[] {
if (readVars.has(DetectChangesVars.changes.name)) { if (readVars.has(DetectChangesVars.changes.name)) {
varStmts.push( varStmts.push(
DetectChangesVars.changes.set(o.NULL_EXPR) DetectChangesVars.changes.set(o.NULL_EXPR)
.toDeclStmt(new o.MapType(o.importType(resolveIdentifier(Identifiers.SimpleChange))))); .toDeclStmt(new o.MapType(o.importType(createIdentifier(Identifiers.SimpleChange)))));
} }
varStmts.push(...createSharedBindingVariablesIfNeeded(stmts)); varStmts.push(...createSharedBindingVariablesIfNeeded(stmts));
return varStmts.concat(stmts); return varStmts.concat(stmts);
@ -703,5 +704,5 @@ function generateCreateEmbeddedViewsMethod(view: CompileView): o.ClassMethod {
} }
return new o.ClassMethod( return new o.ClassMethod(
'createEmbeddedViewInternal', [new o.FnParam(nodeIndexVar.name, o.NUMBER_TYPE)], stmts, 'createEmbeddedViewInternal', [new o.FnParam(nodeIndexVar.name, o.NUMBER_TYPE)], stmts,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])); o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE]));
} }

View File

@ -42,7 +42,7 @@ export class ViewCompiler {
Array<ViewClassDependency|ComponentFactoryDependency|DirectiveWrapperDependency> = []; Array<ViewClassDependency|ComponentFactoryDependency|DirectiveWrapperDependency> = [];
const view = new CompileView( const view = new CompileView(
component, this._genConfig, pipes, styles, compiledAnimations, 0, component, this._genConfig, pipes, styles, compiledAnimations, 0,
CompileElement.createNull(), []); CompileElement.createNull(), [], dependencies);
const statements: o.Statement[] = []; const statements: o.Statement[] = [];
buildView(view, template, dependencies); buildView(view, template, dependencies);

View File

@ -10,7 +10,7 @@ import {AnimationMetadata, animate, sequence, style, transition, trigger} from '
import {beforeEach, describe, expect, inject, it} from '@angular/core/testing/testing_internal'; import {beforeEach, describe, expect, inject, it} from '@angular/core/testing/testing_internal';
import {AnimationCompiler, AnimationEntryCompileResult} from '../../src/animation/animation_compiler'; import {AnimationCompiler, AnimationEntryCompileResult} from '../../src/animation/animation_compiler';
import {AnimationParser} from '../../src/animation/animation_parser'; import {AnimationParser} from '../../src/animation/animation_parser';
import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '../../src/compile_metadata'; import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata, identifierName} from '../../src/compile_metadata';
import {CompileMetadataResolver} from '../../src/metadata_resolver'; import {CompileMetadataResolver} from '../../src/metadata_resolver';
import {ElementSchemaRegistry} from '../../src/schema/element_schema_registry'; import {ElementSchemaRegistry} from '../../src/schema/element_schema_registry';
@ -30,7 +30,7 @@ export function main() {
const compileAnimations = const compileAnimations =
(component: CompileDirectiveMetadata): AnimationEntryCompileResult[] => { (component: CompileDirectiveMetadata): AnimationEntryCompileResult[] => {
const parsedAnimations = parser.parseComponent(component); const parsedAnimations = parser.parseComponent(component);
return compiler.compile(component.type.name, parsedAnimations); return compiler.compile(identifierName(component.type), parsedAnimations);
}; };
const compileTriggers = (input: any[]) => { const compileTriggers = (input: any[]) => {
@ -40,7 +40,7 @@ export function main() {
}); });
const component = CompileDirectiveMetadata.create({ const component = CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({name: 'myCmp'}), type: new CompileTypeMetadata({reference: {name: 'myCmp', filePath: ''}}),
template: new CompileTemplateMetadata({animations: entries}) template: new CompileTemplateMetadata({animations: entries})
}); });

View File

@ -7,7 +7,7 @@
*/ */
import {createInlineArray} from '../../src/compiler_util/identifier_util'; import {createInlineArray} from '../../src/compiler_util/identifier_util';
import {Identifiers, resolveIdentifier} from '../../src/identifiers'; import {Identifiers, createIdentifier} from '../../src/identifiers';
import * as o from '../../src/output/output_ast'; import * as o from '../../src/output/output_ast';
export function main() { export function main() {
@ -16,7 +16,7 @@ export function main() {
function check(argCount: number, expectedIdentifier: any) { function check(argCount: number, expectedIdentifier: any) {
const args = createArgs(argCount); const args = createArgs(argCount);
expect(createInlineArray(args)) expect(createInlineArray(args))
.toEqual(o.importExpr(resolveIdentifier(expectedIdentifier)).instantiate([ .toEqual(o.importExpr(createIdentifier(expectedIdentifier)).instantiate([
<o.Expression>o.literal(argCount) <o.Expression>o.literal(argCount)
].concat(args))); ].concat(args)));
} }
@ -31,7 +31,7 @@ export function main() {
it('should work for arrays of length 0', () => { it('should work for arrays of length 0', () => {
expect(createInlineArray([ expect(createInlineArray([
])).toEqual(o.importExpr(resolveIdentifier(Identifiers.EMPTY_INLINE_ARRAY))); ])).toEqual(o.importExpr(createIdentifier(Identifiers.EMPTY_INLINE_ARRAY)));
}); });
it('should work for arrays of length 1 - 2', () => { it('should work for arrays of length 1 - 2', () => {

View File

@ -11,6 +11,7 @@ import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit,
import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks'; import {LIFECYCLE_HOOKS_VALUES} from '@angular/core/src/metadata/lifecycle_hooks';
import {TestBed, async, inject} from '@angular/core/testing'; import {TestBed, async, inject} from '@angular/core/testing';
import {identifierName} from '../src/compile_metadata';
import {stringify} from '../src/facade/lang'; import {stringify} from '../src/facade/lang';
import {CompileMetadataResolver} from '../src/metadata_resolver'; import {CompileMetadataResolver} from '../src/metadata_resolver';
import {ResourceLoader} from '../src/resource_loader'; import {ResourceLoader} from '../src/resource_loader';
@ -50,7 +51,7 @@ export function main() {
expect(meta.exportAs).toEqual('someExportAs'); expect(meta.exportAs).toEqual('someExportAs');
expect(meta.isComponent).toBe(true); expect(meta.isComponent).toBe(true);
expect(meta.type.reference).toBe(ComponentWithEverythingInline); expect(meta.type.reference).toBe(ComponentWithEverythingInline);
expect(meta.type.name).toEqual(stringify(ComponentWithEverythingInline)); expect(identifierName(meta.type)).toEqual(stringify(ComponentWithEverythingInline));
expect(meta.type.lifecycleHooks).toEqual(LIFECYCLE_HOOKS_VALUES); expect(meta.type.lifecycleHooks).toEqual(LIFECYCLE_HOOKS_VALUES);
expect(meta.changeDetection).toBe(ChangeDetectionStrategy.Default); expect(meta.changeDetection).toBe(ChangeDetectionStrategy.Default);
expect(meta.inputs).toEqual({'someProp': 'someProp'}); expect(meta.inputs).toEqual({'someProp': 'someProp'});
@ -114,18 +115,24 @@ export function main() {
resourceLoader.flush(); resourceLoader.flush();
}))); })));
it('should use the moduleUrl from the reflector if none is given', it('should use `./` as base url for templates during runtime compilation if no moduleId is given',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => { async(inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {
@Component({selector: 'someComponent', templateUrl: 'someUrl'})
class ComponentWithoutModuleId {
}
@NgModule({declarations: [ComponentWithoutModuleId]}) @NgModule({declarations: [ComponentWithoutModuleId]})
class SomeModule { class SomeModule {
} }
resolver.loadNgModuleMetadata(SomeModule, true);
const value: string = resolver.loadNgModuleMetadata(SomeModule, false).loading.then(() => {
resolver.getDirectiveMetadata(ComponentWithoutModuleId).type.moduleUrl; const value: string =
const expectedEndValue = './ComponentWithoutModuleId'; resolver.getDirectiveMetadata(ComponentWithoutModuleId).template.templateUrl;
expect(value.endsWith(expectedEndValue)).toBe(true); const expectedEndValue = './someUrl';
})); expect(value.endsWith(expectedEndValue)).toBe(true);
});
})));
it('should throw when the moduleId is not a string', it('should throw when the moduleId is not a string',
inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => { inject([CompileMetadataResolver], (resolver: CompileMetadataResolver) => {

View File

@ -15,9 +15,9 @@ const someModuleUrl = 'somePackage/somePath';
const anotherModuleUrl = 'somePackage/someOtherPath'; const anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier = const sameModuleIdentifier =
new CompileIdentifierMetadata({name: 'someLocalId', moduleUrl: someModuleUrl}); new CompileIdentifierMetadata({reference: {name: 'someLocalId', filePath: someModuleUrl}});
const externalModuleIdentifier = const externalModuleIdentifier = new CompileIdentifierMetadata(
new CompileIdentifierMetadata({name: 'someExternalId', moduleUrl: anotherModuleUrl}); {reference: {name: 'someExternalId', filePath: anotherModuleUrl}});
class SimpleJsImportGenerator implements ImportResolver { class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string { fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {

View File

@ -7,7 +7,7 @@
*/ */
import {CompileIdentifierMetadata} from '@angular/compiler/src/compile_metadata'; import {CompileIdentifierMetadata} from '@angular/compiler/src/compile_metadata';
import {assetUrl} from '@angular/compiler/src/identifiers'; import {assetUrl, createIdentifier} from '@angular/compiler/src/identifiers';
import * as o from '@angular/compiler/src/output/output_ast'; import * as o from '@angular/compiler/src/output/output_ast';
import {ImportResolver} from '@angular/compiler/src/output/path_util'; import {ImportResolver} from '@angular/compiler/src/output/path_util';
import {EventEmitter} from '@angular/core'; import {EventEmitter} from '@angular/core';
@ -20,23 +20,29 @@ export class ExternalClass {
someMethod(a: any /** TODO #9100 */) { return {'param': a, 'data': this.data}; } someMethod(a: any /** TODO #9100 */) { return {'param': a, 'data': this.data}; }
} }
const testDataIdentifier = new CompileIdentifierMetadata({ const testDataIdentifier = {
name: 'ExternalClass', name: 'ExternalClass',
moduleUrl: `@angular/compiler/test/output/output_emitter_util`, moduleUrl: `@angular/compiler/test/output/output_emitter_util`,
reference: ExternalClass runtime: ExternalClass
}); };
const eventEmitterIdentifier = new CompileIdentifierMetadata( const eventEmitterIdentifier = {
{name: 'EventEmitter', moduleUrl: assetUrl('core'), reference: EventEmitter}); name: 'EventEmitter',
moduleUrl: assetUrl('core'),
runtime: EventEmitter
};
const enumIdentifier = new CompileIdentifierMetadata({ const enumIdentifier = {
name: 'ViewType.HOST', name: 'ViewType.HOST',
moduleUrl: assetUrl('core', 'linker/view_type'), moduleUrl: assetUrl('core', 'linker/view_type'),
reference: ViewType.HOST runtime: ViewType.HOST
}); };
const baseErrorIdentifier = new CompileIdentifierMetadata( const baseErrorIdentifier = {
{name: 'BaseError', moduleUrl: assetUrl('core', 'facade/errors'), reference: BaseError}); name: 'BaseError',
moduleUrl: assetUrl('core', 'facade/errors'),
runtime: BaseError
};
export var codegenExportsVars = [ export var codegenExportsVars = [
'getExpressions', 'getExpressions',
@ -58,7 +64,7 @@ const _getExpressionsStmts: o.Statement[] = [
o.variable('map').key(o.literal('changeable')).set(o.literal('changedValue')).toStmt(), o.variable('map').key(o.literal('changeable')).set(o.literal('changedValue')).toStmt(),
o.variable('externalInstance') o.variable('externalInstance')
.set(o.importExpr(testDataIdentifier).instantiate([o.literal('someValue')])) .set(o.importExpr(createIdentifier(testDataIdentifier)).instantiate([o.literal('someValue')]))
.toDeclStmt(), .toDeclStmt(),
o.variable('externalInstance').prop('changeable').set(o.literal('changedValue')).toStmt(), o.variable('externalInstance').prop('changeable').set(o.literal('changedValue')).toStmt(),
@ -69,8 +75,8 @@ const _getExpressionsStmts: o.Statement[] = [
.toDeclStmt(), .toDeclStmt(),
o.variable('throwError') o.variable('throwError')
.set(o.fn([], [new o.ThrowStmt( .set(o.fn([], [new o.ThrowStmt(o.importExpr(createIdentifier(baseErrorIdentifier))
o.importExpr(baseErrorIdentifier).instantiate([o.literal('someError')]))])) .instantiate([o.literal('someError')]))]))
.toDeclStmt(), .toDeclStmt(),
o.variable('catchError') o.variable('catchError')
@ -152,9 +158,9 @@ const _getExpressionsStmts: o.Statement[] = [
['not', o.not(o.literal(false))], ['not', o.not(o.literal(false))],
['externalTestIdentifier', o.importExpr(testDataIdentifier)], ['externalTestIdentifier', o.importExpr(createIdentifier(testDataIdentifier))],
['externalSrcIdentifier', o.importExpr(eventEmitterIdentifier)], ['externalSrcIdentifier', o.importExpr(createIdentifier(eventEmitterIdentifier))],
['externalEnumIdentifier', o.importExpr(enumIdentifier)], ['externalEnumIdentifier', o.importExpr(createIdentifier(enumIdentifier))],
['externalInstance', o.variable('externalInstance')], ['externalInstance', o.variable('externalInstance')],
['dynamicInstance', o.variable('dynamicInstance')], ['dynamicInstance', o.variable('dynamicInstance')],
@ -188,7 +194,7 @@ export var codegenStmts: o.Statement[] = [
new o.CommentStmt('This is a comment'), new o.CommentStmt('This is a comment'),
new o.ClassStmt( new o.ClassStmt(
'DynamicClass', o.importExpr(testDataIdentifier), 'DynamicClass', o.importExpr(createIdentifier(testDataIdentifier)),
[ [
new o.ClassField('dynamicProp', o.DYNAMIC_TYPE), new o.ClassField('dynamicProp', o.DYNAMIC_TYPE),
new o.ClassField('dynamicChangeable', o.DYNAMIC_TYPE), new o.ClassField('dynamicChangeable', o.DYNAMIC_TYPE),

View File

@ -10,16 +10,15 @@ import {CompileIdentifierMetadata} from '@angular/compiler/src/compile_metadata'
import * as o from '@angular/compiler/src/output/output_ast'; import * as o from '@angular/compiler/src/output/output_ast';
import {ImportResolver} from '@angular/compiler/src/output/path_util'; import {ImportResolver} from '@angular/compiler/src/output/path_util';
import {TypeScriptEmitter} from '@angular/compiler/src/output/ts_emitter'; import {TypeScriptEmitter} from '@angular/compiler/src/output/ts_emitter';
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
const someModuleUrl = 'somePackage/somePath'; const someModuleUrl = 'somePackage/somePath';
const anotherModuleUrl = 'somePackage/someOtherPath'; const anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier = const sameModuleIdentifier =
new CompileIdentifierMetadata({name: 'someLocalId', moduleUrl: someModuleUrl}); new CompileIdentifierMetadata({reference: {name: 'someLocalId', filePath: someModuleUrl}});
const externalModuleIdentifier = const externalModuleIdentifier = new CompileIdentifierMetadata(
new CompileIdentifierMetadata({name: 'someExternalId', moduleUrl: anotherModuleUrl}); {reference: {name: 'someExternalId', filePath: anotherModuleUrl}});
class SimpleJsImportGenerator implements ImportResolver { class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string { fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
@ -323,6 +322,14 @@ export function main() {
].join('\n')); ].join('\n'));
}); });
it('should support expression types', () => {
expect(emitStmt(o.variable('a')
.set(o.NULL_EXPR)
.toDeclStmt(o.expressionType(
o.variable('b'), [o.expressionType(o.variable('c'))]))))
.toEqual('var a:b<c> = (null as any);');
});
it('should support combined types', () => { it('should support combined types', () => {
const writeVarExpr = o.variable('a').set(o.NULL_EXPR); const writeVarExpr = o.variable('a').set(o.NULL_EXPR);
expect(emitStmt(writeVarExpr.toDeclStmt(new o.ArrayType(null)))) expect(emitStmt(writeVarExpr.toDeclStmt(new o.ArrayType(null))))

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {CompileAnimationEntryMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata} from '@angular/compiler/src/compile_metadata'; import {CompileAnimationEntryMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileQueryMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, tokenReference} from '@angular/compiler/src/compile_metadata';
import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry'; import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry';
import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry'; import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry';
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAstType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '@angular/compiler/src/template_parser/template_ast'; import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAstType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '@angular/compiler/src/template_parser/template_ast';
@ -14,10 +14,9 @@ import {TEMPLATE_TRANSFORMS, TemplateParser, splitClasses} from '@angular/compil
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings'; import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings';
import {SchemaMetadata, SecurityContext, Type} from '@angular/core'; import {SchemaMetadata, SecurityContext, Type} from '@angular/core';
import {Console} from '@angular/core/src/console'; import {Console} from '@angular/core/src/console';
import {TestBed} from '@angular/core/testing'; import {TestBed, inject} from '@angular/core/testing';
import {beforeEach, describe, expect, inject, it} from '@angular/core/testing/testing_internal';
import {Identifiers, identifierToken, resolveIdentifierToken} from '../../src/identifiers'; import {Identifiers, createIdentifierToken, identifierToken} from '../../src/identifiers';
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../src/ml_parser/interpolation_config'; import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../src/ml_parser/interpolation_config';
import {MockSchemaRegistry} from '../../testing/index'; import {MockSchemaRegistry} from '../../testing/index';
import {unparse} from '../expression_parser/unparser'; import {unparse} from '../expression_parser/unparser';
@ -49,19 +48,18 @@ export function main() {
const component = CompileDirectiveMetadata.create({ const component = CompileDirectiveMetadata.create({
selector: 'root', selector: 'root',
template: someTemplate, template: someTemplate,
type: new CompileTypeMetadata( type: new CompileTypeMetadata({reference: {filePath: someModuleUrl, name: 'Root'}}),
{moduleUrl: someModuleUrl, name: 'Root', reference: {} as Type<any>}),
isComponent: true isComponent: true
}); });
ngIf = CompileDirectiveMetadata ngIf =
.create({ CompileDirectiveMetadata
selector: '[ngIf]', .create({
template: someTemplate, selector: '[ngIf]',
type: new CompileTypeMetadata( template: someTemplate,
{moduleUrl: someModuleUrl, name: 'NgIf', reference: {} as Type<any>}), type: new CompileTypeMetadata({reference: {filePath: someModuleUrl, name: 'NgIf'}}),
inputs: ['ngIf'] inputs: ['ngIf']
}) })
.toSummary(); .toSummary();
parse = parse =
(template: string, directives: CompileDirectiveSummary[], (template: string, directives: CompileDirectiveSummary[],
@ -302,8 +300,8 @@ export function main() {
inject([TemplateParser], (parser: TemplateParser) => { inject([TemplateParser], (parser: TemplateParser) => {
const component = CompileDirectiveMetadata.create({ const component = CompileDirectiveMetadata.create({
selector: 'test', selector: 'test',
type: new CompileTypeMetadata( type:
{moduleUrl: someModuleUrl, name: 'Test', reference: {} as Type<any>}), new CompileTypeMetadata({reference: {filePath: someModuleUrl, name: 'Test'}}),
isComponent: true, isComponent: true,
template: new CompileTemplateMetadata({interpolation: ['{%', '%}']}) template: new CompileTemplateMetadata({interpolation: ['{%', '%}']})
}); });
@ -471,9 +469,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
selector: 'div', selector: 'div',
template: new CompileTemplateMetadata({animations: animationEntries}), template: new CompileTemplateMetadata({animations: animationEntries}),
type: new CompileTypeMetadata({ type: new CompileTypeMetadata({
moduleUrl: someModuleUrl, reference: {filePath: someModuleUrl, name: 'DirA'},
name: 'DirA',
reference: {} as Type<any>
}), }),
host: {'[@prop]': 'expr'} host: {'[@prop]': 'expr'}
}) })
@ -484,15 +480,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should throw descriptive error when a host binding is not a string expression', () => { it('should throw descriptive error when a host binding is not a string expression', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'broken',
selector: 'broken', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), host: {'[class.foo]': null}
host: {'[class.foo]': null} })
}) .toSummary();
.toSummary();
expect(() => { parse('<broken></broken>', [dirA]); }) expect(() => { parse('<broken></broken>', [dirA]); })
.toThrowError( .toThrowError(
@ -500,15 +495,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should throw descriptive error when a host event is not a string expression', () => { it('should throw descriptive error when a host event is not a string expression', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'broken',
selector: 'broken', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), host: {'(click)': null}
host: {'(click)': null} })
}) .toSummary();
.toSummary();
expect(() => { parse('<broken></broken>', [dirA]); }) expect(() => { parse('<broken></broken>', [dirA]); })
.toThrowError( .toThrowError(
@ -572,11 +566,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
.create({ .create({
selector: 'template', selector: 'template',
outputs: ['e'], outputs: ['e'],
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirA'}})
name: 'DirA',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
expect(humanizeTplAst(parse('<template (e)="f"></template>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<template (e)="f"></template>', [dirA]))).toEqual([
@ -614,31 +605,22 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirA = CompileDirectiveMetadata const dirA = CompileDirectiveMetadata
.create({ .create({
selector: '[a]', selector: '[a]',
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirA'}})
name: 'DirA',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
const dirB = CompileDirectiveMetadata const dirB = CompileDirectiveMetadata
.create({ .create({
selector: '[b]', selector: '[b]',
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirB'}})
name: 'DirB',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
const dirC = CompileDirectiveMetadata const dirC = CompileDirectiveMetadata
.create({ .create({
selector: '[c]', selector: '[c]',
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirC'}})
name: 'DirC',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
expect(humanizeTplAst(parse('<div a c b a b>', [dirA, dirB, dirC]))).toEqual([ expect(humanizeTplAst(parse('<div a c b a b>', [dirA, dirB, dirC]))).toEqual([
@ -649,22 +631,20 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should locate directives in property bindings', () => { it('should locate directives in property bindings', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a=b]',
selector: '[a=b]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}})
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary(); const dirB = CompileDirectiveMetadata
const dirB = .create({
CompileDirectiveMetadata selector: '[b]',
.create({ type: new CompileTypeMetadata(
selector: '[b]', {reference: {filePath: someModuleUrl, name: 'DirB'}})
type: new CompileTypeMetadata( })
{moduleUrl: someModuleUrl, name: 'DirB', reference: {} as Type<any>}) .toSummary();
})
.toSummary();
expect(humanizeTplAst(parse('<div [a]="b">', [dirA, dirB]))).toEqual([ expect(humanizeTplAst(parse('<div [a]="b">', [dirA, dirB]))).toEqual([
[ElementAst, 'div'], [ElementAst, 'div'],
[BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'b', null], [BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'b', null],
@ -673,14 +653,13 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should locate directives in event bindings', () => { it('should locate directives in event bindings', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirB'}})
{moduleUrl: someModuleUrl, name: 'DirB', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div (a)="b">', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div (a)="b">', [dirA]))).toEqual([
[ElementAst, 'div'], [BoundEventAst, 'a', null, 'b'], [DirectiveAst, dirA] [ElementAst, 'div'], [BoundEventAst, 'a', null, 'b'], [DirectiveAst, dirA]
@ -688,15 +667,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should parse directive host properties', () => { it('should parse directive host properties', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), host: {'[a]': 'expr'}
host: {'[a]': 'expr'} })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA], [ElementAst, 'div'], [DirectiveAst, dirA],
[BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'expr', null] [BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'expr', null]
@ -704,30 +682,28 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should parse directive host listeners', () => { it('should parse directive host listeners', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), host: {'(a)': 'expr'}
host: {'(a)': 'expr'} })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA], [BoundEventAst, 'a', null, 'expr'] [ElementAst, 'div'], [DirectiveAst, dirA], [BoundEventAst, 'a', null, 'expr']
]); ]);
}); });
it('should parse directive properties', () => { it('should parse directive properties', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['aProp']
inputs: ['aProp'] })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div [aProp]="expr"></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div [aProp]="expr"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA], [ElementAst, 'div'], [DirectiveAst, dirA],
[BoundDirectivePropertyAst, 'aProp', 'expr'] [BoundDirectivePropertyAst, 'aProp', 'expr']
@ -735,15 +711,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should parse renamed directive properties', () => { it('should parse renamed directive properties', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['b:a']
inputs: ['b:a'] })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div [a]="expr"></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div [a]="expr"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA], [ElementAst, 'div'], [DirectiveAst, dirA],
[BoundDirectivePropertyAst, 'b', 'expr'] [BoundDirectivePropertyAst, 'b', 'expr']
@ -751,15 +726,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should parse literal directive properties', () => { it('should parse literal directive properties', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['a']
inputs: ['a'] })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div a="literal"></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div a="literal"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [AttrAst, 'a', 'literal'], [DirectiveAst, dirA], [ElementAst, 'div'], [AttrAst, 'a', 'literal'], [DirectiveAst, dirA],
[BoundDirectivePropertyAst, 'a', '"literal"'] [BoundDirectivePropertyAst, 'a', '"literal"']
@ -767,15 +741,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should favor explicit bound properties over literal properties', () => { it('should favor explicit bound properties over literal properties', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['a']
inputs: ['a'] })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div a="literal" [a]="\'literal2\'"></div>', [dirA]))) expect(humanizeTplAst(parse('<div a="literal" [a]="\'literal2\'"></div>', [dirA])))
.toEqual([ .toEqual([
[ElementAst, 'div'], [AttrAst, 'a', 'literal'], [DirectiveAst, dirA], [ElementAst, 'div'], [AttrAst, 'a', 'literal'], [DirectiveAst, dirA],
@ -784,15 +757,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should support optional directive properties', () => { it('should support optional directive properties', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['a']
inputs: ['a'] })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA] [ElementAst, 'div'], [DirectiveAst, dirA]
]); ]);
@ -807,10 +779,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
let token: CompileTokenMetadata; let token: CompileTokenMetadata;
if (value.startsWith('type:')) { if (value.startsWith('type:')) {
const name = value.substring(5); const name = value.substring(5);
token = new CompileTokenMetadata({ token = new CompileTokenMetadata(
identifier: new CompileTypeMetadata( {identifier: new CompileTypeMetadata({reference: <any>name})});
{moduleUrl: someModuleUrl, name, reference: name as any as Type<any>})
});
} else { } else {
token = new CompileTokenMetadata({value: value}); token = new CompileTokenMetadata({value: value});
} }
@ -845,10 +815,11 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
token: string, {multi = false, deps = []}: {multi?: boolean, deps?: string[]} = {}): token: string, {multi = false, deps = []}: {multi?: boolean, deps?: string[]} = {}):
CompileProviderMetadata { CompileProviderMetadata {
const name = `provider${nextProviderId++}`; const name = `provider${nextProviderId++}`;
const compileToken = createToken(token);
return new CompileProviderMetadata({ return new CompileProviderMetadata({
token: createToken(token), token: compileToken,
multi: multi, multi: multi,
useClass: new CompileTypeMetadata({name, reference: name as any as Type<any>}), useClass: new CompileTypeMetadata({reference: tokenReference(compileToken)}),
deps: deps.map(createDep) deps: deps.map(createDep)
}); });
} }
@ -866,10 +837,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
.create({ .create({
selector: selector, selector: selector,
type: new CompileTypeMetadata({ type: new CompileTypeMetadata({
moduleUrl: someModuleUrl, reference: <any>selector,
name: selector,
diDeps: deps.map(createDep), diDeps: deps.map(createDep),
reference: selector as any as Type<any>
}), }),
isComponent: isComponent, isComponent: isComponent,
template: new CompileTemplateMetadata({ngContentSelectors: []}), template: new CompileTemplateMetadata({ngContentSelectors: []}),
@ -1118,15 +1087,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
}); });
it('should assign references to directives via exportAs', () => { it('should assign references to directives via exportAs', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), exportAs: 'dirA'
exportAs: 'dirA' })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div a #a="dirA"></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div a #a="dirA"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [ElementAst, 'div'],
[AttrAst, 'a', ''], [AttrAst, 'a', ''],
@ -1165,17 +1133,16 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
}); });
it('should assign references with empty value to components', () => { it('should assign references with empty value to components', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', isComponent: true,
isComponent: true, type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), exportAs: 'dirA',
exportAs: 'dirA', template: new CompileTemplateMetadata({ngContentSelectors: []})
template: new CompileTemplateMetadata({ngContentSelectors: []}) })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div a #a></div>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div a #a></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [ElementAst, 'div'],
[AttrAst, 'a', ''], [AttrAst, 'a', ''],
@ -1185,14 +1152,13 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
}); });
it('should not locate directives in references', () => { it('should not locate directives in references', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}})
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<div ref-a>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div ref-a>', [dirA]))).toEqual([
[ElementAst, 'div'], [ReferenceAst, 'a', null] [ElementAst, 'div'], [ReferenceAst, 'a', null]
]); ]);
@ -1218,14 +1184,14 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
it('should support references via #...', () => { it('should support references via #...', () => {
expect(humanizeTplAst(parse('<template #a>', []))).toEqual([ expect(humanizeTplAst(parse('<template #a>', []))).toEqual([
[EmbeddedTemplateAst], [EmbeddedTemplateAst],
[ReferenceAst, 'a', resolveIdentifierToken(Identifiers.TemplateRef)] [ReferenceAst, 'a', createIdentifierToken(Identifiers.TemplateRef)]
]); ]);
}); });
it('should support references via ref-...', () => { it('should support references via ref-...', () => {
expect(humanizeTplAst(parse('<template ref-a>', []))).toEqual([ expect(humanizeTplAst(parse('<template ref-a>', []))).toEqual([
[EmbeddedTemplateAst], [EmbeddedTemplateAst],
[ReferenceAst, 'a', resolveIdentifierToken(Identifiers.TemplateRef)] [ReferenceAst, 'a', createIdentifierToken(Identifiers.TemplateRef)]
]); ]);
}); });
@ -1235,14 +1201,13 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
}); });
it('should not locate directives in variables', () => { it('should not locate directives in variables', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}})
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary();
expect(humanizeTplAst(parse('<template let-a="b"></template>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<template let-a="b"></template>', [dirA]))).toEqual([
[EmbeddedTemplateAst], [VariableAst, 'a', 'b'] [EmbeddedTemplateAst], [VariableAst, 'a', 'b']
]); ]);
@ -1281,23 +1246,19 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
describe('directives', () => { describe('directives', () => {
it('should locate directives in property bindings', () => { it('should locate directives in property bindings', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a=b]',
selector: '[a=b]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['a']
inputs: ['a'] })
}) .toSummary();
.toSummary();
const dirB = CompileDirectiveMetadata const dirB = CompileDirectiveMetadata
.create({ .create({
selector: '[b]', selector: '[b]',
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirB'}})
name: 'DirB',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
expect(humanizeTplAst(parse('<div template="a b" b>', [dirA, dirB]))).toEqual([ expect(humanizeTplAst(parse('<div template="a b" b>', [dirA, dirB]))).toEqual([
@ -1311,11 +1272,8 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
const dirA = CompileDirectiveMetadata const dirA = CompileDirectiveMetadata
.create({ .create({
selector: '[a]', selector: '[a]',
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirA'}})
name: 'DirA',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
expect(humanizeTplAst(parse('<div template="let a=b">', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div template="let a=b">', [dirA]))).toEqual([
@ -1327,11 +1285,8 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
const dirA = CompileDirectiveMetadata const dirA = CompileDirectiveMetadata
.create({ .create({
selector: '[a]', selector: '[a]',
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: 'DirA'}})
name: 'DirA',
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
expect(humanizeTplAst(parse('<div ref-a>', [dirA]))).toEqual([ expect(humanizeTplAst(parse('<div ref-a>', [dirA]))).toEqual([
@ -1367,11 +1322,8 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
.create({ .create({
selector: selector, selector: selector,
isComponent: true, isComponent: true,
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: `SomeComp${compCounter++}`}}),
name: `SomeComp${compCounter++}`,
reference: {} as Type<any>
}),
template: new CompileTemplateMetadata({ngContentSelectors: ngContentSelectors}) template: new CompileTemplateMetadata({ngContentSelectors: ngContentSelectors})
}) })
.toSummary(); .toSummary();
@ -1381,11 +1333,8 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
return CompileDirectiveMetadata return CompileDirectiveMetadata
.create({ .create({
selector: selector, selector: selector,
type: new CompileTypeMetadata({ type: new CompileTypeMetadata(
moduleUrl: someModuleUrl, {reference: {filePath: someModuleUrl, name: `SomeDir${compCounter++}`}})
name: `SomeDir${compCounter++}`,
reference: {} as Type<any>
})
}) })
.toSummary(); .toSummary();
} }
@ -1555,15 +1504,14 @@ Can't bind to 'invalidProp' since it isn't a known property of 'div'. ("<div [ER
}); });
it('should report invalid host property names', () => { it('should report invalid host property names', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), host: {'[invalidProp]': 'someProp'}
host: {'[invalidProp]': 'someProp'} })
}) .toSummary();
.toSummary();
expect(() => parse('<div></div>', [dirA])).toThrowError(`Template parse errors: expect(() => parse('<div></div>', [dirA])).toThrowError(`Template parse errors:
Can't bind to 'invalidProp' since it isn't a known property of 'div'. ("[ERROR ->]<div></div>"): TestComp@0:0, Directive DirA`); Can't bind to 'invalidProp' since it isn't a known property of 'div'. ("[ERROR ->]<div></div>"): TestComp@0:0, Directive DirA`);
}); });
@ -1575,39 +1523,36 @@ Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [
it('should not throw on invalid property names if the property is used by a directive', it('should not throw on invalid property names if the property is used by a directive',
() => { () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['invalidProp']
inputs: ['invalidProp'] })
}) .toSummary();
.toSummary();
expect(() => parse('<div [invalid-prop]></div>', [dirA])).not.toThrow(); expect(() => parse('<div [invalid-prop]></div>', [dirA])).not.toThrow();
}); });
it('should not allow more than 1 component per element', () => { it('should not allow more than 1 component per element', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', isComponent: true,
isComponent: true, type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), template: new CompileTemplateMetadata({ngContentSelectors: []})
template: new CompileTemplateMetadata({ngContentSelectors: []}) })
}) .toSummary();
.toSummary(); const dirB = CompileDirectiveMetadata
const dirB = .create({
CompileDirectiveMetadata selector: 'div',
.create({ isComponent: true,
selector: 'div', type: new CompileTypeMetadata(
isComponent: true, {reference: {filePath: someModuleUrl, name: 'DirB'}}),
type: new CompileTypeMetadata( template: new CompileTemplateMetadata({ngContentSelectors: []})
{moduleUrl: someModuleUrl, name: 'DirB', reference: {} as Type<any>}), })
template: new CompileTemplateMetadata({ngContentSelectors: []}) .toSummary();
})
.toSummary();
expect(() => parse('<div>', [dirB, dirA])) expect(() => parse('<div>', [dirB, dirA]))
.toThrowError( .toThrowError(
`Template parse errors:\n` + `Template parse errors:\n` +
@ -1618,16 +1563,15 @@ Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [
it('should not allow components or element bindings nor dom events on explicit embedded templates', it('should not allow components or element bindings nor dom events on explicit embedded templates',
() => { () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', isComponent: true,
isComponent: true, type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), template: new CompileTemplateMetadata({ngContentSelectors: []})
template: new CompileTemplateMetadata({ngContentSelectors: []}) })
}) .toSummary();
.toSummary();
expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA])) expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA]))
.toThrowError(`Template parse errors: .toThrowError(`Template parse errors:
Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "directives" section. ("<template [a]="b" [ERROR ->](e)="f"></template>"): TestComp@0:18 Event binding e not emitted by any directive on an embedded template. Make sure that the event name is spelled correctly and all directives are listed in the "directives" section. ("<template [a]="b" [ERROR ->](e)="f"></template>"): TestComp@0:18
@ -1636,16 +1580,15 @@ Property binding a not used by any directive on an embedded template. Make sure
}); });
it('should not allow components or element bindings on inline embedded templates', () => { it('should not allow components or element bindings on inline embedded templates', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', isComponent: true,
isComponent: true, type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), template: new CompileTemplateMetadata({ngContentSelectors: []})
template: new CompileTemplateMetadata({ngContentSelectors: []}) })
}) .toSummary();
.toSummary();
expect(() => parse('<div *a="b"></div>', [dirA])).toThrowError(`Template parse errors: expect(() => parse('<div *a="b"></div>', [dirA])).toThrowError(`Template parse errors:
Components on an embedded template: DirA ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0 Components on an embedded template: DirA ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0
Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "directives" section. ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0`); Property binding a not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "directives" section. ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0`);
@ -1797,24 +1740,22 @@ Property binding a not used by any directive on an embedded template. Make sure
}); });
it('should support directive', () => { it('should support directive', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: '[a]',
selector: '[a]', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}})
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary(); const comp = CompileDirectiveMetadata
const comp = .create({
CompileDirectiveMetadata selector: 'div',
.create({ isComponent: true,
selector: 'div', type: new CompileTypeMetadata(
isComponent: true, {reference: {filePath: someModuleUrl, name: 'ZComp'}}),
type: new CompileTypeMetadata( template: new CompileTemplateMetadata({ngContentSelectors: []})
{moduleUrl: someModuleUrl, name: 'ZComp', reference: {} as Type<any>}), })
template: new CompileTemplateMetadata({ngContentSelectors: []}) .toSummary();
})
.toSummary();
expect(humanizeTplAstSourceSpans(parse('<div a>', [dirA, comp]))).toEqual([ expect(humanizeTplAstSourceSpans(parse('<div a>', [dirA, comp]))).toEqual([
[ElementAst, 'div', '<div a>'], [AttrAst, 'a', '', 'a'], [ElementAst, 'div', '<div a>'], [AttrAst, 'a', '', 'a'],
[DirectiveAst, dirA, '<div a>'], [DirectiveAst, comp, '<div a>'] [DirectiveAst, dirA, '<div a>'], [DirectiveAst, comp, '<div a>']
@ -1822,22 +1763,20 @@ Property binding a not used by any directive on an embedded template. Make sure
}); });
it('should support directive in namespace', () => { it('should support directive in namespace', () => {
const tagSel = const tagSel = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'circle',
selector: 'circle', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'elDir'}})
{moduleUrl: someModuleUrl, name: 'elDir', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary(); const attrSel = CompileDirectiveMetadata
const attrSel = .create({
CompileDirectiveMetadata selector: '[href]',
.create({ type: new CompileTypeMetadata(
selector: '[href]', {reference: {filePath: someModuleUrl, name: 'attrDir'}})
type: new CompileTypeMetadata( })
{moduleUrl: someModuleUrl, name: 'attrDir', reference: {} as Type<any>}) .toSummary();
})
.toSummary();
expect(humanizeTplAstSourceSpans( expect(humanizeTplAstSourceSpans(
parse('<svg><circle /><use xlink:href="Port" /></svg>', [tagSel, attrSel]))) parse('<svg><circle /><use xlink:href="Port" /></svg>', [tagSel, attrSel])))
@ -1852,15 +1791,14 @@ Property binding a not used by any directive on an embedded template. Make sure
}); });
it('should support directive property', () => { it('should support directive property', () => {
const dirA = const dirA = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'div',
selector: 'div', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}}),
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}), inputs: ['aProp']
inputs: ['aProp'] })
}) .toSummary();
.toSummary();
expect(humanizeTplAstSourceSpans(parse('<div [aProp]="foo"></div>', [dirA]))).toEqual([ expect(humanizeTplAstSourceSpans(parse('<div [aProp]="foo"></div>', [dirA]))).toEqual([
[ElementAst, 'div', '<div [aProp]="foo">'], [ElementAst, 'div', '<div [aProp]="foo">'],
[DirectiveAst, dirA, '<div [aProp]="foo">'], [DirectiveAst, dirA, '<div [aProp]="foo">'],
@ -1869,14 +1807,13 @@ Property binding a not used by any directive on an embedded template. Make sure
}); });
it('should support endSourceSpan for elements', () => { it('should support endSourceSpan for elements', () => {
const tagSel = const tagSel = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'circle',
selector: 'circle', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'elDir'}})
{moduleUrl: someModuleUrl, name: 'elDir', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary();
const result = parse('<circle></circle>', [tagSel]); const result = parse('<circle></circle>', [tagSel]);
const circle = result[0] as ElementAst; const circle = result[0] as ElementAst;
expect(circle.endSourceSpan).toBeDefined(); expect(circle.endSourceSpan).toBeDefined();
@ -1885,22 +1822,20 @@ Property binding a not used by any directive on an embedded template. Make sure
}); });
it('should report undefined for endSourceSpan for elements without an end-tag', () => { it('should report undefined for endSourceSpan for elements without an end-tag', () => {
const ulSel = const ulSel = CompileDirectiveMetadata
CompileDirectiveMetadata .create({
.create({ selector: 'ul',
selector: 'ul', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'ulDir'}})
{moduleUrl: someModuleUrl, name: 'ulDir', reference: {} as Type<any>}) })
}) .toSummary();
.toSummary(); const liSel = CompileDirectiveMetadata
const liSel = .create({
CompileDirectiveMetadata selector: 'li',
.create({ type: new CompileTypeMetadata(
selector: 'li', {reference: {filePath: someModuleUrl, name: 'liDir'}})
type: new CompileTypeMetadata( })
{moduleUrl: someModuleUrl, name: 'liDir', reference: {} as Type<any>}) .toSummary();
})
.toSummary();
const result = parse('<ul><li><li></ul>', [ulSel, liSel]); const result = parse('<ul><li><li></ul>', [ulSel, liSel]);
const ul = result[0] as ElementAst; const ul = result[0] as ElementAst;
const li = ul.children[0] as ElementAst; const li = ul.children[0] as ElementAst;
@ -1910,12 +1845,11 @@ Property binding a not used by any directive on an embedded template. Make sure
describe('pipes', () => { describe('pipes', () => {
it('should allow pipes that have been defined as dependencies', () => { it('should allow pipes that have been defined as dependencies', () => {
const testPipe = const testPipe = new CompilePipeMetadata({
new CompilePipeMetadata({ name: 'test',
name: 'test', type: new CompileTypeMetadata(
type: new CompileTypeMetadata( {reference: {filePath: someModuleUrl, name: 'DirA'}})
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}) }).toSummary();
}).toSummary();
expect(() => parse('{{a | test}}', [], [testPipe])).not.toThrow(); expect(() => parse('{{a | test}}', [], [testPipe])).not.toThrow();
}); });

View File

@ -57,7 +57,7 @@ function createCompileView(config: {className: string, parent?: CompileView, fie
config.fields.forEach((fieldName) => { fields.push(new o.ClassField(fieldName)); }); config.fields.forEach((fieldName) => { fields.push(new o.ClassField(fieldName)); });
} }
return <any>{ return <any>{
classType: o.importType(new CompileIdentifierMetadata({name: config.className})), classType: o.importType(new CompileIdentifierMetadata()),
fields: fields, fields: fields,
getters: [], getters: [],
declarationElement: declarationElement declarationElement: declarationElement

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {StaticSymbol} from '@angular/compiler'; import {StaticSymbol, identifierName, tokenReference} from '@angular/compiler';
import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead} from '@angular/compiler/src/expression_parser/ast'; import {AST, ASTWithSource, AstVisitor, Binary, BindingPipe, Chain, Conditional, FunctionCall, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, PrefixNot, PropertyRead, PropertyWrite, Quote, SafeMethodCall, SafePropertyRead} from '@angular/compiler/src/expression_parser/ast';
import {ElementAst, EmbeddedTemplateAst, ReferenceAst, TemplateAst, templateVisitAll} from '@angular/compiler/src/template_parser/template_ast'; import {ElementAst, EmbeddedTemplateAst, ReferenceAst, TemplateAst, templateVisitAll} from '@angular/compiler/src/template_parser/template_ast';
@ -667,7 +667,7 @@ function getReferences(info: TemplateInfo): SymbolDeclaration[] {
for (const reference of references) { for (const reference of references) {
let type: Symbol; let type: Symbol;
if (reference.value) { if (reference.value) {
type = info.template.query.getTypeSymbol(reference.value.reference); type = info.template.query.getTypeSymbol(tokenReference(reference.value));
} }
result.push({ result.push({
name: reference.name, name: reference.name,
@ -740,7 +740,8 @@ function getVarDeclarations(info: TemplateInfo, path: TemplateAstPath): SymbolDe
function refinedVariableType( function refinedVariableType(
type: Symbol, info: TemplateInfo, templateElement: EmbeddedTemplateAst): Symbol { type: Symbol, info: TemplateInfo, templateElement: EmbeddedTemplateAst): Symbol {
// Special case the ngFor directive // Special case the ngFor directive
const ngForDirective = templateElement.directives.find(d => d.directive.type.name == 'NgFor'); const ngForDirective =
templateElement.directives.find(d => identifierName(d.directive.type) == 'NgFor');
if (ngForDirective) { if (ngForDirective) {
const ngForOfBinding = ngForDirective.inputs.find(i => i.directiveName == 'ngForOf'); const ngForOfBinding = ngForDirective.inputs.find(i => i.directiveName == 'ngForOf');
if (ngForOfBinding) { if (ngForOfBinding) {

View File

@ -107,9 +107,9 @@ class LanguageServiceImpl implements LanguageService {
getTemplateAst(template: TemplateSource, contextFile: string): AstResult { getTemplateAst(template: TemplateSource, contextFile: string): AstResult {
let result: AstResult; let result: AstResult;
try { try {
const directive = const {metadata} =
this.metadataResolver.getNonNormalizedDirectiveMetadata(template.type as any); this.metadataResolver.getNonNormalizedDirectiveMetadata(template.type as any);
if (directive) { if (metadata) {
const rawHtmlParser = new HtmlParser(); const rawHtmlParser = new HtmlParser();
const htmlParser = new I18NHtmlParser(rawHtmlParser); const htmlParser = new I18NHtmlParser(rawHtmlParser);
const expressionParser = new Parser(new Lexer()); const expressionParser = new Parser(new Lexer());
@ -125,15 +125,17 @@ class LanguageServiceImpl implements LanguageService {
} }
if (ngModule) { if (ngModule) {
const directives = ngModule.transitiveModule.directives.map( const directives = ngModule.transitiveModule.directives.map(
d => this.host.resolver.getNonNormalizedDirectiveMetadata(d.reference).toSummary()); d => this.host.resolver.getNonNormalizedDirectiveMetadata(d.reference)
.metadata.toSummary());
const pipes = ngModule.transitiveModule.pipes.map( const pipes = ngModule.transitiveModule.pipes.map(
p => this.host.resolver.getOrLoadPipeMetadata(p.reference).toSummary()); p => this.host.resolver.getOrLoadPipeMetadata(p.reference).toSummary());
const schemas = ngModule.schemas; const schemas = ngModule.schemas;
const parseResult = parser.tryParseHtml( const parseResult = parser.tryParseHtml(
htmlResult, directive, template.source, directives, pipes, schemas, ''); htmlResult, metadata, template.source, directives, pipes, schemas, '');
result = { result = {
htmlAst: htmlResult.rootNodes, htmlAst: htmlResult.rootNodes,
templateAst: parseResult.templateAst, directive, directives, pipes, templateAst: parseResult.templateAst,
directive: metadata, directives, pipes,
parseErrors: parseResult.errors, expressionParser, errors parseErrors: parseResult.errors, expressionParser, errors
}; };
} }

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {tokenReference} from '@angular/compiler';
import {AST} from '@angular/compiler/src/expression_parser/ast'; import {AST} from '@angular/compiler/src/expression_parser/ast';
import {Attribute} from '@angular/compiler/src/ml_parser/ast'; import {Attribute} from '@angular/compiler/src/ml_parser/ast';
import {BoundDirectivePropertyAst, BoundEventAst, ElementAst, TemplateAst} from '@angular/compiler/src/template_parser/template_ast'; import {BoundDirectivePropertyAst, BoundEventAst, ElementAst, TemplateAst} from '@angular/compiler/src/template_parser/template_ast';
@ -67,7 +68,7 @@ export function locateSymbol(info: TemplateInfo): SymbolInfo {
} }
}, },
visitReference(ast) { visitReference(ast) {
symbol = info.template.query.getTypeSymbol(ast.value.reference); symbol = info.template.query.getTypeSymbol(tokenReference(ast.value));
span = spanOf(ast); span = spanOf(ast);
}, },
visitVariable(ast) {}, visitVariable(ast) {},

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {CompileDirectiveMetadata, CompilerConfig, StaticReflector, StaticSymbol, StaticSymbolCache, createOfflineCompileUrlResolver} from '@angular/compiler'; import {CompileDirectiveMetadata, CompilerConfig, StaticReflector, StaticSymbol, StaticSymbolCache, componentModuleUrl, createOfflineCompileUrlResolver} from '@angular/compiler';
import {NgAnalyzedModules, analyzeNgModules, extractProgramSymbols} from '@angular/compiler/src/aot/compiler'; import {NgAnalyzedModules, analyzeNgModules, extractProgramSymbols} from '@angular/compiler/src/aot/compiler';
import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer'; import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer';
import {DirectiveResolver} from '@angular/compiler/src/directive_resolver'; import {DirectiveResolver} from '@angular/compiler/src/directive_resolver';
@ -235,12 +235,12 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
const urlResolver = createOfflineCompileUrlResolver(); const urlResolver = createOfflineCompileUrlResolver();
for (const module of ngModuleSummary.ngModules) { for (const module of ngModuleSummary.ngModules) {
for (const directive of module.declaredDirectives) { for (const directive of module.declaredDirectives) {
const directiveMetadata = const {metadata, annotation} =
this.resolver.getNonNormalizedDirectiveMetadata(directive.reference); this.resolver.getNonNormalizedDirectiveMetadata(directive.reference);
if (directiveMetadata.isComponent && directiveMetadata.template && if (metadata.isComponent && metadata.template && metadata.template.templateUrl) {
directiveMetadata.template.templateUrl) { const templateName = urlResolver.resolve(
const templateName = componentModuleUrl(this.reflector, directive.reference, annotation),
urlResolver.resolve(directive.moduleUrl, directiveMetadata.template.templateUrl); metadata.template.templateUrl);
fileToComponent.set(templateName, directive.reference); fileToComponent.set(templateName, directive.reference);
templateReference.push(templateName); templateReference.push(templateName);
} }
@ -427,7 +427,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
this._reflector.getStaticSymbol(sourceFile.fileName, classDeclaration.name.text); this._reflector.getStaticSymbol(sourceFile.fileName, classDeclaration.name.text);
try { try {
if (this.resolver.isDirective(staticSymbol as any)) { if (this.resolver.isDirective(staticSymbol as any)) {
const metadata = const {metadata} =
this.resolver.getNonNormalizedDirectiveMetadata(staticSymbol as any); this.resolver.getNonNormalizedDirectiveMetadata(staticSymbol as any);
return {type: staticSymbol, declarationSpan: spanOf(target), metadata}; return {type: staticSymbol, declarationSpan: spanOf(target), metadata};
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {CompileDirectiveSummary, CompileTypeMetadata} from '@angular/compiler'; import {CompileDirectiveSummary, CompileTypeMetadata, identifierName} from '@angular/compiler';
import {ParseSourceSpan} from '@angular/compiler/src/parse_util'; import {ParseSourceSpan} from '@angular/compiler/src/parse_util';
import {CssSelector, SelectorMatcher} from '@angular/compiler/src/selector'; import {CssSelector, SelectorMatcher} from '@angular/compiler/src/selector';
@ -56,7 +56,8 @@ export function isNarrower(spanA: Span, spanB: Span): boolean {
export function hasTemplateReference(type: CompileTypeMetadata): boolean { export function hasTemplateReference(type: CompileTypeMetadata): boolean {
if (type.diDeps) { if (type.diDeps) {
for (let diDep of type.diDeps) { for (let diDep of type.diDeps) {
if (diDep.token.identifier && diDep.token.identifier.name == 'TemplateRef') return true; if (diDep.token.identifier && identifierName(diDep.token.identifier) == 'TemplateRef')
return true;
} }
} }
return false; return false;

View File

@ -11,7 +11,6 @@ if [ $# -eq 0 ]
else else
cd `dirname $0` cd `dirname $0`
rm -rf dist/tools rm -rf dist/tools
rm -rf dist/all
if [ -z ${NODE_PATH+x} ]; then if [ -z ${NODE_PATH+x} ]; then
export NODE_PATH=$(pwd)/dist/all:$(pwd)/dist/tools export NODE_PATH=$(pwd)/dist/all:$(pwd)/dist/tools
else else