refactor(compiler): remove `view.parentInjector`

This commit is contained in:
Tobias Bosch 2016-11-01 11:45:27 -07:00 committed by vikerman
parent e7c00be19d
commit 20a4f9923f
10 changed files with 91 additions and 101 deletions

View File

@ -42,7 +42,6 @@ export class CompileElement extends CompileNode {
public compViewExpr: o.Expression = null;
public viewContainer: o.ReadPropExpr;
public elementRef: o.Expression;
public injector: o.Expression;
public instances = new Map<any, o.Expression>();
public directiveWrapperInstance = new Map<any, o.Expression>();
private _resolvedProviders: Map<any, ProviderAst>;
@ -69,8 +68,9 @@ export class CompileElement extends CompileNode {
this.elementRef =
o.importExpr(resolveIdentifier(Identifiers.ElementRef)).instantiate([this.renderNode]);
this.instances.set(resolveIdentifierToken(Identifiers.ElementRef).reference, this.elementRef);
this.injector = o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]);
this.instances.set(resolveIdentifierToken(Identifiers.Injector).reference, this.injector);
this.instances.set(
resolveIdentifierToken(Identifiers.Injector).reference,
o.THIS_EXPR.callMethod('injector', [o.literal(this.nodeIndex)]));
this.instances.set(
resolveIdentifierToken(Identifiers.Renderer).reference, o.THIS_EXPR.prop('renderer'));
if (this.hasViewContainer) {
@ -115,7 +115,7 @@ export class CompileElement extends CompileNode {
o.importExpr(resolveIdentifier(Identifiers.CodegenComponentFactoryResolver)).instantiate([
o.literalArr(entryComponents.map((entryComponent) => o.importExpr(entryComponent))),
injectFromViewParentInjector(
resolveIdentifierToken(Identifiers.ComponentFactoryResolver), false)
this.view, resolveIdentifierToken(Identifiers.ComponentFactoryResolver), false)
]);
var provider = new CompileProviderMetadata({
token: resolveIdentifierToken(Identifiers.ComponentFactoryResolver),
@ -373,7 +373,7 @@ export class CompileElement extends CompileNode {
}
if (!result) {
result = injectFromViewParentInjector(dep.token, dep.isOptional);
result = injectFromViewParentInjector(this.view, dep.token, dep.isOptional);
}
if (!result) {
result = o.NULL_EXPR;

View File

@ -46,7 +46,7 @@ export class CompilePipe {
resolveIdentifierToken(Identifiers.ChangeDetectorRef).reference) {
return getPropertyInView(o.THIS_EXPR.prop('ref'), this.view, this.view.componentView);
}
return injectFromViewParentInjector(diDep.token, false);
return injectFromViewParentInjector(view, diDep.token, false);
});
this.view.fields.push(new o.ClassField(this.instance.name, o.importType(this.meta.type)));
this.view.createMethod.resetDebugInfo(null, null);

View File

@ -39,7 +39,6 @@ export class ChangeDetectorStatusEnum {
export class ViewConstructorVars {
static viewUtils = o.variable('viewUtils');
static parentInjector = o.variable('parentInjector');
static parentView = o.variable('parentView');
static parentIndex = o.variable('parentIndex');
static parentElement = o.variable('parentElement');

View File

@ -12,6 +12,7 @@ import {createDiTokenExpression} from '../compiler_util/identifier_util';
import {isPresent} from '../facade/lang';
import {Identifiers, resolveIdentifier} from '../identifiers';
import * as o from '../output/output_ast';
import {ViewType} from '../private_import_core';
import {CompileView} from './compile_view';
@ -56,12 +57,18 @@ class _ReplaceViewTransformer extends o.ExpressionTransformer {
}
export function injectFromViewParentInjector(
token: CompileTokenMetadata, optional: boolean): o.Expression {
var args = [createDiTokenExpression(token)];
view: CompileView, token: CompileTokenMetadata, optional: boolean): o.Expression {
let viewExpr: o.Expression;
if (view.viewType === ViewType.HOST) {
viewExpr = o.THIS_EXPR;
} else {
viewExpr = o.THIS_EXPR.prop('parentView');
}
let args = [createDiTokenExpression(token), o.THIS_EXPR.prop('parentIndex')];
if (optional) {
args.push(o.NULL_EXPR);
}
return o.THIS_EXPR.prop('parentInjector').callMethod('get', args);
return viewExpr.callMethod('injectorGet', args);
}
export function getViewFactoryName(
@ -71,4 +78,4 @@ export function getViewFactoryName(
export function getHandleEventMethodName(elementIndex: number): string {
return `handleEvent_${elementIndex}`;
}
}

View File

@ -232,12 +232,12 @@ class ViewBuilderVisitor implements TemplateAstVisitor {
o.importType(resolveIdentifier(Identifiers.AppView), [o.importType(component.type)])));
this.view.viewChildren.push(compViewExpr);
compileElement.setComponentView(compViewExpr);
this.view.createMethod.addStmt(compViewExpr
.set(o.importExpr(nestedComponentIdentifier).callFn([
ViewProperties.viewUtils, compileElement.injector,
o.THIS_EXPR, o.literal(nodeIndex), renderNode
]))
.toStmt());
this.view.createMethod.addStmt(
compViewExpr
.set(o.importExpr(nestedComponentIdentifier).callFn([
ViewProperties.viewUtils, o.THIS_EXPR, o.literal(nodeIndex), renderNode
]))
.toStmt());
}
compileElement.beforeChildren();
this._addRootNodeAndProject(compileElement);
@ -437,9 +437,6 @@ function createViewClass(
var viewConstructorArgs = [
new o.FnParam(
ViewConstructorVars.viewUtils.name, o.importType(resolveIdentifier(Identifiers.ViewUtils))),
new o.FnParam(
ViewConstructorVars.parentInjector.name,
o.importType(resolveIdentifier(Identifiers.Injector))),
new o.FnParam(
ViewConstructorVars.parentView.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
@ -448,8 +445,7 @@ function createViewClass(
];
var superConstructorArgs = [
o.variable(view.className), renderCompTypeVar, ViewTypeEnum.fromValue(view.viewType),
ViewConstructorVars.viewUtils, ViewConstructorVars.parentInjector,
ViewConstructorVars.parentView, ViewConstructorVars.parentIndex,
ViewConstructorVars.viewUtils, ViewConstructorVars.parentView, ViewConstructorVars.parentIndex,
ViewConstructorVars.parentElement,
ChangeDetectorStatusEnum.fromValue(getChangeDetectionMode(view))
];
@ -507,9 +503,6 @@ function createViewFactory(
var viewFactoryArgs = [
new o.FnParam(
ViewConstructorVars.viewUtils.name, o.importType(resolveIdentifier(Identifiers.ViewUtils))),
new o.FnParam(
ViewConstructorVars.parentInjector.name,
o.importType(resolveIdentifier(Identifiers.Injector))),
new o.FnParam(
ViewConstructorVars.parentView.name,
o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
@ -729,9 +722,7 @@ function generateCreateEmbeddedViewsMethod(view: CompileView) {
stmts.push(new o.IfStmt(
nodeIndexVar.equals(o.literal(node.nodeIndex)),
[new o.ReturnStatement(node.embeddedView.viewFactory.callFn([
ViewProperties.viewUtils,
o.THIS_EXPR.callMethod('injector', [o.literal(parentNodeIndex)]), o.THIS_EXPR,
o.literal(node.nodeIndex), node.renderNode
ViewProperties.viewUtils, o.THIS_EXPR, o.literal(node.nodeIndex), node.renderNode
]))]));
}
}

View File

@ -110,17 +110,7 @@ export class ComponentFactory<C> {
if (!projectableNodes) {
projectableNodes = [];
}
var hostView: AppView<any> = this._viewFactory(vu, injector, null, null, null);
// TODO: implement this in the View class directly?!
// (behind a `if (this.type === ViewType.HOST)`)
// TODO: and pass the projectableNodes into `createHostView`
hostView.visitProjectableNodesInternal =
(nodeIndex: number, ngContentIndex: number, cb: any, ctx: any) => {
const nodes = projectableNodes[ngContentIndex] || [];
for (var i = 0; i < nodes.length; i++) {
cb(nodes[i], ctx);
}
};
return hostView.createHostView(rootSelectorOrNode);
var hostView: AppView<any> = this._viewFactory(vu, null, null, null);
return hostView.createHostView(rootSelectorOrNode, injector, projectableNodes);
}
}

View File

@ -15,13 +15,6 @@ export class ElementInjector extends Injector {
constructor(private _view: AppView<any>, private _nodeIndex: number) { super(); }
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
var result = _UNDEFINED;
if (result === _UNDEFINED) {
result = this._view.injectorGet(token, this._nodeIndex, _UNDEFINED);
}
if (result === _UNDEFINED) {
result = this._view.parentInjector.get(token, notFoundValue);
}
return result;
return this._view.injectorGet(token, this._nodeIndex, notFoundValue);
}
}

View File

@ -7,7 +7,7 @@
*/
import {ChangeDetectorRef, ChangeDetectorStatus} from '../change_detection/change_detection';
import {Injector} from '../di/injector';
import {Injector, THROW_IF_NOT_FOUND} from '../di/injector';
import {ListWrapper} from '../facade/collection';
import {isPresent} from '../facade/lang';
import {WtfScopeFn, wtfCreateScope, wtfLeave} from '../profile/profile';
@ -30,6 +30,8 @@ var _scope_check: WtfScopeFn = wtfCreateScope(`AppView#check(ascii id)`);
*/
const EMPTY_CONTEXT = new Object();
const UNDEFINED = new Object();
/**
* Cost of making objects: http://jsperf.com/instantiate-size-of-object
*
@ -46,14 +48,16 @@ export abstract class AppView<T> {
renderer: Renderer;
private _hasExternalHostElement: boolean;
private _hostInjector: Injector;
private _hostProjectableNodes: any[][];
private _animationContext: AnimationViewContext;
public context: T;
constructor(
public clazz: any, public componentType: RenderComponentType, public type: ViewType,
public viewUtils: ViewUtils, public parentInjector: Injector, public parentView: AppView<any>,
public parentIndex: number, public parentElement: any, public cdMode: ChangeDetectorStatus) {
public viewUtils: ViewUtils, public parentView: AppView<any>, public parentIndex: number,
public parentElement: any, public cdMode: ChangeDetectorStatus) {
this.ref = new ViewRef_(this);
if (type === ViewType.COMPONENT || type === ViewType.HOST) {
this.renderer = viewUtils.renderComponent(componentType);
@ -76,9 +80,12 @@ export abstract class AppView<T> {
return this.createInternal(null);
}
createHostView(rootSelectorOrNode: string|any): ComponentRef<any> {
createHostView(rootSelectorOrNode: string|any, hostInjector: Injector, projectableNodes: any[][]):
ComponentRef<any> {
this.context = <any>EMPTY_CONTEXT;
this._hasExternalHostElement = isPresent(rootSelectorOrNode);
this._hostInjector = hostInjector;
this._hostProjectableNodes = projectableNodes;
return this.createInternal(rootSelectorOrNode);
}
@ -102,8 +109,20 @@ export abstract class AppView<T> {
}
}
injectorGet(token: any, nodeIndex: number, notFoundResult: any): any {
return this.injectorGetInternal(token, nodeIndex, notFoundResult);
injectorGet(token: any, nodeIndex: number, notFoundValue: any = THROW_IF_NOT_FOUND): any {
let result = UNDEFINED;
let view: AppView<any> = this;
while (result === UNDEFINED) {
if (isPresent(nodeIndex)) {
result = view.injectorGetInternal(token, nodeIndex, UNDEFINED);
}
if (result === UNDEFINED && view.type === ViewType.HOST) {
result = view._hostInjector.get(token, notFoundValue);
}
nodeIndex = view.parentIndex;
view = view.parentView;
}
return result;
}
/**
@ -113,13 +132,7 @@ export abstract class AppView<T> {
return notFoundResult;
}
injector(nodeIndex: number): Injector {
if (isPresent(nodeIndex)) {
return new ElementInjector(this, nodeIndex);
} else {
return this.parentInjector;
}
}
injector(nodeIndex: number): Injector { return new ElementInjector(this, nodeIndex); }
detachAndDestroy() {
if (this._hasExternalHostElement) {
@ -193,7 +206,14 @@ export abstract class AppView<T> {
this.parentView.visitProjectedNodes(ngContentIndex, cb, c);
break;
case ViewType.COMPONENT:
this.parentView.visitProjectableNodesInternal(this.parentIndex, ngContentIndex, cb, c);
if (this.parentView.type === ViewType.HOST) {
const nodes = this.parentView._hostProjectableNodes[ngContentIndex] || [];
for (var i = 0; i < nodes.length; i++) {
cb(nodes[i], c);
}
} else {
this.parentView.visitProjectableNodesInternal(this.parentIndex, ngContentIndex, cb, c);
}
break;
}
}
@ -275,11 +295,9 @@ export class DebugAppView<T> extends AppView<T> {
constructor(
clazz: any, componentType: RenderComponentType, type: ViewType, viewUtils: ViewUtils,
parentInjector: Injector, parentView: AppView<any>, parentIndex: number, parentNode: any,
cdMode: ChangeDetectorStatus, public staticNodeDebugInfos: StaticNodeDebugInfo[]) {
super(
clazz, componentType, type, viewUtils, parentInjector, parentView, parentIndex, parentNode,
cdMode);
parentView: AppView<any>, parentIndex: number, parentNode: any, cdMode: ChangeDetectorStatus,
public staticNodeDebugInfos: StaticNodeDebugInfo[]) {
super(clazz, componentType, type, viewUtils, parentView, parentIndex, parentNode, cdMode);
}
create(context: T) {
@ -292,10 +310,12 @@ export class DebugAppView<T> extends AppView<T> {
}
}
createHostView(rootSelectorOrNode: string|any): ComponentRef<any> {
createHostView(
rootSelectorOrNode: string|any, injector: Injector,
projectableNodes: any[][] = null): ComponentRef<any> {
this._resetDebug();
try {
return super.createHostView(rootSelectorOrNode);
return super.createHostView(rootSelectorOrNode, injector, projectableNodes);
} catch (e) {
this._rethrowWithContext(e);
throw e;

View File

@ -26,12 +26,11 @@ class _View_TreeComponent_Host0 extends import1.AppView<any> {
_vc_0: import2.ViewContainer;
_TreeComponent_0_4: _View_TreeComponent0;
constructor(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number, parentElement: any) {
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any) {
super(
_View_TreeComponent_Host0, renderType_TreeComponent_Host, import6.ViewType.HOST, viewUtils,
parentInjector, parentView, parentIndex, parentElement,
import7.ChangeDetectorStatus.CheckAlways);
parentView, parentIndex, parentElement, import7.ChangeDetectorStatus.CheckAlways);
}
createInternal(rootSelector: string): import9.ComponentRef<any> {
this._el_0 = import4.selectOrCreateRenderHostElement(
@ -53,15 +52,13 @@ class _View_TreeComponent_Host0 extends import1.AppView<any> {
}
}
function viewFactory_TreeComponent_Host0(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number,
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any): import1.AppView<any> {
if ((renderType_TreeComponent_Host === (null as any))) {
(renderType_TreeComponent_Host =
viewUtils.createRenderComponentType('', 0, import8.ViewEncapsulation.None, [], {}));
}
return new _View_TreeComponent_Host0(
viewUtils, parentInjector, parentView, parentIndex, parentElement);
return new _View_TreeComponent_Host0(viewUtils, parentView, parentIndex, parentElement);
}
export const TreeComponentNgFactory: import9.ComponentFactory<import3.TreeComponent> =
new import9.ComponentFactory<import3.TreeComponent>(

View File

@ -29,11 +29,11 @@ class _View_TreeRootComponent_Host0 extends import1.AppView<any> {
_TreeRootComponent_0_4: import3.TreeRootComponent;
_TreeRootComponent_0_4_View: any;
constructor(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number, parentElement: any) {
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any) {
super(
_View_TreeRootComponent_Host0, renderType_TreeRootComponent_Host, import6.ViewType.HOST,
viewUtils, parentInjector, parentView, parentIndex, parentElement,
viewUtils, parentView, parentIndex, parentElement,
import7.ChangeDetectorStatus.CheckAlways);
}
createInternal(rootSelector: string): import9.ComponentRef<any> {
@ -41,7 +41,7 @@ class _View_TreeRootComponent_Host0 extends import1.AppView<any> {
this.renderer, 'tree', import4.EMPTY_INLINE_ARRAY, rootSelector, (null as any));
this._appEl_0 = new import2.ViewContainer(0, (null as any), this, this._el_0);
this._TreeRootComponent_0_4_View =
viewFactory_TreeRootComponent0(this.viewUtils, this.injector(0), this, 0, this._el_0);
viewFactory_TreeRootComponent0(this.viewUtils, this, 0, this._el_0);
this._TreeRootComponent_0_4 = new import3.TreeRootComponent();
this._TreeRootComponent_0_4_View.create(this._TreeRootComponent_0_4, (null as any));
this.init([].concat([this._el_0]), [this._el_0], []);
@ -59,15 +59,13 @@ class _View_TreeRootComponent_Host0 extends import1.AppView<any> {
}
}
function viewFactory_TreeRootComponent_Host0(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number,
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any): import1.AppView<any> {
if ((renderType_TreeRootComponent_Host === (null as any))) {
(renderType_TreeRootComponent_Host =
viewUtils.createRenderComponentType('', 0, import8.ViewEncapsulation.None, [], {}));
}
return new _View_TreeRootComponent_Host0(
viewUtils, parentInjector, parentView, parentIndex, parentElement);
return new _View_TreeRootComponent_Host0(viewUtils, parentView, parentIndex, parentElement);
}
export const TreeRootComponentNgFactory: import9.ComponentFactory<import3.TreeRootComponent> =
new import9.ComponentFactory<import3.TreeRootComponent>(
@ -81,11 +79,11 @@ class _View_TreeRootComponent0 extends import1.AppView<import3.TreeRootComponent
_NgIf_0_6: import10.NgIf;
/*private*/ _expr_0: any;
constructor(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number, parentElement: any) {
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any) {
super(
_View_TreeRootComponent0, renderType_TreeRootComponent, import6.ViewType.COMPONENT,
viewUtils, parentInjector, parentView, parentIndex, parentElement,
viewUtils, parentView, parentIndex, parentElement,
import7.ChangeDetectorStatus.CheckAlways);
}
createInternal(rootSelector: string): import9.ComponentRef<any> {
@ -101,8 +99,7 @@ class _View_TreeRootComponent0 extends import1.AppView<import3.TreeRootComponent
createEmbeddedViewInternal(nodeIndex: number): import1.AppView<any> {
if (nodeIndex === 0) {
return viewFactory_TreeRootComponent1(
this.viewUtils, this.parentInjector, this, 0, this._anchor_0);
return viewFactory_TreeRootComponent1(this.viewUtils, this, 0, this._anchor_0);
}
}
@ -125,26 +122,24 @@ class _View_TreeRootComponent0 extends import1.AppView<import3.TreeRootComponent
}
}
export function viewFactory_TreeRootComponent0(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number,
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any): import1.AppView<import3.TreeRootComponent> {
if ((renderType_TreeRootComponent === (null as any))) {
(renderType_TreeRootComponent = viewUtils.createRenderComponentType(
'/Users/tbosch/projects/conf-demos/ngc-demo/src/ng2_static/root_tree.ts class TreeRootComponent - inline template',
0, import8.ViewEncapsulation.None, styles_TreeRootComponent, {}));
}
return new _View_TreeRootComponent0(
viewUtils, parentInjector, parentView, parentIndex, parentElement);
return new _View_TreeRootComponent0(viewUtils, parentView, parentIndex, parentElement);
}
class _View_TreeRootComponent1 extends import1.AppView<any> {
_el_0: any;
_TreeComponent0_0_4View: any;
constructor(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number, parentElement: any) {
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any) {
super(
_View_TreeRootComponent1, renderType_TreeRootComponent, import6.ViewType.EMBEDDED,
viewUtils, parentInjector, parentView, parentIndex, parentElement,
viewUtils, parentView, parentIndex, parentElement,
import7.ChangeDetectorStatus.CheckAlways);
}
createInternal(rootSelector: string): import9.ComponentRef<any> {
@ -161,9 +156,7 @@ class _View_TreeRootComponent1 extends import1.AppView<any> {
visitRootNodesInternal(cb: any, context: any) { cb(this._el_0, context); }
}
function viewFactory_TreeRootComponent1(
viewUtils: import4.ViewUtils, parentInjector: import5.Injector,
parentView: import1.AppView<any>, parentIndex: number,
viewUtils: import4.ViewUtils, parentView: import1.AppView<any>, parentIndex: number,
parentElement: any): import1.AppView<any> {
return new _View_TreeRootComponent1(
viewUtils, parentInjector, parentView, parentIndex, parentElement);
return new _View_TreeRootComponent1(viewUtils, parentView, parentIndex, parentElement);
}