From e5fdf4c70ace58e5af9c99200bac3195fba530bf Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Mon, 31 Oct 2016 10:10:13 -0700 Subject: [PATCH] refactor(compiler): inline view.viewChildren in generated code --- .../src/view_compiler/compile_view.ts | 2 ++ .../src/view_compiler/view_builder.ts | 25 ++++++++++++++----- modules/@angular/core/src/linker/view.ts | 20 ++------------- .../src/tree/ng2_ftl/tree_host.ngfactory.ts | 2 +- .../ng2_static_ftl/tree_root.ngfactory.ts | 19 ++++++++------ 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/modules/@angular/compiler/src/view_compiler/compile_view.ts b/modules/@angular/compiler/src/view_compiler/compile_view.ts index b76043a032..224c7cfe7d 100644 --- a/modules/@angular/compiler/src/view_compiler/compile_view.ts +++ b/modules/@angular/compiler/src/view_compiler/compile_view.ts @@ -27,6 +27,8 @@ export class CompileView implements NameResolver { public viewType: ViewType; public viewQueries: Map; + public viewChildren: o.Expression[] = []; + public nodes: CompileNode[] = []; // root nodes or AppElements for ViewContainers public rootNodesOrAppElements: o.Expression[] = []; diff --git a/modules/@angular/compiler/src/view_compiler/view_builder.ts b/modules/@angular/compiler/src/view_compiler/view_builder.ts index 17739360c8..90b1c3befc 100644 --- a/modules/@angular/compiler/src/view_compiler/view_builder.ts +++ b/modules/@angular/compiler/src/view_compiler/view_builder.ts @@ -194,21 +194,25 @@ class ViewBuilderVisitor implements TemplateAstVisitor { parent, this.view, nodeIndex, renderNode, ast, component, directives, ast.providers, ast.hasViewContainer, false, ast.references, this.targetDependencies); this.view.nodes.push(compileElement); - var compViewExpr: o.ReadVarExpr = null; + var compViewExpr: o.ReadPropExpr = null; if (isPresent(component)) { let nestedComponentIdentifier = new CompileIdentifierMetadata({name: getViewFactoryName(component, 0)}); this.targetDependencies.push( new ViewFactoryDependency(component.type, nestedComponentIdentifier)); - compViewExpr = o.variable(`compView_${nodeIndex}`); // fix highlighting: ` + 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)]))); + this.view.viewChildren.push(compViewExpr); compileElement.setComponentView(compViewExpr); this.view.createMethod.addStmt( compViewExpr .set(o.importExpr(nestedComponentIdentifier).callFn([ ViewProperties.viewUtils, compileElement.injector, compileElement.appElement ])) - .toDeclStmt()); + .toStmt()); } compileElement.beforeChildren(); this._addRootNodeAndProject(compileElement); @@ -452,7 +456,7 @@ function createViewClass( 'detectChangesInternal', [new o.FnParam(DetectChangesVars.throwOnChange.name, o.BOOL_TYPE)], generateDetectChangesMethod(view)), new o.ClassMethod('dirtyParentQueriesInternal', [], view.dirtyParentQueriesMethod.finish()), - new o.ClassMethod('destroyInternal', [], view.destroyMethod.finish()), + new o.ClassMethod('destroyInternal', [], generateDestroyMethod(view)), new o.ClassMethod('detachInternal', [], view.detachMethod.finish()) ].filter((method) => method.body.length > 0); var superClass = view.genConfig.genDebugInfo ? Identifiers.DebugAppView : Identifiers.AppView; @@ -467,6 +471,14 @@ function createViewClass( return viewClass; } +function generateDestroyMethod(view: CompileView): o.Statement[] { + const stmts: o.Statement[] = []; + view.viewChildren.forEach( + (viewChild) => { stmts.push(viewChild.callMethod('destroy', []).toStmt()); }); + stmts.push(...view.destroyMethod.finish()); + return stmts; +} + function createViewFactory( view: CompileView, viewClass: o.ClassStmt, renderCompTypeVar: o.ReadVarExpr): o.Statement { var viewFactoryArgs = [ @@ -569,8 +581,9 @@ function generateDetectChangesMethod(view: CompileView): o.Statement[] { stmts.push(new o.IfStmt(o.not(DetectChangesVars.throwOnChange), afterContentStmts)); } stmts.push(...view.detectChangesRenderPropertiesMethod.finish()); - stmts.push(o.THIS_EXPR.callMethod('detectViewChildrenChanges', [DetectChangesVars.throwOnChange]) - .toStmt()); + view.viewChildren.forEach((viewChild) => { + stmts.push(viewChild.callMethod('detectChanges', [DetectChangesVars.throwOnChange]).toStmt()); + }); var afterViewStmts = view.updateViewQueriesMethod.finish().concat(view.afterViewLifecycleCallbacksMethod.finish()); if (afterViewStmts.length > 0) { diff --git a/modules/@angular/core/src/linker/view.ts b/modules/@angular/core/src/linker/view.ts index 9d5e70d786..e532ded49f 100644 --- a/modules/@angular/core/src/linker/view.ts +++ b/modules/@angular/core/src/linker/view.ts @@ -34,7 +34,6 @@ export abstract class AppView { allNodes: any[]; disposables: Function[]; contentChildren: AppView[] = []; - viewChildren: AppView[] = []; viewContainerElement: AppElement = null; numberOfChecks: number = 0; @@ -102,9 +101,6 @@ export abstract class AppView { this.allNodes = allNodes; this.disposables = disposables; if (this.type === ViewType.COMPONENT) { - // Note: the render nodes have been attached to their host element - // in the ViewFactory already. - this.declarationAppElement.parentView.viewChildren.push(this); this.dirtyParentQueriesInternal(); } } @@ -145,10 +141,6 @@ export abstract class AppView { for (var i = 0; i < children.length; i++) { children[i]._destroyRecurse(); } - children = this.viewChildren; - for (var i = 0; i < children.length; i++) { - children[i]._destroyRecurse(); - } this.destroyLocal(); this.cdMode = ChangeDetectorStatus.Destroyed; @@ -214,7 +206,8 @@ export abstract class AppView { detectChanges(throwOnChange: boolean): void { var s = _scope_check(this.clazz); if (this.cdMode === ChangeDetectorStatus.Checked || - this.cdMode === ChangeDetectorStatus.Errored) + this.cdMode === ChangeDetectorStatus.Errored || + this.cdMode === ChangeDetectorStatus.Detached) return; if (this.cdMode === ChangeDetectorStatus.Destroyed) { this.throwDestroyedError('detectChanges'); @@ -231,7 +224,6 @@ export abstract class AppView { */ detectChangesInternal(throwOnChange: boolean): void { this.detectContentChildrenChanges(throwOnChange); - this.detectViewChildrenChanges(throwOnChange); } detectContentChildrenChanges(throwOnChange: boolean) { @@ -242,14 +234,6 @@ export abstract class AppView { } } - detectViewChildrenChanges(throwOnChange: boolean) { - for (var i = 0; i < this.viewChildren.length; ++i) { - var child = this.viewChildren[i]; - if (child.cdMode === ChangeDetectorStatus.Detached) continue; - child.detectChanges(throwOnChange); - } - } - markContentChildAsMoved(renderAppElement: AppElement): void { this.dirtyParentQueriesInternal(); } addToContentChildren(renderAppElement: AppElement): void { diff --git a/modules/benchmarks/src/tree/ng2_ftl/tree_host.ngfactory.ts b/modules/benchmarks/src/tree/ng2_ftl/tree_host.ngfactory.ts index 6656047838..235d71a43a 100644 --- a/modules/benchmarks/src/tree/ng2_ftl/tree_host.ngfactory.ts +++ b/modules/benchmarks/src/tree/ng2_ftl/tree_host.ngfactory.ts @@ -38,7 +38,7 @@ class _View_TreeComponent_Host0 extends import1.AppView { this._vc_0 = new import2.AppElement(0, (null as any), this, this._el_0); this._TreeComponent_0_4 = new _View_TreeComponent0(this._el_0); this._vc_0.initComponent(this._TreeComponent_0_4.context, [], this._TreeComponent_0_4); - this.init([].concat([this._el_0]), [this._el_0], [], []); + this.init([].concat([this._el_0]), [this._el_0], []); return this._vc_0; } detectChangesInternal(throwOnChange: boolean): void { diff --git a/modules/benchmarks/src/tree/ng2_static_ftl/tree_root.ngfactory.ts b/modules/benchmarks/src/tree/ng2_static_ftl/tree_root.ngfactory.ts index 225d9df54a..e8ac52ce84 100644 --- a/modules/benchmarks/src/tree/ng2_static_ftl/tree_root.ngfactory.ts +++ b/modules/benchmarks/src/tree/ng2_static_ftl/tree_root.ngfactory.ts @@ -27,6 +27,7 @@ class _View_TreeRootComponent_Host0 extends import1.AppView { _el_0: any; /*private*/ _appEl_0: import2.AppElement; _TreeRootComponent_0_4: import3.TreeRootComponent; + _TreeRootComponent_0_4_View: any; constructor( viewUtils: import4.ViewUtils, parentInjector: import5.Injector, declarationEl: import2.AppElement) { @@ -38,14 +39,19 @@ class _View_TreeRootComponent_Host0 extends import1.AppView { this._el_0 = import4.selectOrCreateRenderHostElement( this.renderer, 'tree', import4.EMPTY_INLINE_ARRAY, rootSelector, (null as any)); this._appEl_0 = new import2.AppElement(0, (null as any), this, this._el_0); - var compView_0: any = + this._TreeRootComponent_0_4_View = viewFactory_TreeRootComponent0(this.viewUtils, this.injector(0), this._appEl_0); this._TreeRootComponent_0_4 = new import3.TreeRootComponent(); - this._appEl_0.initComponent(this._TreeRootComponent_0_4, [], compView_0); - compView_0.create(this._TreeRootComponent_0_4, this.projectableNodes, (null as any)); - this.init([].concat([this._el_0]), [this._el_0], [], []); + this._appEl_0.initComponent(this._TreeRootComponent_0_4, [], this._TreeRootComponent_0_4_View); + this._TreeRootComponent_0_4_View.create( + this._TreeRootComponent_0_4, this.projectableNodes, (null as any)); + this.init([].concat([this._el_0]), [this._el_0], []); return this._appEl_0; } + detectChangesInternal(throwOnChange: boolean): void { + this._TreeRootComponent_0_4_View.detectChangesInternal(throwOnChange); + } + destroyInternal(): void { this._TreeRootComponent_0_4_View.destroyInternal(); } injectorGetInternal(token: any, requestNodeIndex: number, notFoundResult: any): any { if (((token === import3.TreeRootComponent) && (0 === requestNodeIndex))) { return this._TreeRootComponent_0_4; @@ -89,7 +95,7 @@ class _View_TreeRootComponent0 extends import1.AppView { createInternal(rootSelector: string): import2.AppElement { this._el_0 = this.renderer.createElement((null as any), 'tree0', (null as any)); this._TreeComponent0_0_4View = new import13.View_TreeTreeComponent(maxDepth - 1, this._el_0); - this.init([].concat([this._el_0]), [this._el_0], [], []); + this.init([].concat([this._el_0]), [this._el_0], []); return (null as any); } destroyInternal() { this._TreeComponent0_0_4View.destroyInternal(); }