refactor(compiler): replace CompileIdentifierMap with regular Map

closes #11145

Also rename `CompileIdentifierMetadata.runtime` into `CompileIdentifierMetadata.reference`.

Also remove `CompileIdentifierMetadata.equalsTo` as
now it is enough to just check the `reference` fields for equality.
This commit is contained in:
Tobias Bosch
2016-08-29 08:52:25 -07:00
committed by Victor Berchet
parent 51877ef4ed
commit d7de5c4f8e
27 changed files with 347 additions and 471 deletions

View File

@ -7,8 +7,8 @@
*/
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileIdentifierMap, CompileIdentifierMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata';
import {ListWrapper, StringMapWrapper} from '../facade/collection';
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileIdentifierMetadata, CompileProviderMetadata, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata';
import {ListWrapper, MapWrapper, StringMapWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, identifierToken, resolveIdentifier, resolveIdentifierToken} from '../identifiers';
import * as o from '../output/output_ast';
@ -41,11 +41,11 @@ export class CompileElement extends CompileNode {
public appElement: o.ReadPropExpr;
public elementRef: o.Expression;
public injector: o.Expression;
public instances = new CompileIdentifierMap<CompileTokenMetadata, o.Expression>();
private _resolvedProviders: CompileIdentifierMap<CompileTokenMetadata, ProviderAst>;
public instances = new Map<any, o.Expression>();
private _resolvedProviders: Map<any, ProviderAst>;
private _queryCount = 0;
private _queries = new CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>();
private _queries = new Map<any, CompileQuery[]>();
private _componentConstructorViewQueryLists: o.Expression[] = [];
public contentNodesByNgContentIndex: Array<o.Expression>[] = null;
@ -64,10 +64,11 @@ export class CompileElement extends CompileNode {
this.elementRef =
o.importExpr(resolveIdentifier(Identifiers.ElementRef)).instantiate([this.renderNode]);
this.instances.add(resolveIdentifierToken(Identifiers.ElementRef), this.elementRef);
this.instances.set(resolveIdentifierToken(Identifiers.ElementRef).reference, this.elementRef);
this.injector = o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]);
this.instances.add(resolveIdentifierToken(Identifiers.Injector), this.injector);
this.instances.add(resolveIdentifierToken(Identifiers.Renderer), o.THIS_EXPR.prop('renderer'));
this.instances.set(resolveIdentifierToken(Identifiers.Injector).reference, this.injector);
this.instances.set(
resolveIdentifierToken(Identifiers.Renderer).reference, o.THIS_EXPR.prop('renderer'));
if (this.hasViewContainer || this.hasEmbeddedView || isPresent(this.component)) {
this._createAppElement();
}
@ -88,7 +89,7 @@ export class CompileElement extends CompileNode {
.toStmt();
this.view.createMethod.addStmt(statement);
this.appElement = o.THIS_EXPR.prop(fieldName);
this.instances.add(resolveIdentifierToken(Identifiers.AppElement), this.appElement);
this.instances.set(resolveIdentifierToken(Identifiers.AppElement).reference, this.appElement);
}
public createComponentFactoryResolver(entryComponents: CompileIdentifierMetadata[]) {
@ -142,17 +143,18 @@ export class CompileElement extends CompileNode {
beforeChildren(): void {
if (this.hasViewContainer) {
this.instances.add(
resolveIdentifierToken(Identifiers.ViewContainerRef), this.appElement.prop('vcRef'));
this.instances.set(
resolveIdentifierToken(Identifiers.ViewContainerRef).reference,
this.appElement.prop('vcRef'));
}
this._resolvedProviders = new CompileIdentifierMap<CompileTokenMetadata, ProviderAst>();
this._resolvedProviders = new Map<any, ProviderAst>();
this._resolvedProvidersArray.forEach(
provider => this._resolvedProviders.add(provider.token, provider));
provider => this._resolvedProviders.set(provider.token.reference, 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.
this._resolvedProviders.values().forEach((resolvedProvider) => {
MapWrapper.values(this._resolvedProviders).forEach((resolvedProvider) => {
var providerValueExpressions = resolvedProvider.providers.map((provider) => {
if (isPresent(provider.useExisting)) {
return this._getDependency(
@ -175,16 +177,16 @@ export class CompileElement extends CompileNode {
var instance = createProviderProperty(
propName, resolvedProvider, providerValueExpressions, resolvedProvider.multiProvider,
resolvedProvider.eager, this);
this.instances.add(resolvedProvider.token, instance);
this.instances.set(resolvedProvider.token.reference, instance);
});
for (var i = 0; i < this._directives.length; i++) {
var directive = this._directives[i];
var directiveInstance = this.instances.get(identifierToken(directive.type));
var directiveInstance = this.instances.get(identifierToken(directive.type).reference);
directive.queries.forEach((queryMeta) => { this._addQuery(queryMeta, directiveInstance); });
}
var queriesWithReads: _QueryWithRead[] = [];
this._resolvedProviders.values().forEach((resolvedProvider) => {
MapWrapper.values(this._resolvedProviders).forEach((resolvedProvider) => {
var queriesForProvider = this._getQueriesFor(resolvedProvider.token);
ListWrapper.addAll(
queriesWithReads,
@ -194,7 +196,7 @@ export class CompileElement extends CompileNode {
var token = this.referenceTokens[varName];
var varValue: o.Expression;
if (isPresent(token)) {
varValue = this.instances.get(token);
varValue = this.instances.get(token.reference);
} else {
varValue = this.renderNode;
}
@ -208,12 +210,12 @@ export class CompileElement extends CompileNode {
var value: o.Expression;
if (isPresent(queryWithRead.read.identifier)) {
// query for an identifier
value = this.instances.get(queryWithRead.read);
value = this.instances.get(queryWithRead.read.reference);
} else {
// query for a reference
var token = this.referenceTokens[queryWithRead.read.value];
if (isPresent(token)) {
value = this.instances.get(token);
value = this.instances.get(token.reference);
} else {
value = this.elementRef;
}
@ -238,11 +240,11 @@ export class CompileElement extends CompileNode {
}
afterChildren(childNodeCount: number) {
this._resolvedProviders.values().forEach((resolvedProvider) => {
MapWrapper.values(this._resolvedProviders).forEach((resolvedProvider) => {
// 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.
var providerExpr = this.instances.get(resolvedProvider.token);
var providerExpr = this.instances.get(resolvedProvider.token.reference);
// 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
@ -253,10 +255,11 @@ export class CompileElement extends CompileNode {
this.nodeIndex, providerChildNodeCount, resolvedProvider, providerExpr));
});
this._queries.values().forEach(
(queries) => queries.forEach(
(query) =>
query.afterChildren(this.view.createMethod, this.view.updateContentQueriesMethod)));
MapWrapper.values(this._queries)
.forEach(
(queries) => queries.forEach(
(query) => query.afterChildren(
this.view.createMethod, this.view.updateContentQueriesMethod)));
}
addContentNode(ngContentIndex: number, nodeExpr: o.Expression) {
@ -264,13 +267,14 @@ export class CompileElement extends CompileNode {
}
getComponent(): o.Expression {
return isPresent(this.component) ? this.instances.get(identifierToken(this.component.type)) :
null;
return isPresent(this.component) ?
this.instances.get(identifierToken(this.component.type).reference) :
null;
}
getProviderTokens(): o.Expression[] {
return this._resolvedProviders.values().map(
(resolvedProvider) => createDiTokenExpression(resolvedProvider.token));
return MapWrapper.values(this._resolvedProviders)
.map((resolvedProvider) => createDiTokenExpression(resolvedProvider.token));
}
private _getQueriesFor(token: CompileTokenMetadata): CompileQuery[] {
@ -279,7 +283,7 @@ export class CompileElement extends CompileNode {
var distance = 0;
var queries: CompileQuery[];
while (!currentEl.isNull()) {
queries = currentEl._queries.get(token);
queries = currentEl._queries.get(token.reference);
if (isPresent(queries)) {
ListWrapper.addAll(
result, queries.filter((query) => query.meta.descendants || distance <= 1));
@ -289,7 +293,7 @@ export class CompileElement extends CompileNode {
}
currentEl = currentEl.parent;
}
queries = this.view.componentView.viewQueries.get(token);
queries = this.view.componentView.viewQueries.get(token.reference);
if (isPresent(queries)) {
ListWrapper.addAll(result, queries);
}
@ -325,7 +329,8 @@ export class CompileElement extends CompileNode {
if (isPresent(dep.token)) {
// access builtins with special visibility
if (isBlank(result)) {
if (dep.token.equalsTo(resolveIdentifierToken(Identifiers.ChangeDetectorRef))) {
if (dep.token.reference ===
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
if (requestingProviderType === ProviderAstType.Component) {
return this._compViewExpr.prop('ref');
} else {
@ -335,7 +340,7 @@ export class CompileElement extends CompileNode {
}
// access regular providers on the element
if (isBlank(result)) {
let resolvedProvider = this._resolvedProviders.get(dep.token);
let resolvedProvider = this._resolvedProviders.get(dep.token.reference);
// don't allow directives / public services to access private services.
// only components and private services can access private services.
if (resolvedProvider && (requestingProviderType === ProviderAstType.Directive ||
@ -343,7 +348,7 @@ export class CompileElement extends CompileNode {
resolvedProvider.providerType === ProviderAstType.PrivateService) {
return null;
}
result = this.instances.get(dep.token);
result = this.instances.get(dep.token.reference);
}
}
return result;

View File

@ -42,7 +42,8 @@ export class CompilePipe {
constructor(public view: CompileView, public meta: CompilePipeMetadata) {
this.instance = o.THIS_EXPR.prop(`_pipe_${meta.name}_${view.pipeCount++}`);
var deps = this.meta.type.diDeps.map((diDep) => {
if (diDep.token.equalsTo(resolveIdentifierToken(Identifiers.ChangeDetectorRef))) {
if (diDep.token.reference ===
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
return getPropertyInView(o.THIS_EXPR.prop('ref'), this.view, this.view.componentView);
}
return injectFromViewParentInjector(diDep.token, false);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {CompileIdentifierMap, CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata';
import {CompileQueryMetadata, CompileTokenMetadata} from '../compile_metadata';
import {ListWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
@ -126,13 +126,12 @@ export function createQueryList(
return expr;
}
export function addQueryToTokenMap(
map: CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>, query: CompileQuery) {
export function addQueryToTokenMap(map: Map<any, CompileQuery[]>, query: CompileQuery) {
query.meta.selectors.forEach((selector) => {
var entry = map.get(selector);
var entry = map.get(selector.reference);
if (isBlank(entry)) {
entry = [];
map.add(selector, entry);
map.set(selector.reference, entry);
}
entry.push(query);
});

View File

@ -8,9 +8,9 @@
import {ViewType} from '../../core_private';
import {CompiledAnimationTriggerResult} from '../animation/animation_compiler';
import {CompileDirectiveMetadata, CompileIdentifierMap, CompileIdentifierMetadata, CompilePipeMetadata, CompileTokenMetadata} from '../compile_metadata';
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompilePipeMetadata, CompileTokenMetadata} from '../compile_metadata';
import {CompilerConfig} from '../config';
import {ListWrapper} from '../facade/collection';
import {ListWrapper, MapWrapper} from '../facade/collection';
import {isBlank, isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
@ -27,7 +27,7 @@ import {createPureProxy, getPropertyInView, getViewFactoryName, injectFromViewPa
export class CompileView implements NameResolver {
public viewType: ViewType;
public viewQueries: CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>;
public viewQueries: Map<any, CompileQuery[]>;
public nodes: CompileNode[] = [];
// root nodes or AppElements for ViewContainers
@ -98,7 +98,7 @@ export class CompileView implements NameResolver {
this.componentContext =
getPropertyInView(o.THIS_EXPR.prop('context'), this, this.componentView);
var viewQueries = new CompileIdentifierMap<CompileTokenMetadata, CompileQuery[]>();
var viewQueries = new Map<any, CompileQuery[]>();
if (this.viewType === ViewType.COMPONENT) {
var directiveInstance = o.THIS_EXPR.prop('context');
ListWrapper.forEachWithIndex(this.component.viewQueries, (queryMeta, queryIndex) => {
@ -191,9 +191,10 @@ export class CompileView implements NameResolver {
}
afterNodes() {
this.viewQueries.values().forEach(
(queries) => queries.forEach(
(query) => query.afterChildren(this.createMethod, this.updateViewQueriesMethod)));
MapWrapper.values(this.viewQueries)
.forEach(
(queries) => queries.forEach(
(query) => query.afterChildren(this.createMethod, this.updateViewQueriesMethod)));
}
}

View File

@ -165,7 +165,7 @@ export function collectEventListeners(
});
dirs.forEach((directiveAst) => {
var directiveInstance =
compileElement.instances.get(identifierToken(directiveAst.directive.type));
compileElement.instances.get(identifierToken(directiveAst.directive.type).reference);
directiveAst.hostEvents.forEach((hostEvent) => {
compileElement.view.bindings.push(new CompileBinding(compileElement, hostEvent));
var listener = CompileEventListener.getOrCreate(

View File

@ -67,8 +67,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
bindRenderInputs(ast.inputs, compileElement);
bindRenderOutputs(eventListeners);
ast.directives.forEach((directiveAst) => {
var directiveInstance =
compileElement.instances.get(identifierToken(directiveAst.directive.type));
var directiveInstance = compileElement.instances.get(directiveAst.directive.type.reference);
bindDirectiveInputs(directiveAst, directiveInstance, compileElement);
bindDirectiveDetectChangesLifecycleCallbacks(directiveAst, directiveInstance, compileElement);
@ -79,15 +78,14 @@ class ViewBinderVisitor implements TemplateAstVisitor {
// afterContent and afterView lifecycles need to be called bottom up
// so that children are notified before parents
ast.directives.forEach((directiveAst) => {
var directiveInstance =
compileElement.instances.get(identifierToken(directiveAst.directive.type));
var directiveInstance = compileElement.instances.get(directiveAst.directive.type.reference);
bindDirectiveAfterContentLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
bindDirectiveAfterViewLifecycleCallbacks(
directiveAst.directive, directiveInstance, compileElement);
});
ast.providers.forEach((providerAst) => {
var providerInstance = compileElement.instances.get(providerAst.token);
var providerInstance = compileElement.instances.get(providerAst.token.reference);
bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement);
});
return null;
@ -97,8 +95,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
var compileElement = <CompileElement>this.view.nodes[this._nodeIndex++];
var eventListeners = collectEventListeners(ast.outputs, ast.directives, compileElement);
ast.directives.forEach((directiveAst) => {
var directiveInstance =
compileElement.instances.get(identifierToken(directiveAst.directive.type));
var directiveInstance = compileElement.instances.get(directiveAst.directive.type.reference);
bindDirectiveInputs(directiveAst, directiveInstance, compileElement);
bindDirectiveDetectChangesLifecycleCallbacks(directiveAst, directiveInstance, compileElement);
bindDirectiveOutputs(directiveAst, directiveInstance, eventListeners);
@ -108,7 +105,7 @@ class ViewBinderVisitor implements TemplateAstVisitor {
directiveAst.directive, directiveInstance, compileElement);
});
ast.providers.forEach((providerAst) => {
var providerInstance = compileElement.instances.get(providerAst.token);
var providerInstance = compileElement.instances.get(providerAst.token.reference);
bindInjectableDestroyLifecycleCallbacks(providerAst, providerInstance, compileElement);
});
bindView(compileElement.embeddedView, ast.children, []);