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 {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {ANY_STATE, DEFAULT_STATE, EMPTY_STATE} from '../private_import_core';
@ -69,8 +69,8 @@ class _AnimationBuilder implements AnimationAstVisitor {
stylesArr.push(o.literalMap(entries));
});
return o.importExpr(resolveIdentifier(Identifiers.AnimationStyles)).instantiate([
o.importExpr(resolveIdentifier(Identifiers.collectAndResolveStyles)).callFn([
return o.importExpr(createIdentifier(Identifiers.AnimationStyles)).instantiate([
o.importExpr(createIdentifier(Identifiers.collectAndResolveStyles)).callFn([
_ANIMATION_COLLECTED_STYLES, o.literalArr(stylesArr)
])
]);
@ -78,7 +78,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
visitAnimationKeyframe(ast: AnimationKeyframeAst, context: _AnimationBuilderContext):
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)
]);
}
@ -100,7 +100,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
const startingStylesExpr = ast.startingStyles.visit(this, context);
const keyframeExpressions = ast.keyframes.map(keyframe => keyframe.visit(this, context));
const keyframesExpr =
o.importExpr(resolveIdentifier(Identifiers.balanceAnimationKeyframes)).callFn([
o.importExpr(createIdentifier(Identifiers.balanceAnimationKeyframes)).callFn([
_ANIMATION_COLLECTED_STYLES, _ANIMATION_END_STATE_STYLES_VAR,
o.literalArr(keyframeExpressions)
]);
@ -127,14 +127,14 @@ class _AnimationBuilder implements AnimationAstVisitor {
visitAnimationSequence(ast: AnimationSequenceAst, context: _AnimationBuilderContext):
o.Expression {
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)
]);
}
visitAnimationGroup(ast: AnimationGroupAst, context: _AnimationBuilderContext): o.Expression {
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)
]);
}
@ -228,7 +228,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
_ANIMATION_END_STATE_STYLES_VAR.equals(o.NULL_EXPR),
[_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)));
@ -237,7 +237,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
statements.push(new o.IfStmt(
_ANIMATION_PLAYER_VAR.equals(o.NULL_EXPR),
[_ANIMATION_PLAYER_VAR
.set(o.importExpr(resolveIdentifier(Identifiers.NoOpAnimationPlayer)).instantiate([]))
.set(o.importExpr(createIdentifier(Identifiers.NoOpAnimationPlayer)).instantiate([]))
.toStmt()]));
// once complete we want to apply the styles on the element
@ -255,17 +255,18 @@ class _AnimationBuilder implements AnimationAstVisitor {
.callFn([
_ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(
resolveIdentifier(Identifiers.prepareFinalAnimationStyles))
.callFn([
_ANIMATION_START_STATE_STYLES_VAR,
_ANIMATION_END_STATE_STYLES_VAR
])
createIdentifier(Identifiers.prepareFinalAnimationStyles))
.callFn(
[
_ANIMATION_START_STATE_STYLES_VAR,
_ANIMATION_END_STATE_STYLES_VAR
])
])
.toStmt()
])])
.toStmt());
statements.push(o.importExpr(resolveIdentifier(Identifiers.AnimationSequencePlayer))
statements.push(o.importExpr(createIdentifier(Identifiers.AnimationSequencePlayer))
.instantiate([_PREVIOUS_ANIMATION_PLAYERS])
.callMethod('destroy', [])
.toStmt());
@ -276,7 +277,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
statements.push(RENDER_STYLES_FN
.callFn([
_ANIMATION_FACTORY_ELEMENT_VAR, _ANIMATION_FACTORY_RENDERER_VAR,
o.importExpr(resolveIdentifier(Identifiers.clearStyles))
o.importExpr(createIdentifier(Identifiers.clearStyles))
.callFn([_ANIMATION_START_STATE_STYLES_VAR])
])
.toStmt());
@ -291,7 +292,7 @@ class _AnimationBuilder implements AnimationAstVisitor {
.toStmt());
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_TIME_VAR
])));
@ -300,12 +301,12 @@ class _AnimationBuilder implements AnimationAstVisitor {
[
new o.FnParam(
_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_CURRENT_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 {

View File

@ -8,7 +8,7 @@
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 {isBlank, isPresent} from '../facade/lang';
import {ParseError} from '../parse_util';
@ -41,7 +41,7 @@ export class AnimationParser {
parseComponent(component: CompileDirectiveMetadata): AnimationEntryAst[] {
const errors: string[] = [];
const componentName = component.type.name;
const componentName = identifierName(component.type);
const animationTriggerNames = new Set<string>();
const asts = component.template.animations.map(entry => {
const result = this.parseEntry(entry);

View File

@ -10,11 +10,11 @@ import {SchemaMetadata} from '@angular/core';
import {AnimationCompiler} from '../animation/animation_compiler';
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 {DirectiveWrapperCompileResult, DirectiveWrapperCompiler} from '../directive_wrapper_compiler';
import {ListWrapper} from '../facade/collection';
import {Identifiers, resolveIdentifier, resolveIdentifierToken} from '../identifiers';
import {Identifiers, createIdentifier, createIdentifierToken} from '../identifiers';
import {CompileMetadataResolver} from '../metadata_resolver';
import {NgModuleCompiler} from '../ng_module_compiler';
import {OutputEmitter} from '../output/abstract_emitter';
@ -82,7 +82,7 @@ export class AotCompiler {
const ngModule = ngModuleByPipeOrDirective.get(dirType);
if (!ngModule) {
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);
@ -114,14 +114,14 @@ export class AotCompiler {
if (this._localeId) {
providers.push(new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.LOCALE_ID),
token: createIdentifierToken(Identifiers.LOCALE_ID),
useValue: this._localeId,
}));
}
if (this._translationFormat) {
providers.push(new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.TRANSLATIONS_FORMAT),
token: createIdentifierToken(Identifiers.TRANSLATIONS_FORMAT),
useValue: this._translationFormat
}));
}
@ -129,8 +129,8 @@ export class AotCompiler {
const appCompileResult = this._ngModuleCompiler.compile(ngModule, providers);
appCompileResult.dependencies.forEach((dep) => {
dep.placeholder.name = _componentFactoryName(dep.comp);
dep.placeholder.moduleUrl = _ngfactoryModuleUrl(dep.comp.moduleUrl);
dep.placeholder.reference = this._staticReflector.getStaticSymbol(
_ngfactoryModuleUrl(identifierModuleUrl(dep.comp)), _componentFactoryName(dep.comp));
});
targetStatements.push(...appCompileResult.statements);
@ -149,14 +149,17 @@ export class AotCompiler {
private _compileComponentFactory(
compMeta: CompileDirectiveMetadata, ngModule: CompileNgModuleMetadata, fileSuffix: 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(
hostMeta, ngModule, [compMeta.type], null, fileSuffix, targetStatements);
const compFactoryVar = _componentFactoryName(compMeta.type);
targetStatements.push(
o.variable(compFactoryVar)
.set(o.importExpr(resolveIdentifier(Identifiers.ComponentFactory), [o.importType(
compMeta.type)])
.set(o.importExpr(
createIdentifier(Identifiers.ComponentFactory), [o.importType(compMeta.type)])
.instantiate(
[
o.literal(compMeta.selector),
@ -164,7 +167,7 @@ export class AotCompiler {
o.importExpr(compMeta.type),
],
o.importType(
resolveIdentifier(Identifiers.ComponentFactory),
createIdentifier(Identifiers.ComponentFactory),
[o.importType(compMeta.type)], [o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]));
return compFactoryVar;
@ -182,23 +185,24 @@ export class AotCompiler {
const parsedTemplate = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, ngModule.schemas,
compMeta.type.name);
identifierName(compMeta.type));
const stylesExpr = componentStyles ? o.variable(componentStyles.stylesVar) : o.literalArr([]);
const compiledAnimations =
this._animationCompiler.compile(compMeta.type.name, parsedAnimations);
this._animationCompiler.compile(identifierName(compMeta.type), parsedAnimations);
const viewResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, stylesExpr, pipes, compiledAnimations);
if (componentStyles) {
targetStatements.push(..._resolveStyleStatements(componentStyles, fileSuffix));
targetStatements.push(
..._resolveStyleStatements(this._staticReflector, componentStyles, fileSuffix));
}
compiledAnimations.forEach(entry => targetStatements.push(...entry.statements));
targetStatements.push(..._resolveViewStatements(viewResult));
targetStatements.push(..._resolveViewStatements(this._staticReflector, viewResult));
return viewResult.viewClassVar;
}
private _codgenStyles(
fileUrl: string, stylesCompileResult: CompiledStylesheet, fileSuffix: string): SourceModule {
_resolveStyleStatements(stylesCompileResult, fileSuffix);
_resolveStyleStatements(this._staticReflector, stylesCompileResult, fileSuffix);
return this._codegenSourceModule(
fileUrl, _stylesModuleUrl(
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) => {
if (dep instanceof ViewClassDependency) {
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) {
const cfd = <ComponentFactoryDependency>dep;
cfd.placeholder.name = _componentFactoryName(cfd.comp);
cfd.placeholder.moduleUrl = _ngfactoryModuleUrl(cfd.comp.moduleUrl);
cfd.placeholder.reference = reflector.getStaticSymbol(
_ngfactoryModuleUrl(identifierModuleUrl(cfd.comp)), _componentFactoryName(cfd.comp));
} else if (dep instanceof DirectiveWrapperDependency) {
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;
@ -233,9 +240,11 @@ function _resolveViewStatements(compileResult: ViewCompileResult): o.Statement[]
function _resolveStyleStatements(
compileResult: CompiledStylesheet, fileSuffix: string): o.Statement[] {
reflector: StaticReflector, compileResult: CompiledStylesheet,
fileSuffix: string): o.Statement[] {
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;
}
@ -246,7 +255,7 @@ function _ngfactoryModuleUrl(dirUrl: string): string {
}
function _componentFactoryName(comp: CompileIdentifierMetadata): string {
return `${comp.name}NgFactory`;
return `${identifierName(comp)}NgFactory`;
}
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) {
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 {StaticSymbol, isStaticSymbol} from './aot/static_symbol';
import {ListWrapper} from './facade/collection';
import {isPresent} from './facade/lang';
import {LifecycleHooks} from './private_import_core';
import {isPresent, stringify} from './facade/lang';
import {LifecycleHooks, reflector} from './private_import_core';
import {CssSelector} from './selector';
import {sanitizeIdentifier, splitAtColon} from './util';
import {splitAtColon} from './util';
function unimplemented(): any {
throw new Error('unimplemented');
@ -24,10 +25,6 @@ function unimplemented(): any {
// group 3: "@trigger" from "@trigger"
const HOST_REG_EXP = /^(?:(?:\[([^\]]+)\])|(?:\(([^\)]+)\)))|(\@[-\w]+)$/;
export abstract class CompileMetadataWithIdentifier {
get identifier(): CompileIdentifierMetadata { return <CompileIdentifierMetadata>unimplemented(); }
}
export class CompileAnimationEntryMetadata {
constructor(
public name: string = null, public definitions: CompileAnimationStateMetadata[] = null) {}
@ -78,24 +75,47 @@ export class CompileAnimationGroupMetadata extends CompileAnimationWithStepsMeta
constructor(steps: CompileAnimationMetadata[] = null) { super(steps); }
}
export class CompileIdentifierMetadata implements CompileMetadataWithIdentifier {
reference: any;
name: string;
prefix: string;
moduleUrl: string;
value: any;
constructor(
{reference, name, moduleUrl, prefix, value}:
{reference?: any, name?: string, moduleUrl?: string, prefix?: string, value?: any} = {}) {
this.reference = reference;
this.name = name;
this.prefix = prefix;
this.moduleUrl = moduleUrl;
this.value = value;
function _sanitizeIdentifier(name: string): string {
return name.replace(/\W/g, '_');
}
let _anonymousTypeIndex = 0;
export function identifierName(compileIdentifier: CompileIdentifierMetadata): string {
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 {
diDeps: CompileDiDependencyMetadata[];
constructor({reference, name, moduleUrl, prefix, diDeps, value}: {
reference?: Function,
name?: string,
prefix?: string,
moduleUrl?: string,
value?: boolean,
diDeps?: CompileDiDependencyMetadata[]
}) {
super({reference: reference, name: name, prefix: prefix, moduleUrl: moduleUrl, value: value});
constructor({reference, diDeps}: {reference?: Function, diDeps?: CompileDiDependencyMetadata[]}) {
super({reference: reference});
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;
identifier: CompileIdentifierMetadata;
identifierIsInstance: boolean;
constructor(
{value, identifier, identifierIsInstance}:
{value?: any, identifier?: CompileIdentifierMetadata, identifierIsInstance?: boolean}) {
constructor({value, identifier}: {value?: any, identifier?: CompileIdentifierMetadata}) {
this.value = value;
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.
*/
export class CompileTypeMetadata extends CompileIdentifierMetadata {
isHost: boolean;
diDeps: CompileDiDependencyMetadata[];
lifecycleHooks: LifecycleHooks[];
constructor({reference, name, moduleUrl, prefix, isHost, value, diDeps, lifecycleHooks}: {
reference?: Type<any>,
name?: string,
moduleUrl?: string,
prefix?: string,
isHost?: boolean,
value?: any,
constructor({reference, diDeps, lifecycleHooks}: {
reference?: Type<any>| StaticSymbol,
diDeps?: CompileDiDependencyMetadata[],
lifecycleHooks?: LifecycleHooks[];
} = {}) {
super({reference: reference, name: name, moduleUrl: moduleUrl, prefix: prefix, value: value});
this.isHost = !!isHost;
super({reference: reference});
this.diDeps = _normalizeArray(diDeps);
this.lifecycleHooks = _normalizeArray(lifecycleHooks);
}
@ -355,10 +358,11 @@ export interface CompileDirectiveSummary extends CompileSummary {
/**
* Metadata regarding compilation of a directive.
*/
export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
export class CompileDirectiveMetadata {
static create(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host, providers,
viewProviders, queries, viewQueries, entryComponents, template}: {
{isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
providers, viewProviders, queries, viewQueries, entryComponents, template}: {
isHost?: boolean,
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
@ -412,6 +416,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
}
return new CompileDirectiveMetadata({
isHost,
type,
isComponent: !!isComponent, selector, exportAs, changeDetection,
inputs: inputsMap,
@ -427,6 +432,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
template,
});
}
isHost: boolean;
type: CompileTypeMetadata;
isComponent: boolean;
selector: string;
@ -446,9 +452,10 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
template: CompileTemplateMetadata;
constructor(
{type, isComponent, selector, exportAs, changeDetection, inputs, outputs, hostListeners,
hostProperties, hostAttributes, providers, viewProviders, queries, viewQueries,
entryComponents, template}: {
{isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs,
hostListeners, hostProperties, hostAttributes, providers, viewProviders, queries,
viewQueries, entryComponents, template}: {
isHost?: boolean,
type?: CompileTypeMetadata,
isComponent?: boolean,
selector?: string,
@ -468,6 +475,7 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
entryComponents?: CompileIdentifierMetadata[],
template?: CompileTemplateMetadata,
} = {}) {
this.isHost = !!isHost;
this.type = type;
this.isComponent = isComponent;
this.selector = selector;
@ -487,8 +495,6 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
this.template = template;
}
get identifier(): CompileIdentifierMetadata { return this.type; }
toSummary(): CompileDirectiveSummary {
return {
isSummary: true,
@ -514,16 +520,12 @@ export class CompileDirectiveMetadata implements CompileMetadataWithIdentifier {
/**
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
*/
export function createHostComponentMeta(compMeta: CompileDirectiveMetadata):
CompileDirectiveMetadata {
export function createHostComponentMeta(
typeReference: any, compMeta: CompileDirectiveMetadata): CompileDirectiveMetadata {
const template = CssSelector.parse(compMeta.selector)[0].getMatchingElementTemplate();
return CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({
reference: Object,
name: `${compMeta.type.name}_Host`,
moduleUrl: compMeta.type.moduleUrl,
isHost: true
}),
isHost: true,
type: new CompileTypeMetadata({reference: typeReference}),
template: new CompileTemplateMetadata({
encapsulation: ViewEncapsulation.None,
template: template,
@ -553,7 +555,7 @@ export interface CompilePipeSummary extends CompileSummary {
pure: boolean;
}
export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
export class CompilePipeMetadata {
type: CompileTypeMetadata;
name: string;
pure: boolean;
@ -567,7 +569,6 @@ export class CompilePipeMetadata implements CompileMetadataWithIdentifier {
this.name = name;
this.pure = !!pure;
}
get identifier(): CompileIdentifierMetadata { return this.type; }
toSummary(): CompilePipeSummary {
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.
*/
export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
export class CompileNgModuleMetadata {
type: CompileTypeMetadata;
declaredDirectives: CompileIdentifierMetadata[];
exportedDirectives: CompileIdentifierMetadata[];
@ -649,8 +650,6 @@ export class CompileNgModuleMetadata implements CompileMetadataWithIdentifier {
this.transitiveModule = transitiveModule;
}
get identifier(): CompileIdentifierMetadata { return this.type; }
toSummary(): CompileNgModuleSummary {
return {
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[] {
return obj || [];
}

View File

@ -6,7 +6,7 @@
* 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 * 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...
builder.fields.push(new o.ClassField(fieldExpr.name, null, [o.StmtModifier.Private]));
builder.ctorStmts.push(o.THIS_EXPR.prop(fieldExpr.name)
.set(o.importExpr(resolveIdentifier(Identifiers.UNINITIALIZED)))
.set(o.importExpr(createIdentifier(Identifiers.UNINITIALIZED)))
.toStmt());
return new CheckBindingField(fieldExpr, bindingId);
}
@ -30,7 +30,7 @@ export function createCheckBindingField(builder: ClassBuilder): CheckBindingFiel
export function createCheckBindingStmt(
evalResult: ConvertPropertyBindingResult, fieldExpr: o.ReadPropExpr,
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
]);
if (evalResult.forceUpdate) {

View File

@ -9,7 +9,7 @@
import * as cdAst from '../expression_parser/ast';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import {ClassBuilder} from '../output/class_builder';
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)) {
unwrapperStmts.push(
VAL_UNWRAPPER_VAR
.set(o.importExpr(resolveIdentifier(Identifiers.ValueUnwrapper)).instantiate([]))
.set(o.importExpr(createIdentifier(Identifiers.ValueUnwrapper)).instantiate([]))
.toDeclStmt(null, [o.StmtModifier.Final]));
}
return unwrapperStmts;
@ -277,8 +277,8 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
args.push(o.literal(ast.strings[ast.strings.length - 1]));
return ast.expressions.length <= 9 ?
o.importExpr(resolveIdentifier(Identifiers.inlineInterpolate)).callFn(args) :
o.importExpr(resolveIdentifier(Identifiers.interpolate)).callFn([
o.importExpr(createIdentifier(Identifiers.inlineInterpolate)).callFn(args) :
o.importExpr(createIdentifier(Identifiers.interpolate)).callFn([
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 {
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 proxyParams: o.FnParam[] = [];
@ -599,7 +599,7 @@ function createCachedLiteralArray(builder: ClassBuilder, values: o.Expression[])
function createCachedLiteralMap(
builder: ClassBuilder, entries: [string, o.Expression][]): o.Expression {
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 proxyParams: o.FnParam[] = [];

View File

@ -8,15 +8,12 @@
import {CompileTokenMetadata} from '../compile_metadata';
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';
export function createDiTokenExpression(token: CompileTokenMetadata): o.Expression {
if (isPresent(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 {
return o.importExpr(token.identifier);
}
@ -24,13 +21,13 @@ export function createDiTokenExpression(token: CompileTokenMetadata): o.Expressi
export function createInlineArray(values: o.Expression[]): o.Expression {
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 index = Math.ceil(log2);
const identifierSpec = index < Identifiers.inlineArrays.length ? Identifiers.inlineArrays[index] :
Identifiers.InlineArrayDynamic;
const identifier = resolveIdentifier(identifierSpec);
const identifier = createIdentifier(identifierSpec);
return o.importExpr(identifier).instantiate([
<o.Expression>o.literal(values.length)
].concat(values));
@ -46,7 +43,7 @@ export function createPureProxy(
throw new Error(`Unsupported number of argument for pure functions: ${argCount}`);
}
builder.ctorStmts.push(o.THIS_EXPR.prop(pureProxyProp.name)
.set(o.importExpr(resolveIdentifier(pureProxyId)).callFn([fn]))
.set(o.importExpr(createIdentifier(pureProxyId)).callFn([fn]))
.toStmt());
}
@ -56,5 +53,5 @@ export function createEnumExpression(enumType: IdentifierSpec, enumValue: any):
if (!enumName) {
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 {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {EMPTY_STATE as EMPTY_ANIMATION_STATE} from '../private_import_core';
import {BoundElementPropertyAst, BoundEventAst, PropertyBindingType} from '../template_parser/template_ast';
@ -26,7 +26,7 @@ export function writeToRenderer(
case PropertyBindingType.Property:
if (logBindingUpdate) {
updateStmts.push(
o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfo))
o.importExpr(createIdentifier(Identifiers.setBindingDebugInfo))
.callFn([renderer, renderElement, o.literal(boundProp.name), renderValue])
.toStmt());
}
@ -104,7 +104,7 @@ export function triggerAnimation(
// it's important to normalize the void value as `void` explicitly
// so that the styles data can be obtained from the stringmap
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);
updateStmts.push(

View File

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

View File

@ -8,13 +8,13 @@
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 {EventHandlerVars, convertActionBinding, convertPropertyBinding} from './compiler_util/expression_converter';
import {triggerAnimation, writeToRenderer} from './compiler_util/render_util';
import {CompilerConfig} from './config';
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 {ClassBuilder, createClassStmt} from './output/class_builder';
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()
export class DirectiveWrapperCompiler {
static dirWrapperClassName(id: CompileIdentifierMetadata) { return `Wrapper_${id.name}`; }
static dirWrapperClassName(id: CompileIdentifierMetadata) {
return `Wrapper_${identifierName(id)}`;
}
constructor(
private compilerConfig: CompilerConfig, private _exprParser: Parser,
@ -117,10 +119,10 @@ class DirectiveWrapperBuilder implements ClassBuilder {
[
new o.FnParam(
VIEW_VAR.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
o.importType(createIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
new o.FnParam(
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),
],
this.detachStmts),
@ -172,7 +174,7 @@ function addNgDoCheckMethod(builder: DirectiveWrapperBuilder) {
}
if (builder.compilerConfig.logBindingUpdate) {
onChangesStmts.push(
o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfoForChanges))
o.importExpr(createIdentifier(Identifiers.setBindingDebugInfoForChanges))
.callFn(
[VIEW_VAR.prop('renderer'), RENDER_EL_VAR, o.THIS_EXPR.prop(CHANGES_FIELD_NAME)])
.toStmt());
@ -198,7 +200,7 @@ function addNgDoCheckMethod(builder: DirectiveWrapperBuilder) {
'ngDoCheck',
[
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(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
],
@ -214,7 +216,7 @@ function addCheckInputMethod(input: string, builder: DirectiveWrapperBuilder) {
if (builder.genChanges) {
onChangeStatements.push(o.THIS_EXPR.prop(CHANGES_FIELD_NAME)
.key(o.literal(input))
.set(o.importExpr(resolveIdentifier(Identifiers.SimpleChange))
.set(o.importExpr(createIdentifier(Identifiers.SimpleChange))
.instantiate([field.expression, CURR_VALUE_VAR]))
.toStmt());
}
@ -237,10 +239,10 @@ function addCheckHostMethod(
const stmts: o.Statement[] = [];
const methodParams: 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(
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(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
];
@ -255,14 +257,14 @@ function addCheckHostMethod(
if (hostProp.needsRuntimeSecurityContext) {
securityContextExpr = o.variable(`secCtx_${methodParams.length}`);
methodParams.push(new o.FnParam(
securityContextExpr.name, o.importType(resolveIdentifier(Identifiers.SecurityContext))));
securityContextExpr.name, o.importType(createIdentifier(Identifiers.SecurityContext))));
}
let checkBindingStmts: o.Statement[];
if (hostProp.isAnimation) {
const {updateStmts, detachStmts} = triggerAnimation(
VIEW_VAR, COMPONENT_VIEW_VAR, hostProp,
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);
checkBindingStmts = updateStmts;
builder.detachStmts.push(...detachStmts);
@ -306,7 +308,7 @@ function addHandleEventMethod(hostListeners: BoundEventAst[], builder: Directive
function addSubscribeMethod(dirMeta: CompileDirectiveMetadata, builder: DirectiveWrapperBuilder) {
const methodParams: 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)
];
const stmts: o.Statement[] = [
@ -348,9 +350,10 @@ function parseHostBindings(
const errors: ParseError[] = [];
const parser =
new BindingParser(exprParser, DEFAULT_INTERPOLATION_CONFIG, schemaRegistry, [], errors);
const sourceFileName = dirMeta.type.moduleUrl ?
`in Directive ${dirMeta.type.name} in ${dirMeta.type.moduleUrl}` :
`in Directive ${dirMeta.type.name}`;
const moduleUrl = identifierModuleUrl(dirMeta.type);
const sourceFileName = moduleUrl ?
`in Directive ${identifierName(dirMeta.type)} in ${moduleUrl}` :
`in Directive ${identifierName(dirMeta.type)}`;
const sourceFile = new ParseSourceFile('', sourceFileName);
const sourceSpan = new ParseSourceSpan(
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 {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';
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) {
let moduleUrl = identifier.moduleUrl;
return reflector.resolveIdentifier(identifier.name, identifier.moduleUrl, identifier.runtime);
}
export function createIdentifier(identifier: IdentifierSpec) {
const reference =
reflector.resolveIdentifier(identifier.name, identifier.moduleUrl, identifier.runtime);
if (isStaticSymbol(reference)) {
moduleUrl = reference.filePath;
}
return new CompileIdentifierMetadata(
{name: identifier.name, moduleUrl: moduleUrl, reference: reference});
return new CompileIdentifierMetadata({reference: reference});
}
export function identifierToken(identifier: CompileIdentifierMetadata): CompileTokenMetadata {
return new CompileTokenMetadata({identifier: identifier});
}
export function resolveIdentifierToken(identifier: IdentifierSpec): CompileTokenMetadata {
return identifierToken(resolveIdentifier(identifier));
export function createIdentifierToken(identifier: IdentifierSpec): CompileTokenMetadata {
return identifierToken(createIdentifier(identifier));
}
export function resolveEnumIdentifier(
enumType: CompileIdentifierMetadata, name: string): CompileIdentifierMetadata {
const resolvedEnum = reflector.resolveEnum(enumType.reference, name);
return new CompileIdentifierMetadata(
{name: `${enumType.name}.${name}`, moduleUrl: enumType.moduleUrl, reference: resolvedEnum});
export function createEnumIdentifier(
enumType: IdentifierSpec, name: string): CompileIdentifierMetadata {
const resolvedEnum = reflector.resolveEnum(resolveIdentifier(enumType), name);
return new CompileIdentifierMetadata({reference: resolvedEnum});
}

View File

@ -10,7 +10,7 @@ import {Compiler, ComponentFactory, Injectable, Injector, ModuleWithComponentFac
import {AnimationCompiler} from '../animation/animation_compiler';
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 {DirectiveNormalizer} from '../directive_normalizer';
import {DirectiveWrapperCompiler} from '../directive_wrapper_compiler';
@ -126,14 +126,13 @@ export class JitCompiler implements Compiler {
compileResult.dependencies.forEach((dep) => {
dep.placeholder.reference =
this._assertComponentKnown(dep.comp.reference, true).proxyComponentFactory;
dep.placeholder.name = `compFactory_${dep.comp.name}`;
});
if (!this._compilerConfig.useJit) {
ngModuleFactory =
interpretStatements(compileResult.statements, compileResult.ngModuleFactoryVar);
} else {
ngModuleFactory = jitStatements(
`/${moduleMeta.type.name}/module.ngfactory.js`, compileResult.statements,
`/${identifierName(moduleMeta.type)}/module.ngfactory.js`, compileResult.statements,
compileResult.ngModuleFactoryVar);
}
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
@ -215,7 +214,12 @@ export class JitCompiler implements Compiler {
if (!compiledTemplate) {
const compMeta = this._metadataResolver.getDirectiveMetadata(compType);
assertComponent(compMeta);
const hostMeta = createHostComponentMeta(compMeta);
class HostClass {
static overriddenName = `${identifierName(compMeta.type)}_Host`;
}
const hostMeta = createHostComponentMeta(HostClass, compMeta);
compiledTemplate = new CompiledTemplate(
true, compMeta.selector, compMeta.type, hostMeta, ngModule, [compMeta.type]);
this._compiledHostTemplateCache.set(compType, compiledTemplate);
@ -264,8 +268,8 @@ export class JitCompiler implements Compiler {
directiveWrapperClass = interpretStatements(statements, compileResult.dirWrapperClassVar);
} else {
directiveWrapperClass = jitStatements(
`/${moduleMeta.type.name}/${dirMeta.type.name}/wrapper.ngfactory.js`, statements,
compileResult.dirWrapperClassVar);
`/${identifierName(moduleMeta.type)}/${identifierName(dirMeta.type)}/wrapper.ngfactory.js`,
statements, compileResult.dirWrapperClassVar);
}
this._compiledDirectiveWrapperCache.set(dirMeta.type.reference, directiveWrapperClass);
}
@ -288,9 +292,9 @@ export class JitCompiler implements Compiler {
pipe => this._metadataResolver.getPipeSummary(pipe.reference));
const parsedTemplate = this._templateParser.parse(
compMeta, compMeta.template.template, directives, pipes, template.ngModule.schemas,
compMeta.type.name);
identifierName(compMeta.type));
const compiledAnimations =
this._animationCompiler.compile(compMeta.type.name, parsedAnimations);
this._animationCompiler.compile(identifierName(compMeta.type), parsedAnimations);
const compileResult = this._viewCompiler.compileComponent(
compMeta, parsedTemplate, ir.variable(stylesCompileResult.componentStylesheet.stylesVar),
pipes, compiledAnimations);
@ -300,12 +304,10 @@ export class JitCompiler implements Compiler {
const vfd = <ViewClassDependency>dep;
depTemplate = this._assertComponentKnown(vfd.comp.reference, false);
vfd.placeholder.reference = depTemplate.proxyViewClass;
vfd.placeholder.name = `View_${vfd.comp.name}`;
} else if (dep instanceof ComponentFactoryDependency) {
const cfd = <ComponentFactoryDependency>dep;
depTemplate = this._assertComponentKnown(cfd.comp.reference, true);
cfd.placeholder.reference = depTemplate.proxyComponentFactory;
cfd.placeholder.name = `compFactory_${cfd.comp.name}`;
} else if (dep instanceof DirectiveWrapperDependency) {
const dwd = <DirectiveWrapperDependency>dep;
dwd.placeholder.reference = this._assertDirectiveWrapper(dwd.dir.reference);
@ -319,7 +321,7 @@ export class JitCompiler implements Compiler {
viewClass = interpretStatements(statements, compileResult.viewClassVar);
} else {
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);
}
template.compiled(viewClass);
@ -332,7 +334,6 @@ export class JitCompiler implements Compiler {
const nestedStylesArr = this._resolveAndEvalStylesCompileResult(
nestedCompileResult, externalStylesheetsByModuleUrl);
dep.valuePlaceholder.reference = nestedStylesArr;
dep.valuePlaceholder.name = `importedStyles${i}`;
});
}
@ -380,7 +381,8 @@ class CompiledTemplate {
function assertComponent(meta: CompileDirectiveMetadata) {
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
*/
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 {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
@ -15,14 +15,14 @@ import {DirectiveNormalizer} from './directive_normalizer';
import {DirectiveResolver} from './directive_resolver';
import {ListWrapper, StringMapWrapper} from './facade/collection';
import {isBlank, isPresent, stringify} from './facade/lang';
import {Identifiers, resolveIdentifierToken} from './identifiers';
import {Identifiers, createIdentifierToken, resolveIdentifier} from './identifiers';
import {hasLifecycleHook} from './lifecycle_reflector';
import {NgModuleResolver} from './ng_module_resolver';
import {PipeResolver} from './pipe_resolver';
import {ComponentStillLoadingError, LIFECYCLE_HOOKS_VALUES, ReflectorReader, reflector} from './private_import_core';
import {ElementSchemaRegistry} from './schema/element_schema_registry';
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 _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>();
private _ngModuleOfTypes = new Map<Type<any>, Type<any>>();
private _anonymousTypes = new Map<Object, number>();
private _anonymousTypeIndex = 0;
constructor(
private _ngModuleResolver: NgModuleResolver, private _directiveResolver: DirectiveResolver,
@ -50,20 +48,6 @@ export class CompileMetadataResolver {
private _directiveNormalizer: DirectiveNormalizer,
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>) {
const dirMeta = this._directiveCache.get(type);
this._directiveCache.delete(type);
@ -147,25 +131,25 @@ export class CompileMetadataResolver {
return;
}
directiveType = resolveForwardRef(directiveType);
const nonNormalizedMetadata = this.getNonNormalizedDirectiveMetadata(directiveType);
const {annotation, metadata} = this.getNonNormalizedDirectiveMetadata(directiveType);
const createDirectiveMetadata = (templateMetadata: cpl.CompileTemplateMetadata) => {
const normalizedDirMeta = new cpl.CompileDirectiveMetadata({
type: nonNormalizedMetadata.type,
isComponent: nonNormalizedMetadata.isComponent,
selector: nonNormalizedMetadata.selector,
exportAs: nonNormalizedMetadata.exportAs,
changeDetection: nonNormalizedMetadata.changeDetection,
inputs: nonNormalizedMetadata.inputs,
outputs: nonNormalizedMetadata.outputs,
hostListeners: nonNormalizedMetadata.hostListeners,
hostProperties: nonNormalizedMetadata.hostProperties,
hostAttributes: nonNormalizedMetadata.hostAttributes,
providers: nonNormalizedMetadata.providers,
viewProviders: nonNormalizedMetadata.viewProviders,
queries: nonNormalizedMetadata.queries,
viewQueries: nonNormalizedMetadata.viewQueries,
entryComponents: nonNormalizedMetadata.entryComponents,
type: metadata.type,
isComponent: metadata.isComponent,
selector: metadata.selector,
exportAs: metadata.exportAs,
changeDetection: metadata.changeDetection,
inputs: metadata.inputs,
outputs: metadata.outputs,
hostListeners: metadata.hostListeners,
hostProperties: metadata.hostProperties,
hostAttributes: metadata.hostAttributes,
providers: metadata.providers,
viewProviders: metadata.viewProviders,
queries: metadata.queries,
viewQueries: metadata.viewQueries,
entryComponents: metadata.entryComponents,
template: templateMetadata
});
this._directiveCache.set(directiveType, normalizedDirMeta);
@ -173,17 +157,17 @@ export class CompileMetadataResolver {
return normalizedDirMeta;
};
if (nonNormalizedMetadata.isComponent) {
if (metadata.isComponent) {
const templateMeta = this._directiveNormalizer.normalizeTemplate({
componentType: directiveType,
moduleUrl: nonNormalizedMetadata.type.moduleUrl,
encapsulation: nonNormalizedMetadata.template.encapsulation,
template: nonNormalizedMetadata.template.template,
templateUrl: nonNormalizedMetadata.template.templateUrl,
styles: nonNormalizedMetadata.template.styles,
styleUrls: nonNormalizedMetadata.template.styleUrls,
animations: nonNormalizedMetadata.template.animations,
interpolation: nonNormalizedMetadata.template.interpolation
moduleUrl: componentModuleUrl(this._reflector, directiveType, annotation),
encapsulation: metadata.template.encapsulation,
template: metadata.template.template,
templateUrl: metadata.template.templateUrl,
styles: metadata.template.styles,
styleUrls: metadata.template.styleUrls,
animations: metadata.template.animations,
interpolation: metadata.template.interpolation
});
if (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);
const dirMeta = this._directiveResolver.resolve(directiveType);
if (!dirMeta) {
return null;
}
let moduleUrl = staticTypeModuleUrl(directiveType);
let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata;
if (dirMeta instanceof Component) {
// component
moduleUrl = componentModuleUrl(this._reflector, directiveType, dirMeta);
assertArrayOfStrings('styles', dirMeta.styles);
assertArrayOfStrings('styleUrls', dirMeta.styleUrls);
assertInterpolationSymbols('interpolation', dirMeta.interpolation);
@ -246,10 +229,9 @@ export class CompileMetadataResolver {
`viewProviders for "${stringify(directiveType)}"`);
}
if (dirMeta.entryComponents) {
entryComponentMetadata =
flattenAndDedupeArray(dirMeta.entryComponents)
.map((type) => this._getIdentifierMetadata(type, staticTypeModuleUrl(type)))
.concat(entryComponentMetadata);
entryComponentMetadata = flattenAndDedupeArray(dirMeta.entryComponents)
.map((type) => this._getIdentifierMetadata(type))
.concat(entryComponentMetadata);
}
if (!selector) {
selector = this._schemaRegistry.getDefaultComponentElementName();
@ -273,11 +255,11 @@ export class CompileMetadataResolver {
viewQueries = this._getQueriesMetadata(dirMeta.queries, true, directiveType);
}
return cpl.CompileDirectiveMetadata.create({
const metadata = cpl.CompileDirectiveMetadata.create({
selector: selector,
exportAs: dirMeta.exportAs,
isComponent: !!nonNormalizedTemplateMetadata,
type: this._getTypeMetadata(directiveType, moduleUrl),
type: this._getTypeMetadata(directiveType),
template: nonNormalizedTemplateMetadata,
changeDetection: changeDetectionStrategy,
inputs: dirMeta.inputs,
@ -289,6 +271,7 @@ export class CompileMetadataResolver {
viewQueries: viewQueries,
entryComponents: entryComponentMetadata
});
return {metadata, annotation: dirMeta};
}
/**
@ -420,8 +403,7 @@ export class CompileMetadataResolver {
if (exportedModuleSummary) {
exportedModules.push(exportedModuleSummary);
} else {
exportedNonModuleIdentifiers.push(
this._getIdentifierMetadata(exportedType, staticTypeModuleUrl(exportedType)));
exportedNonModuleIdentifiers.push(this._getIdentifierMetadata(exportedType));
}
});
}
@ -435,8 +417,7 @@ export class CompileMetadataResolver {
throw new Error(
`Unexpected value '${stringify(declaredType)}' declared by the module '${stringify(moduleType)}'`);
}
const declaredIdentifier =
this._getIdentifierMetadata(declaredType, staticTypeModuleUrl(declaredType));
const declaredIdentifier = this._getIdentifierMetadata(declaredType);
if (this._directiveResolver.isDirective(declaredType)) {
transitiveModule.directivesSet.add(declaredType);
transitiveModule.directives.push(declaredIdentifier);
@ -479,8 +460,7 @@ export class CompileMetadataResolver {
if (meta.entryComponents) {
entryComponents.push(
...flattenAndDedupeArray(meta.entryComponents)
.map(type => this._getTypeMetadata(type, staticTypeModuleUrl(type))));
...flattenAndDedupeArray(meta.entryComponents).map(type => this._getTypeMetadata(type)));
}
if (meta.bootstrap) {
@ -489,7 +469,7 @@ export class CompileMetadataResolver {
throw new Error(
`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);
}
@ -504,7 +484,7 @@ export class CompileMetadataResolver {
transitiveModule.providers.push(...providers);
compileMeta = new cpl.CompileNgModuleMetadata({
type: this._getTypeMetadata(moduleType, staticTypeModuleUrl(moduleType)),
type: this._getTypeMetadata(moduleType),
providers,
entryComponents,
bootstrapComponents,
@ -575,19 +555,14 @@ export class CompileMetadataResolver {
transitiveModules, providers, entryComponents, directives, pipes, directiveLoaders);
}
private _getIdentifierMetadata(type: Type<any>, moduleUrl: string):
cpl.CompileIdentifierMetadata {
private _getIdentifierMetadata(type: Type<any>): cpl.CompileIdentifierMetadata {
type = resolveForwardRef(type);
return new cpl.CompileIdentifierMetadata(
{name: this.sanitizeTokenName(type), moduleUrl, reference: type});
return new cpl.CompileIdentifierMetadata({reference: type});
}
private _getTypeMetadata(type: Type<any>, moduleUrl: string, dependencies: any[] = null):
cpl.CompileTypeMetadata {
const identifier = this._getIdentifierMetadata(type, moduleUrl);
private _getTypeMetadata(type: Type<any>, dependencies: any[] = null): cpl.CompileTypeMetadata {
const identifier = this._getIdentifierMetadata(type);
return new cpl.CompileTypeMetadata({
name: identifier.name,
moduleUrl: identifier.moduleUrl,
reference: identifier.reference,
diDeps: this._getDependenciesMetadata(identifier.reference, dependencies),
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 {
factory = resolveForwardRef(factory);
return new cpl.CompileFactoryMetadata({
name: this.sanitizeTokenName(factory),
moduleUrl,
reference: factory,
diDeps: this._getDependenciesMetadata(factory, dependencies)
});
return new cpl.CompileFactoryMetadata(
{reference: factory, diDeps: this._getDependenciesMetadata(factory, dependencies)});
}
/**
@ -641,7 +612,7 @@ export class CompileMetadataResolver {
const pipeAnnotation = this._pipeResolver.resolve(pipeType);
const pipeMeta = new cpl.CompilePipeMetadata({
type: this._getTypeMetadata(pipeType, staticTypeModuleUrl(pipeType)),
type: this._getTypeMetadata(pipeType),
name: pipeAnnotation.name,
pure: pipeAnnotation.pure
});
@ -716,13 +687,8 @@ export class CompileMetadataResolver {
if (typeof token === 'string') {
compileToken = new cpl.CompileTokenMetadata({value: token});
} else {
compileToken = new cpl.CompileTokenMetadata({
identifier: new cpl.CompileIdentifierMetadata({
reference: token,
name: this.sanitizeTokenName(token),
moduleUrl: staticTypeModuleUrl(token)
})
});
compileToken = new cpl.CompileTokenMetadata(
{identifier: new cpl.CompileIdentifierMetadata({reference: token})});
}
return compileToken;
}
@ -741,14 +707,14 @@ export class CompileMetadataResolver {
compileProvider = this._getProvidersMetadata(provider, targetEntryComponents, debugInfo);
} else if (provider instanceof cpl.ProviderMeta) {
const tokenMeta = this._getTokenMetadata(provider.token);
if (tokenMeta.reference ===
resolveIdentifierToken(Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS).reference) {
if (cpl.tokenReference(tokenMeta) ===
resolveIdentifier(Identifiers.ANALYZE_FOR_ENTRY_COMPONENTS)) {
targetEntryComponents.push(...this._getEntryComponentsFromProvider(provider));
} else {
compileProvider = this.getProviderMetadata(provider);
}
} else if (isValidType(provider)) {
compileProvider = this._getTypeMetadata(provider, staticTypeModuleUrl(provider));
compileProvider = this._getTypeMetadata(provider);
} else {
const providersInfo =
(<string[]>providers.reduce(
@ -803,12 +769,10 @@ export class CompileMetadataResolver {
let compileFactoryMetadata: cpl.CompileFactoryMetadata = null;
if (provider.useClass) {
compileTypeMetadata = this._getTypeMetadata(
provider.useClass, staticTypeModuleUrl(provider.useClass), provider.dependencies);
compileTypeMetadata = this._getTypeMetadata(provider.useClass, provider.dependencies);
compileDeps = compileTypeMetadata.diDeps;
} else if (provider.useFactory) {
compileFactoryMetadata = this._getFactoryMetadata(
provider.useFactory, staticTypeModuleUrl(provider.useFactory), provider.dependencies);
compileFactoryMetadata = this._getFactoryMetadata(provider.useFactory, provider.dependencies);
compileDeps = compileFactoryMetadata.diDeps;
}
@ -925,14 +889,10 @@ function isValidType(value: any): boolean {
return isStaticSymbol(value) || (value instanceof Type);
}
function staticTypeModuleUrl(value: any): string {
return isStaticSymbol(value) ? value.filePath : null;
}
function componentModuleUrl(
export function componentModuleUrl(
reflector: ReflectorReader, type: Type<any>, cmpMetadata: Component): string {
if (isStaticSymbol(type)) {
return staticTypeModuleUrl(type);
return type.filePath;
}
const moduleId = cmpMetadata.moduleId;
@ -956,13 +916,7 @@ function convertToCompileValue(
class _CompileValueConverter extends ValueTransformer {
visitOther(value: any, targetIdentifiers: cpl.CompileIdentifierMetadata[]): any {
let identifier: cpl.CompileIdentifierMetadata;
if (isStaticSymbol(value)) {
identifier = new cpl.CompileIdentifierMetadata(
{name: value.name, moduleUrl: value.filePath, reference: value});
} else {
identifier = new cpl.CompileIdentifierMetadata({reference: value});
}
const identifier = new cpl.CompileIdentifierMetadata({reference: value});
targetIdentifiers.push(identifier);
return identifier;
}

View File

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

View File

@ -7,6 +7,7 @@
*/
import {identifierModuleUrl, identifierName} from '../compile_metadata';
import {isBlank, isPresent} from '../facade/lang';
import {EmitterVisitorContext, OutputEmitter} from './abstract_emitter';
@ -38,18 +39,21 @@ class JsEmitterVisitor extends AbstractJsEmitterVisitor {
constructor(private _moduleUrl: string) { super(); }
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}`);
}
if (isPresent(ast.value.moduleUrl) && ast.value.moduleUrl != this._moduleUrl) {
let prefix = this.importsWithPrefixes.get(ast.value.moduleUrl);
if (isPresent(moduleUrl) && moduleUrl != this._moduleUrl) {
let prefix = this.importsWithPrefixes.get(moduleUrl);
if (isBlank(prefix)) {
prefix = `import${this.importsWithPrefixes.size}`;
this.importsWithPrefixes.set(ast.value.moduleUrl, prefix);
this.importsWithPrefixes.set(moduleUrl, prefix);
}
ctx.print(`${prefix}.`);
}
ctx.print(ast.value.name);
ctx.print(name);
return null;
}
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(
public value: CompileIdentifierMetadata, public typeParams: Type[] = null,
public value: Expression, public typeParams: Type[] = null,
modifiers: TypeModifier[] = null) {
super(modifiers);
}
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 {
visitBuiltintType(type: BuiltinType, context: any): any;
visitExternalType(type: ExternalType, context: any): any;
visitExpressionType(type: ExpressionType, context: any): any;
visitArrayType(type: ArrayType, context: any): any;
visitMapType(type: MapType, context: any): any;
}
@ -876,8 +876,14 @@ export function importExpr(id: CompileIdentifierMetadata, typeParams: Type[] = n
export function importType(
id: CompileIdentifierMetadata, typeParams: Type[] = null,
typeModifiers: TypeModifier[] = null): ExternalType {
return isPresent(id) ? new ExternalType(id, typeParams, typeModifiers) : null;
typeModifiers: TypeModifier[] = null): ExpressionType {
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 {

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {identifierName} from '../compile_metadata';
import {isPresent} from '../facade/lang';
import {sanitizeIdentifier} from '../util';
import {EmitterVisitorContext} from './abstract_emitter';
import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
@ -52,8 +52,8 @@ class JitEmitterVisitor extends AbstractJsEmitterVisitor {
if (id === -1) {
id = this._evalArgValues.length;
this._evalArgValues.push(value);
const name = isPresent(ast.value.name) ? sanitizeIdentifier(ast.value.name) : 'val';
this._evalArgNames.push(sanitizeIdentifier(`jit_${name}${id}`));
const name = identifierName(ast.value) || 'val';
this._evalArgNames.push(`jit_${name}${id}`);
}
ctx.print(this._evalArgNames[id]);
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 {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;
}
visitExternalType(ast: o.ExternalType, ctx: EmitterVisitorContext): any {
this._visitIdentifier(ast.value, ast.typeParams, ctx);
visitExpressionType(ast: o.ExpressionType, ctx: EmitterVisitorContext): any {
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;
}
@ -317,14 +322,16 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
private _visitIdentifier(
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}`);
}
if (isPresent(value.moduleUrl) && value.moduleUrl != this._moduleUrl) {
let prefix = this.importsWithPrefixes.get(value.moduleUrl);
if (isPresent(moduleUrl) && moduleUrl != this._moduleUrl) {
let prefix = this.importsWithPrefixes.get(moduleUrl);
if (isBlank(prefix)) {
prefix = `import${this.importsWithPrefixes.size}`;
this.importsWithPrefixes.set(value.moduleUrl, prefix);
this.importsWithPrefixes.set(moduleUrl, prefix);
}
ctx.print(`${prefix}.`);
}
@ -333,7 +340,7 @@ class _TsEmitterVisitor extends AbstractEmitterVisitor implements o.TypeVisitor
ctx.print('.');
ctx.print(value.reference.members.join('.'));
} else {
ctx.print(value.name);
ctx.print(name);
}
if (isPresent(typeParams) && typeParams.length > 0) {
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 {Identifiers, resolveIdentifierToken} from './identifiers';
import {Identifiers, createIdentifierToken, resolveIdentifier} from './identifiers';
import {ParseError, ParseSourceSpan} from './parse_util';
import {AttrAst, DirectiveAst, ProviderAst, ProviderAstType, ReferenceAst} from './template_parser/template_ast';
@ -32,8 +32,8 @@ export class ProviderViewContext {
this.viewQueries = _getViewQueries(component);
this.viewProviders = new Map<any, boolean>();
_normalizeProviders(component.viewProviders, sourceSpan, this.errors).forEach((provider) => {
if (isBlank(this.viewProviders.get(provider.token.reference))) {
this.viewProviders.set(provider.token.reference, true);
if (isBlank(this.viewProviders.get(tokenReference(provider.token)))) {
this.viewProviders.set(tokenReference(provider.token), true);
}
});
}
@ -65,14 +65,13 @@ export class ProviderElementContext {
refs.forEach((refAst) => {
this._addQueryReadsTo(new CompileTokenMetadata({value: refAst.name}), queriedTokens);
});
if (isPresent(
queriedTokens.get(resolveIdentifierToken(Identifiers.ViewContainerRef).reference))) {
if (isPresent(queriedTokens.get(resolveIdentifier(Identifiers.ViewContainerRef)))) {
this._hasViewContainer = true;
}
// create the providers that we know are eager first
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) {
this._getOrCreateLocalProvider(provider.providerType, provider.token, true);
}
@ -104,8 +103,8 @@ export class ProviderElementContext {
private _addQueryReadsTo(token: CompileTokenMetadata, queryReadTokens: Map<any, boolean>) {
this._getQueriesFor(token).forEach((query) => {
const queryReadToken = query.read || token;
if (isBlank(queryReadTokens.get(queryReadToken.reference))) {
queryReadTokens.set(queryReadToken.reference, true);
if (isBlank(queryReadTokens.get(tokenReference(queryReadToken)))) {
queryReadTokens.set(tokenReference(queryReadToken), true);
}
});
}
@ -116,7 +115,7 @@ export class ProviderElementContext {
let distance = 0;
let queries: CompileQueryMetadata[];
while (currentEl !== null) {
queries = currentEl._contentQueries.get(token.reference);
queries = currentEl._contentQueries.get(tokenReference(token));
if (isPresent(queries)) {
result.push(...queries.filter((query) => query.descendants || distance <= 1));
}
@ -125,7 +124,7 @@ export class ProviderElementContext {
}
currentEl = currentEl._parent;
}
queries = this.viewContext.viewQueries.get(token.reference);
queries = this.viewContext.viewQueries.get(tokenReference(token));
if (isPresent(queries)) {
result.push(...queries);
}
@ -136,7 +135,7 @@ export class ProviderElementContext {
private _getOrCreateLocalProvider(
requestingProviderType: ProviderAstType, token: CompileTokenMetadata,
eager: boolean): ProviderAst {
const resolvedProvider = this._allProviders.get(token.reference);
const resolvedProvider = this._allProviders.get(tokenReference(token));
if (!resolvedProvider || ((requestingProviderType === ProviderAstType.Directive ||
requestingProviderType === ProviderAstType.PublicService) &&
resolvedProvider.providerType === ProviderAstType.PrivateService) ||
@ -145,16 +144,16 @@ export class ProviderElementContext {
resolvedProvider.providerType === ProviderAstType.Builtin)) {
return null;
}
let transformedProviderAst = this._transformedProviders.get(token.reference);
let transformedProviderAst = this._transformedProviders.get(tokenReference(token));
if (isPresent(transformedProviderAst)) {
return transformedProviderAst;
}
if (isPresent(this._seenProviders.get(token.reference))) {
if (isPresent(this._seenProviders.get(tokenReference(token)))) {
this.viewContext.errors.push(new ProviderError(
`Cannot instantiate cyclic dependency! ${token.name}`, this._sourceSpan));
`Cannot instantiate cyclic dependency! ${tokenName(token)}`, this._sourceSpan));
return null;
}
this._seenProviders.set(token.reference, true);
this._seenProviders.set(tokenReference(token), true);
const transformedProviders = resolvedProvider.providers.map((provider) => {
let transformedUseValue = provider.useValue;
let transformedUseExisting = provider.useExisting;
@ -186,7 +185,7 @@ export class ProviderElementContext {
});
transformedProviderAst =
_transformProviderAst(resolvedProvider, {eager: eager, providers: transformedProviders});
this._transformedProviders.set(token.reference, transformedProviderAst);
this._transformedProviders.set(tokenReference(token), transformedProviderAst);
return transformedProviderAst;
}
@ -203,20 +202,18 @@ export class ProviderElementContext {
// access builtints
if ((requestingProviderType === ProviderAstType.Directive ||
requestingProviderType === ProviderAstType.Component)) {
if (dep.token.reference === resolveIdentifierToken(Identifiers.Renderer).reference ||
dep.token.reference === resolveIdentifierToken(Identifiers.ElementRef).reference ||
dep.token.reference ===
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference ||
dep.token.reference === resolveIdentifierToken(Identifiers.TemplateRef).reference) {
if (tokenReference(dep.token) === resolveIdentifier(Identifiers.Renderer) ||
tokenReference(dep.token) === resolveIdentifier(Identifiers.ElementRef) ||
tokenReference(dep.token) === resolveIdentifier(Identifiers.ChangeDetectorRef) ||
tokenReference(dep.token) === resolveIdentifier(Identifiers.TemplateRef)) {
return dep;
}
if (dep.token.reference ===
resolveIdentifierToken(Identifiers.ViewContainerRef).reference) {
if (tokenReference(dep.token) === resolveIdentifier(Identifiers.ViewContainerRef)) {
this._hasViewContainer = true;
}
}
// access the injector
if (dep.token.reference === resolveIdentifierToken(Identifiers.Injector).reference) {
if (tokenReference(dep.token) === resolveIdentifier(Identifiers.Injector)) {
return dep;
}
// access providers
@ -252,9 +249,9 @@ export class ProviderElementContext {
}
// check @Host restriction
if (!result) {
if (!dep.isHost || this.viewContext.component.type.isHost ||
this.viewContext.component.type.reference === dep.token.reference ||
isPresent(this.viewContext.viewProviders.get(dep.token.reference))) {
if (!dep.isHost || this.viewContext.component.isHost ||
this.viewContext.component.type.reference === tokenReference(dep.token) ||
isPresent(this.viewContext.viewProviders.get(tokenReference(dep.token)))) {
result = dep;
} else {
result = dep.isOptional ?
@ -265,7 +262,7 @@ export class ProviderElementContext {
}
if (!result) {
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;
}
@ -308,20 +305,21 @@ export class NgModuleProviderAnalyzer {
}
private _getOrCreateLocalProvider(token: CompileTokenMetadata, eager: boolean): ProviderAst {
const resolvedProvider = this._allProviders.get(token.reference);
const resolvedProvider = this._allProviders.get(tokenReference(token));
if (!resolvedProvider) {
return null;
}
let transformedProviderAst = this._transformedProviders.get(token.reference);
let transformedProviderAst = this._transformedProviders.get(tokenReference(token));
if (isPresent(transformedProviderAst)) {
return transformedProviderAst;
}
if (isPresent(this._seenProviders.get(token.reference))) {
if (isPresent(this._seenProviders.get(tokenReference(token)))) {
this._errors.push(new ProviderError(
`Cannot instantiate cyclic dependency! ${token.name}`, resolvedProvider.sourceSpan));
`Cannot instantiate cyclic dependency! ${tokenName(token)}`,
resolvedProvider.sourceSpan));
return null;
}
this._seenProviders.set(token.reference, true);
this._seenProviders.set(tokenReference(token), true);
const transformedProviders = resolvedProvider.providers.map((provider) => {
let transformedUseValue = provider.useValue;
let transformedUseExisting = provider.useExisting;
@ -353,7 +351,7 @@ export class NgModuleProviderAnalyzer {
});
transformedProviderAst =
_transformProviderAst(resolvedProvider, {eager: eager, providers: transformedProviders});
this._transformedProviders.set(token.reference, transformedProviderAst);
this._transformedProviders.set(tokenReference(token), transformedProviderAst);
return transformedProviderAst;
}
@ -363,9 +361,8 @@ export class NgModuleProviderAnalyzer {
let foundLocal = false;
if (!dep.isSkipSelf && isPresent(dep.token)) {
// access the injector
if (dep.token.reference === resolveIdentifierToken(Identifiers.Injector).reference ||
dep.token.reference ===
resolveIdentifierToken(Identifiers.ComponentFactoryResolver).reference) {
if (tokenReference(dep.token) === resolveIdentifier(Identifiers.Injector) ||
tokenReference(dep.token) === resolveIdentifier(Identifiers.ComponentFactoryResolver)) {
foundLocal = true;
// access providers
} else if (isPresent(this._getOrCreateLocalProvider(dep.token, eager))) {
@ -378,7 +375,7 @@ export class NgModuleProviderAnalyzer {
result = new CompileDiDependencyMetadata({isValue: true, value: null});
} else {
this._errors.push(
new ProviderError(`No provider for ${dep.token.name}`, requestorSourceSpan));
new ProviderError(`No provider for ${tokenName(dep.token)}`, requestorSourceSpan));
}
}
return result;
@ -471,10 +468,10 @@ function _resolveProviders(
sourceSpan: ParseSourceSpan, targetErrors: ParseError[],
targetProvidersByToken: Map<any, ProviderAst>) {
providers.forEach((provider) => {
let resolvedProvider = targetProvidersByToken.get(provider.token.reference);
let resolvedProvider = targetProvidersByToken.get(tokenReference(provider.token));
if (isPresent(resolvedProvider) && resolvedProvider.multiProvider !== provider.multi) {
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));
}
if (!resolvedProvider) {
@ -485,7 +482,7 @@ function _resolveProviders(
resolvedProvider = new ProviderAst(
provider.token, provider.multi, eager || lifecycleHooks.length > 0, [provider],
providerType, lifecycleHooks, sourceSpan);
targetProvidersByToken.set(provider.token.reference, resolvedProvider);
targetProvidersByToken.set(tokenReference(provider.token), resolvedProvider);
} else {
if (!provider.multi) {
resolvedProvider.providers.length = 0;
@ -517,10 +514,10 @@ function _getContentQueries(directives: CompileDirectiveSummary[]):
function _addQueryToTokenMap(map: Map<any, CompileQueryMetadata[]>, query: CompileQueryMetadata) {
query.selectors.forEach((token: CompileTokenMetadata) => {
let entry = map.get(token.reference);
let entry = map.get(tokenReference(token));
if (!entry) {
entry = [];
map.set(token.reference, entry);
map.set(tokenReference(token), entry);
}
entry.push(query);
});

View File

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

View File

@ -8,12 +8,12 @@
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 {Parser} from '../expression_parser/parser';
import {isPresent} from '../facade/lang';
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 {ParseTreeResult} from '../ml_parser/html_parser';
import {expandNodes} from '../ml_parser/icu_ast_expander';
@ -546,7 +546,8 @@ class TemplateParseVisitor implements html.Visitor {
let component: CompileDirectiveSummary = null;
const directiveAsts = directives.map((directive) => {
const sourceSpan = new ParseSourceSpan(
elementSourceSpan.start, elementSourceSpan.end, `Directive ${directive.type.name}`);
elementSourceSpan.start, elementSourceSpan.end,
`Directive ${identifierName(directive.type)}`);
if (directive.isComponent) {
component = directive;
}
@ -579,7 +580,7 @@ class TemplateParseVisitor implements html.Visitor {
} else if (!component) {
let refToken: CompileTokenMetadata = null;
if (isTemplateElement) {
refToken = resolveIdentifierToken(Identifiers.TemplateRef);
refToken = createIdentifierToken(Identifiers.TemplateRef);
}
targetReferences.push(new ReferenceAst(elOrDirRef.name, refToken, elOrDirRef.sourceSpan));
}
@ -640,7 +641,7 @@ class TemplateParseVisitor implements html.Visitor {
private _findComponentDirectiveNames(directives: DirectiveAst[]): string[] {
return this._findComponentDirectives(directives)
.map(directive => directive.directive.type.name);
.map(directive => identifierName(directive.directive.type));
}
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()];
}
export function sanitizeIdentifier(name: string): string {
return name.replace(/\W/g, '_');
}
export function visitValue(value: any, visitor: ValueVisitor, context: any): any {
if (Array.isArray(value)) {
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 {DirectiveWrapperCompiler, DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
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 {convertValueToOutputAst} from '../output/value_util';
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 {CompileView, CompileViewRootNode} from './compile_view';
import {InjectMethodVars, ViewProperties} from './constants';
import {ComponentFactoryDependency, DirectiveWrapperDependency, ViewClassDependency} from './deps';
import {ComponentFactoryDependency, DirectiveWrapperDependency} from './deps';
import {getPropertyInView, injectFromViewParentInjector} from './util';
export class CompileNode {
@ -35,7 +35,7 @@ export class CompileNode {
export class CompileElement extends CompileNode {
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;
@ -57,21 +57,18 @@ export class CompileElement extends CompileNode {
sourceAst: TemplateAst, public component: CompileDirectiveSummary,
private _directives: CompileDirectiveSummary[],
private _resolvedProvidersArray: ProviderAst[], public hasViewContainer: boolean,
public hasEmbeddedView: boolean, references: ReferenceAst[],
private _targetDependencies:
Array<ViewClassDependency|ComponentFactoryDependency|DirectiveWrapperDependency>) {
public hasEmbeddedView: boolean, references: ReferenceAst[]) {
super(parent, view, nodeIndex, renderNode, sourceAst);
this.referenceTokens = {};
references.forEach(ref => this.referenceTokens[ref.name] = ref.value);
this.elementRef =
o.importExpr(resolveIdentifier(Identifiers.ElementRef)).instantiate([this.renderNode]);
this.instances.set(resolveIdentifierToken(Identifiers.ElementRef).reference, this.elementRef);
o.importExpr(createIdentifier(Identifiers.ElementRef)).instantiate([this.renderNode]);
this.instances.set(resolveIdentifier(Identifiers.ElementRef), this.elementRef);
this.instances.set(
resolveIdentifierToken(Identifiers.Injector).reference,
resolveIdentifier(Identifiers.Injector),
o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]));
this.instances.set(
resolveIdentifierToken(Identifiers.Renderer).reference, o.THIS_EXPR.prop('renderer'));
this.instances.set(resolveIdentifier(Identifiers.Renderer), o.THIS_EXPR.prop('renderer'));
if (this.hasViewContainer || this.hasEmbeddedView) {
this._createViewContainer();
}
@ -85,39 +82,38 @@ export class CompileElement extends CompileNode {
const parentNodeIndex = this.isRootElement() ? null : this.parent.nodeIndex;
// private is fine here as no child view will reference a ViewContainer
this.view.fields.push(new o.ClassField(
fieldName, o.importType(resolveIdentifier(Identifiers.ViewContainer)),
fieldName, o.importType(createIdentifier(Identifiers.ViewContainer)),
[o.StmtModifier.Private]));
const statement =
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
]))
.toStmt();
this.view.createMethod.addStmt(statement);
this.viewContainer = o.THIS_EXPR.prop(fieldName);
this.instances.set(
resolveIdentifierToken(Identifiers.ViewContainer).reference, this.viewContainer);
this.instances.set(resolveIdentifier(Identifiers.ViewContainer), this.viewContainer);
this.view.viewContainers.push(this.viewContainer);
}
private _createComponentFactoryResolver() {
const entryComponents =
this.component.entryComponents.map((entryComponent: CompileIdentifierMetadata) => {
const id = new CompileIdentifierMetadata({name: entryComponent.name});
this._targetDependencies.push(new ComponentFactoryDependency(entryComponent, id));
const id = new CompileIdentifierMetadata();
this.view.targetDependencies.push(new ComponentFactoryDependency(entryComponent, id));
return id;
});
if (!entryComponents || entryComponents.length === 0) {
return;
}
const createComponentFactoryResolverExpr =
o.importExpr(resolveIdentifier(Identifiers.CodegenComponentFactoryResolver)).instantiate([
o.importExpr(createIdentifier(Identifiers.CodegenComponentFactoryResolver)).instantiate([
o.literalArr(entryComponents.map((entryComponent) => o.importExpr(entryComponent))),
injectFromViewParentInjector(
this.view, resolveIdentifierToken(Identifiers.ComponentFactoryResolver), false)
this.view, createIdentifierToken(Identifiers.ComponentFactoryResolver), false)
]);
const provider = new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.ComponentFactoryResolver),
token: createIdentifierToken(Identifiers.ComponentFactoryResolver),
useValue: createComponentFactoryResolverExpr
});
// 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;
if (isPresent(embeddedView)) {
const createTemplateRefExpr =
o.importExpr(resolveIdentifier(Identifiers.TemplateRef_)).instantiate([
o.importExpr(createIdentifier(Identifiers.TemplateRef_)).instantiate([
o.THIS_EXPR, o.literal(this.nodeIndex), this.renderNode
]);
const provider = new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.TemplateRef),
useValue: createTemplateRefExpr
});
const provider = new CompileProviderMetadata(
{token: createIdentifierToken(Identifiers.TemplateRef), useValue: createTemplateRefExpr});
// Add TemplateRef as first provider as it does not have deps on other providers
this._resolvedProvidersArray.unshift(new ProviderAst(
provider.token, false, true, [provider], ProviderAstType.Builtin, [],
@ -158,13 +152,12 @@ export class CompileElement extends CompileNode {
beforeChildren(): void {
if (this.hasViewContainer) {
this.instances.set(
resolveIdentifierToken(Identifiers.ViewContainerRef).reference,
this.viewContainer.prop('vcRef'));
resolveIdentifier(Identifiers.ViewContainerRef), this.viewContainer.prop('vcRef'));
}
this._resolvedProviders = new Map<any, ProviderAst>();
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,
// 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 =
deps.map((dep) => this._getDependency(resolvedProvider.providerType, dep));
if (isDirectiveWrapper) {
const directiveWrapperIdentifier = new CompileIdentifierMetadata(
{name: DirectiveWrapperCompiler.dirWrapperClassName(provider.useClass)});
this._targetDependencies.push(
new DirectiveWrapperDependency(provider.useClass, directiveWrapperIdentifier));
const directiveWrapperIdentifier = new CompileIdentifierMetadata();
this.view.targetDependencies.push(new DirectiveWrapperDependency(
provider.useClass, DirectiveWrapperCompiler.dirWrapperClassName(provider.useClass),
directiveWrapperIdentifier));
return DirectiveWrapperExpressions.create(directiveWrapperIdentifier, depsExpr);
} else {
return o.importExpr(provider.useClass)
@ -199,22 +192,23 @@ export class CompileElement extends CompileNode {
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(
propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider,
resolvedProvider.eager, this);
if (isDirectiveWrapper) {
this.directiveWrapperInstance.set(resolvedProvider.token.reference, instance);
this.directiveWrapperInstance.set(tokenReference(resolvedProvider.token), instance);
this.instances.set(
resolvedProvider.token.reference, DirectiveWrapperExpressions.context(instance));
tokenReference(resolvedProvider.token), DirectiveWrapperExpressions.context(instance));
} else {
this.instances.set(resolvedProvider.token.reference, instance);
this.instances.set(tokenReference(resolvedProvider.token), instance);
}
});
for (let i = 0; i < this._directives.length; 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); });
}
const queriesWithReads: _QueryWithRead[] = [];
@ -227,7 +221,7 @@ export class CompileElement extends CompileNode {
const token = this.referenceTokens[varName];
let varValue: o.Expression;
if (token) {
varValue = this.instances.get(token.reference);
varValue = this.instances.get(tokenReference(token));
} else {
varValue = this.renderNode;
}
@ -240,12 +234,12 @@ export class CompileElement extends CompileNode {
let value: o.Expression;
if (isPresent(queryWithRead.read.identifier)) {
// query for an identifier
value = this.instances.get(queryWithRead.read.reference);
value = this.instances.get(tokenReference(queryWithRead.read));
} else {
// query for a reference
const token = this.referenceTokens[queryWithRead.read.value];
if (isPresent(token)) {
value = this.instances.get(token.reference);
value = this.instances.get(tokenReference(token));
} else {
value = this.elementRef;
}
@ -261,7 +255,7 @@ export class CompileElement extends CompileNode {
// 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
// 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.
// 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
@ -285,7 +279,7 @@ export class CompileElement extends CompileNode {
getComponent(): o.Expression {
return isPresent(this.component) ?
this.instances.get(identifierToken(this.component.type).reference) :
this.instances.get(tokenReference(identifierToken(this.component.type))) :
null;
}
@ -300,7 +294,7 @@ export class CompileElement extends CompileNode {
let distance = 0;
let queries: CompileQuery[];
while (!currentEl.isNull()) {
queries = currentEl._queries.get(token.reference);
queries = currentEl._queries.get(tokenReference(token));
if (isPresent(queries)) {
result.push(...queries.filter((query) => query.meta.descendants || distance <= 1));
}
@ -309,7 +303,7 @@ export class CompileElement extends CompileNode {
}
currentEl = currentEl.parent;
}
queries = this.view.componentView.viewQueries.get(token.reference);
queries = this.view.componentView.viewQueries.get(tokenReference(token));
if (isPresent(queries)) {
result.push(...queries);
}
@ -319,7 +313,7 @@ export class CompileElement extends CompileNode {
private _addQuery(queryMeta: CompileQueryMetadata, directiveInstance: o.Expression):
CompileQuery {
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 query = new CompileQuery(queryMeta, queryList, directiveInstance, this.view);
addQueryToTokenMap(this._queries, query);
@ -332,8 +326,7 @@ export class CompileElement extends CompileNode {
if (isPresent(dep.token)) {
// access builtins with special visibility
if (!result) {
if (dep.token.reference ===
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
if (tokenReference(dep.token) === resolveIdentifier(Identifiers.ChangeDetectorRef)) {
if (requestingProviderType === ProviderAstType.Component) {
return this.compViewExpr.prop('ref');
} else {
@ -343,7 +336,7 @@ export class CompileElement extends CompileNode {
}
// access regular providers on the element
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.
// only components and private services can access private services.
if (resolvedProvider && (requestingProviderType === ProviderAstType.Directive ||
@ -351,7 +344,7 @@ export class CompileElement extends CompileNode {
resolvedProvider.providerType === ProviderAstType.PrivateService) {
return null;
}
result = this.instances.get(dep.token.reference);
result = this.instances.get(tokenReference(dep.token));
}
}
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 {Identifiers, resolveIdentifier, resolveIdentifierToken} from '../identifiers';
import {Identifiers, createIdentifier, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {CompileView} from './compile_view';
@ -42,8 +42,7 @@ export class CompilePipe {
constructor(public view: CompileView, public meta: CompilePipeSummary) {
this.instance = o.THIS_EXPR.prop(`_pipe_${meta.name}_${view.pipeCount++}`);
const deps = this.meta.type.diDeps.map((diDep) => {
if (diDep.token.reference ===
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
if (tokenReference(diDep.token) === resolveIdentifier(Identifiers.ChangeDetectorRef)) {
return getPropertyInView(o.THIS_EXPR.prop('ref'), this.view, this.view.componentView);
}
return injectFromViewParentInjector(view, diDep.token, false);
@ -69,7 +68,7 @@ export class CompilePipe {
.callMethod(o.BuiltinMethod.Bind, [pipeInstanceSeenFromPureProxy]),
args.length, purePipeProxyInstance,
{fields: callingView.fields, ctorStmts: callingView.createMethod});
return o.importExpr(resolveIdentifier(Identifiers.castByValue))
return o.importExpr(createIdentifier(Identifiers.castByValue))
.callFn([purePipeProxyInstance, pipeInstanceSeenFromPureProxy.prop('transform')])
.callFn(args);
} else {

View File

@ -6,10 +6,10 @@
* 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 {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {CompileElement} from './compile_element';
@ -114,22 +114,22 @@ export function createQueryList(
query: CompileQueryMetadata, directiveInstance: o.Expression, propertyName: string,
compileView: CompileView): o.Expression {
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);
compileView.createMethod.addStmt(
o.THIS_EXPR.prop(propertyName)
.set(o.importExpr(resolveIdentifier(Identifiers.QueryList), [o.DYNAMIC_TYPE])
.instantiate([]))
.set(o.importExpr(createIdentifier(Identifiers.QueryList), [o.DYNAMIC_TYPE]).instantiate([
]))
.toStmt());
return expr;
}
export function addQueryToTokenMap(map: Map<any, CompileQuery[]>, query: CompileQuery) {
query.meta.selectors.forEach((selector) => {
let entry = map.get(selector.reference);
let entry = map.get(tokenReference(selector));
if (!entry) {
entry = [];
map.set(selector.reference, entry);
map.set(tokenReference(selector), entry);
}
entry.push(query);
});

View File

@ -7,12 +7,12 @@
*/
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 {createPureProxy} from '../compiler_util/identifier_util';
import {CompilerConfig} from '../config';
import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {ViewType} from '../private_import_core';
@ -20,6 +20,7 @@ import {CompileElement, CompileNode} from './compile_element';
import {CompileMethod} from './compile_method';
import {CompilePipe} from './compile_pipe';
import {CompileQuery, addQueryToTokenMap, createQueryList} from './compile_query';
import {ComponentFactoryDependency, DirectiveWrapperDependency, ViewClassDependency} from './deps';
import {getPropertyInView, getViewClassName} from './util';
export enum CompileViewRootNodeType {
@ -84,7 +85,9 @@ export class CompileView implements NameResolver {
public component: CompileDirectiveMetadata, public genConfig: CompilerConfig,
public pipeMetas: CompilePipeSummary[], public styles: o.Expression,
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.animationBindingsMethod = new CompileMethod(this);
this.injectorGetMethod = new CompileMethod(this);
@ -101,7 +104,7 @@ export class CompileView implements NameResolver {
this.viewType = getViewType(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);
if (this.viewType === ViewType.COMPONENT || this.viewType === ViewType.HOST) {
this.componentView = this;
@ -115,7 +118,7 @@ export class CompileView implements NameResolver {
if (this.viewType === ViewType.COMPONENT) {
const directiveInstance = o.THIS_EXPR.prop('context');
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 query = new CompileQuery(queryMeta, queryList, directiveInstance, this);
addQueryToTokenMap(viewQueries, query);
@ -164,7 +167,7 @@ function getViewType(component: CompileDirectiveMetadata, embeddedTemplateIndex:
return ViewType.EMBEDDED;
}
if (component.type.isHost) {
if (component.isHost) {
return ViewType.HOST;
}

View File

@ -10,7 +10,8 @@ import {CompileIdentifierMetadata} from '../compile_metadata';
export class ViewClassDependency {
constructor(
public comp: CompileIdentifierMetadata, public placeholder: CompileIdentifierMetadata) {}
public comp: CompileIdentifierMetadata, public name: string,
public placeholder: CompileIdentifierMetadata) {}
}
export class ComponentFactoryDependency {
@ -20,5 +21,6 @@ export class ComponentFactoryDependency {
export class DirectiveWrapperDependency {
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 {createInlineArray} from '../compiler_util/identifier_util';
import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {BoundEventAst, DirectiveAst} from '../template_parser/template_ast';
@ -56,7 +56,7 @@ function subscribeToRenderEvents(
compileElement.view.disposables.push(disposableVar);
compileElement.view.createMethod.addStmt(
disposableVar
.set(o.importExpr(resolveIdentifier(Identifiers.subscribeToRenderElement)).callFn([
.set(o.importExpr(createIdentifier(Identifiers.subscribeToRenderElement)).callFn([
o.THIS_EXPR, compileElement.renderNode, createInlineArray(eventAndTargetExprs),
handleEventExpr(compileElement)
]))

View File

@ -13,7 +13,7 @@ import {ConvertPropertyBindingResult, convertPropertyBinding} from '../compiler_
import {createEnumExpression} from '../compiler_util/identifier_util';
import {triggerAnimation, writeToRenderer} from '../compiler_util/render_util';
import {DirectiveWrapperExpressions} from '../directive_wrapper_compiler';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {isDefaultChangeDetectionStrategy} from '../private_import_core';
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
@ -69,7 +69,7 @@ export function bindRenderInputs(
const {updateStmts, detachStmts} = triggerAnimation(
o.THIS_EXPR, o.THIS_EXPR, boundProp,
(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]),
compileElement.renderNode, evalResult.currValExpr, bindingField.expression);
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 {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {ViewType} from '../private_import_core';
@ -74,7 +74,7 @@ export function injectFromViewParentInjector(
export function getViewClassName(
component: CompileDirectiveSummary | CompileDirectiveMetadata,
embeddedTemplateIndex: number): string {
return `View_${component.type.name}${embeddedTemplateIndex}`;
return `View_${identifierName(component.type)}${embeddedTemplateIndex}`;
}
export function getHandleEventMethodName(elementIndex: number): string {

View File

@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {tokenReference} from '../compile_metadata';
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';
@ -66,7 +67,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
directiveAst, directiveWrapperInstance, compileElement);
});
ast.providers.forEach((providerAst) => {
const providerInstance = compileElement.instances.get(providerAst.token.reference);
const providerInstance = compileElement.instances.get(tokenReference(providerAst.token));
bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement);
});
return null;
@ -89,7 +90,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
directiveAst, directiveWrapperInstance, compileElement);
});
ast.providers.forEach((providerAst) => {
const providerInstance = compileElement.instances.get(providerAst.token.reference);
const providerInstance = compileElement.instances.get(tokenReference(providerAst.token));
bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement);
});
bindView(compileElement.embeddedView, ast.children, this._schemaRegistry);

View File

@ -8,11 +8,11 @@
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 {createDiTokenExpression, createInlineArray} from '../compiler_util/identifier_util';
import {isPresent} from '../facade/lang';
import {Identifiers, identifierToken, resolveIdentifier} from '../identifiers';
import {Identifiers, createIdentifier, identifierToken} from '../identifiers';
import {createClassStmt} from '../output/class_builder';
import * as o from '../output/output_ast';
import {ParseSourceSpan} from '../parse_util';
@ -189,13 +189,13 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
_mergeHtmlAndDirectiveAttrs(htmlAttrs, directives).map(v => o.literal(v)));
if (nodeIndex === 0 && this.view.viewType === ViewType.HOST) {
createRenderNodeExpr =
o.importExpr(resolveIdentifier(Identifiers.selectOrCreateRenderHostElement)).callFn([
o.importExpr(createIdentifier(Identifiers.selectOrCreateRenderHostElement)).callFn([
ViewProperties.renderer, o.literal(ast.name), attrNameAndValues, rootSelectorVar,
debugContextExpr
]);
} else {
createRenderNodeExpr =
o.importExpr(resolveIdentifier(Identifiers.createRenderElement)).callFn([
o.importExpr(createIdentifier(Identifiers.createRenderElement)).callFn([
ViewProperties.renderer, this._getParentRenderNode(parent), o.literal(ast.name),
attrNameAndValues, debugContextExpr
]);
@ -210,19 +210,18 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
const compileElement = new CompileElement(
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);
let compViewExpr: o.ReadPropExpr = null;
if (isPresent(component)) {
const nestedComponentIdentifier =
new CompileIdentifierMetadata({name: getViewClassName(component, 0)});
this.targetDependencies.push(
new ViewClassDependency(component.type, nestedComponentIdentifier));
const nestedComponentIdentifier = new CompileIdentifierMetadata();
this.targetDependencies.push(new ViewClassDependency(
component.type, getViewClassName(component, 0), nestedComponentIdentifier));
compViewExpr = o.THIS_EXPR.prop(`compView_${nodeIndex}`); // fix highlighting: `
this.view.fields.push(new o.ClassField(
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);
compileElement.setComponentView(compViewExpr);
this.view.createMethod.addStmt(
@ -266,14 +265,14 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
const directives = ast.directives.map(directiveAst => directiveAst.directive);
const compileElement = new CompileElement(
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.nestedViewCount++;
const embeddedView = new CompileView(
this.view.component, this.view.genConfig, this.view.pipeMetas, o.NULL_EXPR,
this.view.animations, this.view.viewIndex + this.nestedViewCount, compileElement,
templateVariableBindings);
templateVariableBindings, this.targetDependencies);
this.nestedViewCount += buildView(embeddedView, ast.children, this.targetDependencies);
compileElement.beforeChildren();
@ -372,31 +371,33 @@ function createViewTopLevelStmts(view: CompileView, targetStatements: o.Statemen
let nodeDebugInfosVar: o.Expression = o.NULL_EXPR;
if (view.genConfig.genDebugInfo) {
nodeDebugInfosVar = o.variable(
`nodeDebugInfos_${view.component.type.name}${view.viewIndex}`); // fix highlighting: `
`nodeDebugInfos_${identifierName(view.component.type)}${view.viewIndex}`); // fix
// highlighting:
// `
targetStatements.push(
(<o.ReadVarExpr>nodeDebugInfosVar)
.set(o.literalArr(
view.nodes.map(createStaticNodeDebugInfo),
new o.ArrayType(
new o.ExternalType(resolveIdentifier(Identifiers.StaticNodeDebugInfo)),
o.importType(createIdentifier(Identifiers.StaticNodeDebugInfo)),
[o.TypeModifier.Const])))
.toDeclStmt(null, [o.StmtModifier.Final]));
}
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) {
let templateUrlInfo: string;
if (view.component.template.templateUrl == view.component.type.moduleUrl) {
if (view.component.template.templateUrl == identifierModuleUrl(view.component.type)) {
templateUrlInfo =
`${view.component.type.moduleUrl} class ${view.component.type.name} - inline template`;
`${identifierModuleUrl(view.component.type)} class ${identifierName(view.component.type)} - inline template`;
} else {
templateUrlInfo = view.component.template.templateUrl;
}
targetStatements.push(
renderCompTypeVar
.set(o.importExpr(resolveIdentifier(Identifiers.createRenderComponentType)).callFn([
.set(o.importExpr(createIdentifier(Identifiers.createRenderComponentType)).callFn([
view.genConfig.genDebugInfo ? o.literal(templateUrlInfo) : o.literal(''),
o.literal(view.component.template.ngContentSelectors.length),
ViewEncapsulationEnum.fromValue(view.component.template.encapsulation),
@ -404,7 +405,7 @@ function createViewTopLevelStmts(view: CompileView, targetStatements: o.Statemen
o.literalMap(view.animations.map(
(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);
@ -427,7 +428,7 @@ function createStaticNodeDebugInfo(node: CompileNode): o.Expression {
[varName, isPresent(token) ? createDiTokenExpression(token) : o.NULL_EXPR]);
});
}
return o.importExpr(resolveIdentifier(Identifiers.StaticNodeDebugInfo))
return o.importExpr(createIdentifier(Identifiers.StaticNodeDebugInfo))
.instantiate(
[
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.importType(
resolveIdentifier(Identifiers.StaticNodeDebugInfo), null, [o.TypeModifier.Const]));
createIdentifier(Identifiers.StaticNodeDebugInfo), null, [o.TypeModifier.Const]));
}
function createViewClass(
@ -443,10 +444,10 @@ function createViewClass(
nodeDebugInfosVar: o.Expression): o.ClassStmt {
const viewConstructorArgs = [
new o.FnParam(
ViewConstructorVars.viewUtils.name, o.importType(resolveIdentifier(Identifiers.ViewUtils))),
ViewConstructorVars.viewUtils.name, o.importType(createIdentifier(Identifiers.ViewUtils))),
new o.FnParam(
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.parentElement.name, o.DYNAMIC_TYPE)
];
@ -461,14 +462,14 @@ function createViewClass(
}
if (view.viewType === ViewType.EMBEDDED) {
viewConstructorArgs.push(new o.FnParam(
'declaredViewContainer', o.importType(resolveIdentifier(Identifiers.ViewContainer))));
'declaredViewContainer', o.importType(createIdentifier(Identifiers.ViewContainer))));
superConstructorArgs.push(o.variable('declaredViewContainer'));
}
const viewMethods = [
new o.ClassMethod(
'createInternal', [new o.FnParam(rootSelectorVar.name, o.STRING_TYPE)],
generateCreateMethod(view),
o.importType(resolveIdentifier(Identifiers.ComponentRef), [o.DYNAMIC_TYPE])),
o.importType(createIdentifier(Identifiers.ComponentRef), [o.DYNAMIC_TYPE])),
new o.ClassMethod(
'injectorGetInternal',
[
@ -492,7 +493,7 @@ function createViewClass(
const viewClass = createClassStmt({
name: view.className,
parent: o.importExpr(resolveIdentifier(superClass), [getContextType(view)]),
parent: o.importExpr(createIdentifier(superClass), [getContextType(view)]),
parentArgs: superConstructorArgs,
ctorParams: viewConstructorArgs,
builders: [{methods: viewMethods}, view]
@ -526,7 +527,7 @@ function generateCreateMethod(view: CompileView): o.Statement[] {
if (view.viewType === ViewType.HOST) {
const hostEl = <CompileElement>view.nodes[0];
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()
]);
} else {
@ -591,7 +592,7 @@ function generateDetectChangesMethod(view: CompileView): o.Statement[] {
if (readVars.has(DetectChangesVars.changes.name)) {
varStmts.push(
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));
return varStmts.concat(stmts);
@ -703,5 +704,5 @@ function generateCreateEmbeddedViewsMethod(view: CompileView): o.ClassMethod {
}
return new o.ClassMethod(
'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> = [];
const view = new CompileView(
component, this._genConfig, pipes, styles, compiledAnimations, 0,
CompileElement.createNull(), []);
CompileElement.createNull(), [], dependencies);
const statements: o.Statement[] = [];
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 {AnimationCompiler, AnimationEntryCompileResult} from '../../src/animation/animation_compiler';
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 {ElementSchemaRegistry} from '../../src/schema/element_schema_registry';
@ -30,7 +30,7 @@ export function main() {
const compileAnimations =
(component: CompileDirectiveMetadata): AnimationEntryCompileResult[] => {
const parsedAnimations = parser.parseComponent(component);
return compiler.compile(component.type.name, parsedAnimations);
return compiler.compile(identifierName(component.type), parsedAnimations);
};
const compileTriggers = (input: any[]) => {
@ -40,7 +40,7 @@ export function main() {
});
const component = CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({name: 'myCmp'}),
type: new CompileTypeMetadata({reference: {name: 'myCmp', filePath: ''}}),
template: new CompileTemplateMetadata({animations: entries})
});

View File

@ -7,7 +7,7 @@
*/
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';
export function main() {
@ -16,7 +16,7 @@ export function main() {
function check(argCount: number, expectedIdentifier: any) {
const args = createArgs(argCount);
expect(createInlineArray(args))
.toEqual(o.importExpr(resolveIdentifier(expectedIdentifier)).instantiate([
.toEqual(o.importExpr(createIdentifier(expectedIdentifier)).instantiate([
<o.Expression>o.literal(argCount)
].concat(args)));
}
@ -31,7 +31,7 @@ export function main() {
it('should work for arrays of length 0', () => {
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', () => {

View File

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

View File

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

View File

@ -7,7 +7,7 @@
*/
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 {ImportResolver} from '@angular/compiler/src/output/path_util';
import {EventEmitter} from '@angular/core';
@ -20,23 +20,29 @@ export class ExternalClass {
someMethod(a: any /** TODO #9100 */) { return {'param': a, 'data': this.data}; }
}
const testDataIdentifier = new CompileIdentifierMetadata({
const testDataIdentifier = {
name: 'ExternalClass',
moduleUrl: `@angular/compiler/test/output/output_emitter_util`,
reference: ExternalClass
});
runtime: ExternalClass
};
const eventEmitterIdentifier = new CompileIdentifierMetadata(
{name: 'EventEmitter', moduleUrl: assetUrl('core'), reference: EventEmitter});
const eventEmitterIdentifier = {
name: 'EventEmitter',
moduleUrl: assetUrl('core'),
runtime: EventEmitter
};
const enumIdentifier = new CompileIdentifierMetadata({
const enumIdentifier = {
name: 'ViewType.HOST',
moduleUrl: assetUrl('core', 'linker/view_type'),
reference: ViewType.HOST
});
runtime: ViewType.HOST
};
const baseErrorIdentifier = new CompileIdentifierMetadata(
{name: 'BaseError', moduleUrl: assetUrl('core', 'facade/errors'), reference: BaseError});
const baseErrorIdentifier = {
name: 'BaseError',
moduleUrl: assetUrl('core', 'facade/errors'),
runtime: BaseError
};
export var codegenExportsVars = [
'getExpressions',
@ -58,7 +64,7 @@ const _getExpressionsStmts: o.Statement[] = [
o.variable('map').key(o.literal('changeable')).set(o.literal('changedValue')).toStmt(),
o.variable('externalInstance')
.set(o.importExpr(testDataIdentifier).instantiate([o.literal('someValue')]))
.set(o.importExpr(createIdentifier(testDataIdentifier)).instantiate([o.literal('someValue')]))
.toDeclStmt(),
o.variable('externalInstance').prop('changeable').set(o.literal('changedValue')).toStmt(),
@ -69,8 +75,8 @@ const _getExpressionsStmts: o.Statement[] = [
.toDeclStmt(),
o.variable('throwError')
.set(o.fn([], [new o.ThrowStmt(
o.importExpr(baseErrorIdentifier).instantiate([o.literal('someError')]))]))
.set(o.fn([], [new o.ThrowStmt(o.importExpr(createIdentifier(baseErrorIdentifier))
.instantiate([o.literal('someError')]))]))
.toDeclStmt(),
o.variable('catchError')
@ -152,9 +158,9 @@ const _getExpressionsStmts: o.Statement[] = [
['not', o.not(o.literal(false))],
['externalTestIdentifier', o.importExpr(testDataIdentifier)],
['externalSrcIdentifier', o.importExpr(eventEmitterIdentifier)],
['externalEnumIdentifier', o.importExpr(enumIdentifier)],
['externalTestIdentifier', o.importExpr(createIdentifier(testDataIdentifier))],
['externalSrcIdentifier', o.importExpr(createIdentifier(eventEmitterIdentifier))],
['externalEnumIdentifier', o.importExpr(createIdentifier(enumIdentifier))],
['externalInstance', o.variable('externalInstance')],
['dynamicInstance', o.variable('dynamicInstance')],
@ -188,7 +194,7 @@ export var codegenStmts: o.Statement[] = [
new o.CommentStmt('This is a comment'),
new o.ClassStmt(
'DynamicClass', o.importExpr(testDataIdentifier),
'DynamicClass', o.importExpr(createIdentifier(testDataIdentifier)),
[
new o.ClassField('dynamicProp', 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 {ImportResolver} from '@angular/compiler/src/output/path_util';
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 anotherModuleUrl = 'somePackage/someOtherPath';
const sameModuleIdentifier =
new CompileIdentifierMetadata({name: 'someLocalId', moduleUrl: someModuleUrl});
new CompileIdentifierMetadata({reference: {name: 'someLocalId', filePath: someModuleUrl}});
const externalModuleIdentifier =
new CompileIdentifierMetadata({name: 'someExternalId', moduleUrl: anotherModuleUrl});
const externalModuleIdentifier = new CompileIdentifierMetadata(
{reference: {name: 'someExternalId', filePath: anotherModuleUrl}});
class SimpleJsImportGenerator implements ImportResolver {
fileNameToModuleName(importedUrlStr: string, moduleUrlStr: string): string {
@ -323,6 +322,14 @@ export function main() {
].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', () => {
const writeVarExpr = o.variable('a').set(o.NULL_EXPR);
expect(emitStmt(writeVarExpr.toDeclStmt(new o.ArrayType(null))))

View File

@ -6,7 +6,7 @@
* 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 {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';
@ -14,10 +14,9 @@ import {TEMPLATE_TRANSFORMS, TemplateParser, splitClasses} from '@angular/compil
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/test_bindings';
import {SchemaMetadata, SecurityContext, Type} from '@angular/core';
import {Console} from '@angular/core/src/console';
import {TestBed} from '@angular/core/testing';
import {beforeEach, describe, expect, inject, it} from '@angular/core/testing/testing_internal';
import {TestBed, inject} from '@angular/core/testing';
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 {MockSchemaRegistry} from '../../testing/index';
import {unparse} from '../expression_parser/unparser';
@ -49,19 +48,18 @@ export function main() {
const component = CompileDirectiveMetadata.create({
selector: 'root',
template: someTemplate,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'Root', reference: {} as Type<any>}),
type: new CompileTypeMetadata({reference: {filePath: someModuleUrl, name: 'Root'}}),
isComponent: true
});
ngIf = CompileDirectiveMetadata
.create({
selector: '[ngIf]',
template: someTemplate,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'NgIf', reference: {} as Type<any>}),
inputs: ['ngIf']
})
.toSummary();
ngIf =
CompileDirectiveMetadata
.create({
selector: '[ngIf]',
template: someTemplate,
type: new CompileTypeMetadata({reference: {filePath: someModuleUrl, name: 'NgIf'}}),
inputs: ['ngIf']
})
.toSummary();
parse =
(template: string, directives: CompileDirectiveSummary[],
@ -302,8 +300,8 @@ export function main() {
inject([TemplateParser], (parser: TemplateParser) => {
const component = CompileDirectiveMetadata.create({
selector: 'test',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'Test', reference: {} as Type<any>}),
type:
new CompileTypeMetadata({reference: {filePath: someModuleUrl, name: 'Test'}}),
isComponent: true,
template: new CompileTemplateMetadata({interpolation: ['{%', '%}']})
});
@ -471,9 +469,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
selector: 'div',
template: new CompileTemplateMetadata({animations: animationEntries}),
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirA',
reference: {} as Type<any>
reference: {filePath: someModuleUrl, name: 'DirA'},
}),
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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'broken',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
host: {'[class.foo]': null}
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'broken',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
host: {'[class.foo]': null}
})
.toSummary();
expect(() => { parse('<broken></broken>', [dirA]); })
.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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'broken',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
host: {'(click)': null}
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'broken',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
host: {'(click)': null}
})
.toSummary();
expect(() => { parse('<broken></broken>', [dirA]); })
.toThrowError(
@ -572,11 +566,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
.create({
selector: 'template',
outputs: ['e'],
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirA',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
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
.create({
selector: '[a]',
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirA',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
const dirB = CompileDirectiveMetadata
.create({
selector: '[b]',
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirB',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirB'}})
})
.toSummary();
const dirC = CompileDirectiveMetadata
.create({
selector: '[c]',
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirC',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirC'}})
})
.toSummary();
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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a=b]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>})
})
.toSummary();
const dirB =
CompileDirectiveMetadata
.create({
selector: '[b]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirB', reference: {} as Type<any>})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a=b]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
const dirB = CompileDirectiveMetadata
.create({
selector: '[b]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirB'}})
})
.toSummary();
expect(humanizeTplAst(parse('<div [a]="b">', [dirA, dirB]))).toEqual([
[ElementAst, 'div'],
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirB', reference: {} as Type<any>})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirB'}})
})
.toSummary();
expect(humanizeTplAst(parse('<div (a)="b">', [dirA]))).toEqual([
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
host: {'[a]': 'expr'}
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
host: {'[a]': 'expr'}
})
.toSummary();
expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA],
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
host: {'(a)': 'expr'}
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
host: {'(a)': 'expr'}
})
.toSummary();
expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA], [BoundEventAst, 'a', null, 'expr']
]);
});
it('should parse directive properties', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['aProp']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['aProp']
})
.toSummary();
expect(humanizeTplAst(parse('<div [aProp]="expr"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA],
[BoundDirectivePropertyAst, 'aProp', 'expr']
@ -735,15 +711,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
});
it('should parse renamed directive properties', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['b:a']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['b:a']
})
.toSummary();
expect(humanizeTplAst(parse('<div [a]="expr"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA],
[BoundDirectivePropertyAst, 'b', 'expr']
@ -751,15 +726,14 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
});
it('should parse literal directive properties', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['a']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['a']
})
.toSummary();
expect(humanizeTplAst(parse('<div a="literal"></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [AttrAst, 'a', 'literal'], [DirectiveAst, dirA],
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['a']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['a']
})
.toSummary();
expect(humanizeTplAst(parse('<div a="literal" [a]="\'literal2\'"></div>', [dirA])))
.toEqual([
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['a']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['a']
})
.toSummary();
expect(humanizeTplAst(parse('<div></div>', [dirA]))).toEqual([
[ElementAst, 'div'], [DirectiveAst, dirA]
]);
@ -807,10 +779,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
let token: CompileTokenMetadata;
if (value.startsWith('type:')) {
const name = value.substring(5);
token = new CompileTokenMetadata({
identifier: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name, reference: name as any as Type<any>})
});
token = new CompileTokenMetadata(
{identifier: new CompileTypeMetadata({reference: <any>name})});
} else {
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[]} = {}):
CompileProviderMetadata {
const name = `provider${nextProviderId++}`;
const compileToken = createToken(token);
return new CompileProviderMetadata({
token: createToken(token),
token: compileToken,
multi: multi,
useClass: new CompileTypeMetadata({name, reference: name as any as Type<any>}),
useClass: new CompileTypeMetadata({reference: tokenReference(compileToken)}),
deps: deps.map(createDep)
});
}
@ -866,10 +837,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
.create({
selector: selector,
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: selector,
reference: <any>selector,
diDeps: deps.map(createDep),
reference: selector as any as Type<any>
}),
isComponent: isComponent,
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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
exportAs: 'dirA'
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
exportAs: 'dirA'
})
.toSummary();
expect(humanizeTplAst(parse('<div a #a="dirA"></div>', [dirA]))).toEqual([
[ElementAst, 'div'],
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
exportAs: 'dirA',
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
exportAs: 'dirA',
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
expect(humanizeTplAst(parse('<div a #a></div>', [dirA]))).toEqual([
[ElementAst, 'div'],
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
expect(humanizeTplAst(parse('<div ref-a>', [dirA]))).toEqual([
[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 #...', () => {
expect(humanizeTplAst(parse('<template #a>', []))).toEqual([
[EmbeddedTemplateAst],
[ReferenceAst, 'a', resolveIdentifierToken(Identifiers.TemplateRef)]
[ReferenceAst, 'a', createIdentifierToken(Identifiers.TemplateRef)]
]);
});
it('should support references via ref-...', () => {
expect(humanizeTplAst(parse('<template ref-a>', []))).toEqual([
[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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
expect(humanizeTplAst(parse('<template let-a="b"></template>', [dirA]))).toEqual([
[EmbeddedTemplateAst], [VariableAst, 'a', 'b']
]);
@ -1281,23 +1246,19 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
describe('directives', () => {
it('should locate directives in property bindings', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a=b]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['a']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a=b]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['a']
})
.toSummary();
const dirB = CompileDirectiveMetadata
.create({
selector: '[b]',
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirB',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirB'}})
})
.toSummary();
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
.create({
selector: '[a]',
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirA',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
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
.create({
selector: '[a]',
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: 'DirA',
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
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({
selector: selector,
isComponent: true,
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: `SomeComp${compCounter++}`,
reference: {} as Type<any>
}),
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: `SomeComp${compCounter++}`}}),
template: new CompileTemplateMetadata({ngContentSelectors: ngContentSelectors})
})
.toSummary();
@ -1381,11 +1333,8 @@ Reference "#a" is defined several times ("<div #a></div><div [ERROR ->]#a></div>
return CompileDirectiveMetadata
.create({
selector: selector,
type: new CompileTypeMetadata({
moduleUrl: someModuleUrl,
name: `SomeDir${compCounter++}`,
reference: {} as Type<any>
})
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: `SomeDir${compCounter++}`}})
})
.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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
host: {'[invalidProp]': 'someProp'}
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
host: {'[invalidProp]': 'someProp'}
})
.toSummary();
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`);
});
@ -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',
() => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['invalidProp']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['invalidProp']
})
.toSummary();
expect(() => parse('<div [invalid-prop]></div>', [dirA])).not.toThrow();
});
it('should not allow more than 1 component per element', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirB =
CompileDirectiveMetadata
.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirB', reference: {} as Type<any>}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirB = CompileDirectiveMetadata
.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirB'}}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
expect(() => parse('<div>', [dirB, dirA]))
.toThrowError(
`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',
() => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA]))
.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
@ -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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
isComponent: true,
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
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
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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>})
})
.toSummary();
const comp =
CompileDirectiveMetadata
.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'ZComp', reference: {} as Type<any>}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: '[a]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
})
.toSummary();
const comp = CompileDirectiveMetadata
.create({
selector: 'div',
isComponent: true,
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'ZComp'}}),
template: new CompileTemplateMetadata({ngContentSelectors: []})
})
.toSummary();
expect(humanizeTplAstSourceSpans(parse('<div a>', [dirA, comp]))).toEqual([
[ElementAst, 'div', '<div a>'], [AttrAst, 'a', '', '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', () => {
const tagSel =
CompileDirectiveMetadata
.create({
selector: 'circle',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'elDir', reference: {} as Type<any>})
})
.toSummary();
const attrSel =
CompileDirectiveMetadata
.create({
selector: '[href]',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'attrDir', reference: {} as Type<any>})
})
.toSummary();
const tagSel = CompileDirectiveMetadata
.create({
selector: 'circle',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'elDir'}})
})
.toSummary();
const attrSel = CompileDirectiveMetadata
.create({
selector: '[href]',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'attrDir'}})
})
.toSummary();
expect(humanizeTplAstSourceSpans(
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', () => {
const dirA =
CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>}),
inputs: ['aProp']
})
.toSummary();
const dirA = CompileDirectiveMetadata
.create({
selector: 'div',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}}),
inputs: ['aProp']
})
.toSummary();
expect(humanizeTplAstSourceSpans(parse('<div [aProp]="foo"></div>', [dirA]))).toEqual([
[ElementAst, 'div', '<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', () => {
const tagSel =
CompileDirectiveMetadata
.create({
selector: 'circle',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'elDir', reference: {} as Type<any>})
})
.toSummary();
const tagSel = CompileDirectiveMetadata
.create({
selector: 'circle',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'elDir'}})
})
.toSummary();
const result = parse('<circle></circle>', [tagSel]);
const circle = result[0] as ElementAst;
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', () => {
const ulSel =
CompileDirectiveMetadata
.create({
selector: 'ul',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'ulDir', reference: {} as Type<any>})
})
.toSummary();
const liSel =
CompileDirectiveMetadata
.create({
selector: 'li',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'liDir', reference: {} as Type<any>})
})
.toSummary();
const ulSel = CompileDirectiveMetadata
.create({
selector: 'ul',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'ulDir'}})
})
.toSummary();
const liSel = CompileDirectiveMetadata
.create({
selector: 'li',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'liDir'}})
})
.toSummary();
const result = parse('<ul><li><li></ul>', [ulSel, liSel]);
const ul = result[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', () => {
it('should allow pipes that have been defined as dependencies', () => {
const testPipe =
new CompilePipeMetadata({
name: 'test',
type: new CompileTypeMetadata(
{moduleUrl: someModuleUrl, name: 'DirA', reference: {} as Type<any>})
}).toSummary();
const testPipe = new CompilePipeMetadata({
name: 'test',
type: new CompileTypeMetadata(
{reference: {filePath: someModuleUrl, name: 'DirA'}})
}).toSummary();
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)); });
}
return <any>{
classType: o.importType(new CompileIdentifierMetadata({name: config.className})),
classType: o.importType(new CompileIdentifierMetadata()),
fields: fields,
getters: [],
declarationElement: declarationElement

View File

@ -6,7 +6,7 @@
* 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 {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) {
let type: Symbol;
if (reference.value) {
type = info.template.query.getTypeSymbol(reference.value.reference);
type = info.template.query.getTypeSymbol(tokenReference(reference.value));
}
result.push({
name: reference.name,
@ -740,7 +740,8 @@ function getVarDeclarations(info: TemplateInfo, path: TemplateAstPath): SymbolDe
function refinedVariableType(
type: Symbol, info: TemplateInfo, templateElement: EmbeddedTemplateAst): Symbol {
// 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) {
const ngForOfBinding = ngForDirective.inputs.find(i => i.directiveName == 'ngForOf');
if (ngForOfBinding) {

View File

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

View File

@ -6,6 +6,7 @@
* 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 {Attribute} from '@angular/compiler/src/ml_parser/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) {
symbol = info.template.query.getTypeSymbol(ast.value.reference);
symbol = info.template.query.getTypeSymbol(tokenReference(ast.value));
span = spanOf(ast);
},
visitVariable(ast) {},

View File

@ -6,7 +6,7 @@
* 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 {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer';
import {DirectiveResolver} from '@angular/compiler/src/directive_resolver';
@ -235,12 +235,12 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
const urlResolver = createOfflineCompileUrlResolver();
for (const module of ngModuleSummary.ngModules) {
for (const directive of module.declaredDirectives) {
const directiveMetadata =
const {metadata, annotation} =
this.resolver.getNonNormalizedDirectiveMetadata(directive.reference);
if (directiveMetadata.isComponent && directiveMetadata.template &&
directiveMetadata.template.templateUrl) {
const templateName =
urlResolver.resolve(directive.moduleUrl, directiveMetadata.template.templateUrl);
if (metadata.isComponent && metadata.template && metadata.template.templateUrl) {
const templateName = urlResolver.resolve(
componentModuleUrl(this.reflector, directive.reference, annotation),
metadata.template.templateUrl);
fileToComponent.set(templateName, directive.reference);
templateReference.push(templateName);
}
@ -427,7 +427,7 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
this._reflector.getStaticSymbol(sourceFile.fileName, classDeclaration.name.text);
try {
if (this.resolver.isDirective(staticSymbol as any)) {
const metadata =
const {metadata} =
this.resolver.getNonNormalizedDirectiveMetadata(staticSymbol as any);
return {type: staticSymbol, declarationSpan: spanOf(target), metadata};
}

View File

@ -6,7 +6,7 @@
* 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 {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 {
if (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;

View File

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