Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ivy): combine LView with data #24382

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 10 additions & 13 deletions packages/core/src/render3/component.ts
Expand Up @@ -10,19 +10,16 @@
// correctly implementing its interfaces for backwards compatibility.
import {Type} from '../core';
import {Injector} from '../di/injector';
import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
import {Sanitizer} from '../sanitization/security';

import {assertComponentType, assertDefined} from './assert';
import {queueInitHooks, queueLifecycleHooks} from './hooks';
import {CLEAN_PROMISE, ROOT_DIRECTIVE_INDICES, _getComponentHostLElementNode, baseDirectiveCreate, createLView, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getRootView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement, setHostBindings} from './instructions';
import {CLEAN_PROMISE, ROOT_DIRECTIVE_INDICES, _getComponentHostLElementNode, baseDirectiveCreate, createLViewData, createTView, detectChangesInternal, enterView, executeInitAndContentHooks, getRootView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement, setHostBindings,} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition';
import {LElementNode, TNodeFlags} from './interfaces/node';
import {LElementNode} from './interfaces/node';
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {LView, LViewFlags, RootContext} from './interfaces/view';
import {LViewData, LViewFlags, RootContext, INJECTOR, CONTEXT, TVIEW} from './interfaces/view';
import {stringify} from './util';
import {ViewRef} from './view_ref';



/** Options that control how the component should be bootstrapped. */
Expand Down Expand Up @@ -71,7 +68,6 @@ export interface CreateComponentOptions {
scheduler?: (work: () => void) => void;
}


// TODO: A hack to not pull in the NullInjector from @angular/core.
export const NULL_INJECTOR: Injector = {
get: (token: any, notFoundValue?: any) => {
Expand Down Expand Up @@ -108,11 +104,11 @@ export function renderComponent<T>(
const hostNode = locateHostElement(rendererFactory, opts.host || componentTag);
const rootContext = createRootContext(opts.scheduler || requestAnimationFrame.bind(window));

const rootView: LView = createLView(
const rootView: LViewData = createLViewData(
rendererFactory.createRenderer(hostNode, componentDef.rendererType),
createTView(-1, null, null, null), rootContext,
componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
rootView.injector = opts.injector || null;
rootView[INJECTOR] = opts.injector || null;

const oldView = enterView(rootView, null !);
let elementNode: LElementNode;
Expand All @@ -131,7 +127,7 @@ export function renderComponent<T>(

executeInitAndContentHooks();
setHostBindings(ROOT_DIRECTIVE_INDICES);
detectChangesInternal(elementNode.data as LView, elementNode, component);
detectChangesInternal(elementNode.data as LViewData, elementNode, component);
} finally {
leaveView(oldView);
if (rendererFactory.end) rendererFactory.end();
Expand Down Expand Up @@ -165,8 +161,9 @@ export function LifecycleHooksFeature(component: any, def: ComponentDef<any>): v
const elementNode = _getComponentHostLElementNode(component);

// Root component is always created at dir index 0
queueInitHooks(0, def.onInit, def.doCheck, elementNode.view.tView);
queueLifecycleHooks(elementNode.tNode.flags, elementNode.view);
const tView = elementNode.view[TVIEW];
queueInitHooks(0, def.onInit, def.doCheck, tView);
queueLifecycleHooks(elementNode.tNode.flags, tView);
}

/**
Expand All @@ -176,7 +173,7 @@ export function LifecycleHooksFeature(component: any, def: ComponentDef<any>): v
* @param component any component
*/
function getRootContext(component: any): RootContext {
const rootContext = getRootView(component).context as RootContext;
const rootContext = getRootView(component)[CONTEXT] as RootContext;
ngDevMode && assertDefined(rootContext, 'rootContext');
return rootContext;
}
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/render3/component_ref.ts
Expand Up @@ -18,11 +18,11 @@ import {Type} from '../type';

import {assertComponentType, assertDefined} from './assert';
import {createRootContext} from './component';
import {baseDirectiveCreate, createLView, createTView, enterView, hostElement, initChangeDetectorIfExisting, leaveView, locateHostElement} from './instructions';
import {baseDirectiveCreate, createLViewData, createTView, enterView, hostElement, initChangeDetectorIfExisting, locateHostElement} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition';
import {LElementNode} from './interfaces/node';
import {RElement} from './interfaces/renderer';
import {LView, LViewFlags, RootContext} from './interfaces/view';
import {INJECTOR, LViewData, LViewFlags, RootContext} from './interfaces/view';
import {ViewRef} from './view_ref';

export class ComponentFactoryResolver extends viewEngine_ComponentFactoryResolver {
Expand Down Expand Up @@ -94,11 +94,11 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
const rootContext: RootContext = ngModule !.injector.get(ROOT_CONTEXT);

// Create the root view. Uses empty TView and ContentTemplate.
const rootView: LView = createLView(
const rootView: LViewData = createLViewData(
rendererFactory.createRenderer(hostNode, this.componentDef.rendererType),
createTView(-1, null, null, null), null,
this.componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
rootView.injector = ngModule && ngModule.injector || null;
rootView[INJECTOR] = ngModule && ngModule.injector || null;

// rootView is the parent when bootstrapping
const oldView = enterView(rootView, null !);
Expand Down Expand Up @@ -145,7 +145,7 @@ export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
componentType: Type<T>;

constructor(
componentType: Type<T>, instance: T, rootView: LView, injector: Injector,
componentType: Type<T>, instance: T, rootView: LViewData, injector: Injector,
hostNode: RElement) {
super();
this.instance = instance;
Expand Down Expand Up @@ -173,4 +173,4 @@ export class ComponentRef<T> extends viewEngine_ComponentRef<T> {
ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
this.destroyCbs !.push(callback);
}
}
}
42 changes: 22 additions & 20 deletions packages/core/src/render3/di.ts
Expand Up @@ -19,13 +19,14 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_Vie
import {Type} from '../type';

import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
import {addToViewTree, assertPreviousIsParent, createLContainer, createLNodeObject, createTNode, createTView, getDirectiveInstance, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {ComponentTemplate, DirectiveDef, DirectiveDefList, PipeDefList} from './interfaces/definition';
import {addToViewTree, assertPreviousIsParent, createLContainer, createLNodeObject, createTNode, getDirectiveInstance, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {VIEWS} from './interfaces/container';
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
import {LInjector} from './interfaces/injector';
import {AttributeMarker, LContainerNode, LElementNode, LNode, LViewNode, TNodeFlags, TNodeType} from './interfaces/node';
import {LQueries, QueryReadType} from './interfaces/query';
import {Renderer3} from './interfaces/renderer';
import {LView, TView} from './interfaces/view';
import {DIRECTIVES, HOST_NODE, INJECTOR, LViewData, QUERIES, TVIEW, TView} from './interfaces/view';
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
import {detachView, getParentLNode, insertView, removeView} from './node_manipulation';
import {notImplemented, stringify} from './util';
Expand Down Expand Up @@ -282,9 +283,9 @@ export function getOrCreateChangeDetectorRef(

const currentNode = di.node;
if (isComponent(currentNode.tNode)) {
return di.changeDetectorRef = new ViewRef(currentNode.data as LView, context);
return di.changeDetectorRef = new ViewRef(currentNode.data as LViewData, context);
} else if (currentNode.tNode.type === TNodeType.Element) {
return di.changeDetectorRef = getOrCreateHostChangeDetector(currentNode.view.node);
return di.changeDetectorRef = getOrCreateHostChangeDetector(currentNode.view[HOST_NODE]);
}
return null !;
}
Expand All @@ -299,9 +300,9 @@ function getOrCreateHostChangeDetector(currentNode: LViewNode | LElementNode):
return existingRef ?
existingRef :
new ViewRef(
hostNode.data as LView,
hostNode.view
.directives ![hostNode.tNode.flags >> TNodeFlags.DirectiveStartingIndexShift]);
hostNode.data as LViewData,
hostNode
.view[DIRECTIVES] ![hostNode.tNode.flags >> TNodeFlags.DirectiveStartingIndexShift]);
}

/**
Expand All @@ -311,7 +312,7 @@ function getOrCreateHostChangeDetector(currentNode: LViewNode | LElementNode):
*/
function getClosestComponentAncestor(node: LViewNode | LElementNode): LElementNode {
while (node.tNode.type === TNodeType.View) {
node = node.view.node;
node = node.view[HOST_NODE];
}
return node as LElementNode;
}
Expand Down Expand Up @@ -340,7 +341,7 @@ export function getOrCreateInjectable<T>(
// If the token has a bloom hash, then it is a directive that is public to the injection system
// (diPublic). If there is no hash, fall back to the module injector.
if (bloomHash === null) {
const moduleInjector = getPreviousOrParentNode().view.injector;
const moduleInjector = getPreviousOrParentNode().view[INJECTOR];
const formerInjector = setCurrentInjector(moduleInjector);
try {
return inject(token, flags);
Expand Down Expand Up @@ -370,14 +371,14 @@ export function getOrCreateInjectable<T>(
if (count !== 0) {
const start = nodeFlags >> TNodeFlags.DirectiveStartingIndexShift;
const end = start + count;
const defs = node.view.tView.directives !;
const defs = node.view[TVIEW].directives !;

for (let i = start; i < end; i++) {
// Get the definition for the directive at this index and, if it is injectable (diPublic),
// and matches the given token, return the directive instance.
const directiveDef = defs[i] as DirectiveDef<any>;
if (directiveDef.type === token && directiveDef.diPublic) {
return getDirectiveInstance(node.view.directives ![i]);
return getDirectiveInstance(node.view[DIRECTIVES] ![i]);
}
}
}
Expand Down Expand Up @@ -405,12 +406,12 @@ export function getOrCreateInjectable<T>(
}

function searchMatchesQueuedForCreation<T>(node: LNode, token: any): T|null {
const matches = node.view.tView.currentMatches;
const matches = node.view[TVIEW].currentMatches;
if (matches) {
for (let i = 0; i < matches.length; i += 2) {
const def = matches[i] as DirectiveDef<any>;
if (def.type === token) {
return resolveDirective(def, i + 1, matches, node.view.tView);
return resolveDirective(def, i + 1, matches, node.view[TVIEW]);
}
}
}
Expand Down Expand Up @@ -545,7 +546,7 @@ export const QUERY_READ_FROM_NODE =
(new ReadFromInjectorFn<any>((injector: LInjector, node: LNode, directiveIdx: number) => {
ngDevMode && assertNodeOfPossibleTypes(node, TNodeType.Container, TNodeType.Element);
if (directiveIdx > -1) {
return node.view.directives ![directiveIdx];
return node.view[DIRECTIVES] ![directiveIdx];
} else if (node.tNode.type === TNodeType.Element) {
return getOrCreateElementRef(injector);
} else if (node.tNode.type === TNodeType.Container) {
Expand Down Expand Up @@ -611,7 +612,7 @@ class ViewContainerRef implements viewEngine_ViewContainerRef {

clear(): void {
const lContainer = this._lContainerNode.data;
while (lContainer.views.length) {
while (lContainer[VIEWS].length) {
this.remove(0);
}
}
Expand All @@ -620,7 +621,7 @@ class ViewContainerRef implements viewEngine_ViewContainerRef {

get length(): number {
const lContainer = this._lContainerNode.data;
return lContainer.views.length;
return lContainer[VIEWS].length;
}

createEmbeddedView<C>(templateRef: viewEngine_TemplateRef<C>, context?: C, index?: number):
Expand Down Expand Up @@ -679,12 +680,12 @@ class ViewContainerRef implements viewEngine_ViewContainerRef {

private _adjustIndex(index?: number, shift: number = 0) {
if (index == null) {
return this._lContainerNode.data.views.length + shift;
return this._lContainerNode.data[VIEWS].length + shift;
}
if (ngDevMode) {
assertGreaterThan(index, -1, 'index must be positive');
// +1 because it's legal to insert at the end.
assertLessThan(index, this._lContainerNode.data.views.length + 1 + shift, 'index');
assertLessThan(index, this._lContainerNode.data[VIEWS].length + 1 + shift, 'index');
}
return index;
}
Expand All @@ -704,7 +705,8 @@ export function getOrCreateTemplateRef<T>(di: LInjector): viewEngine_TemplateRef
const hostTNode = hostNode.tNode;
ngDevMode && assertDefined(hostTNode.tViews, 'TView must be allocated');
di.templateRef = new TemplateRef<any>(
getOrCreateElementRef(di), hostTNode.tViews as TView, getRenderer(), hostNode.data.queries);
getOrCreateElementRef(di), hostTNode.tViews as TView, getRenderer(),
hostNode.data[QUERIES]);
}
return di.templateRef;
}
Expand Down
18 changes: 9 additions & 9 deletions packages/core/src/render3/hooks.ts
Expand Up @@ -9,7 +9,7 @@
import {assertEqual} from './assert';
import {DirectiveDef} from './interfaces/definition';
import {TNodeFlags} from './interfaces/node';
import {HookData, LView, LViewFlags, TView} from './interfaces/view';
import {DIRECTIVES, FLAGS, HookData, LViewData, LViewFlags, TView} from './interfaces/view';


/**
Expand All @@ -20,7 +20,7 @@ import {HookData, LView, LViewFlags, TView} from './interfaces/view';
* directive index), then saved in the even indices of the initHooks array. The odd indices
* hold the hook functions themselves.
*
* @param index The index of the directive in LView.data
* @param index The index of the directive in LViewData[DIRECTIVES]
* @param hooks The static hooks map on the directive def
* @param tView The current TView
*/
Expand All @@ -42,9 +42,8 @@ export function queueInitHooks(
* Loops through the directives on a node and queues all their hooks except ngOnInit
* and ngDoCheck, which are queued separately in directiveCreate.
*/
export function queueLifecycleHooks(flags: number, currentView: LView): void {
const tView = currentView.tView;
if (tView.firstTemplatePass === true) {
export function queueLifecycleHooks(flags: number, tView: TView): void {
if (tView.firstTemplatePass) {
const start = flags >> TNodeFlags.DirectiveStartingIndexShift;
const count = flags & TNodeFlags.DirectiveCountMask;
const end = start + count;
Expand Down Expand Up @@ -97,10 +96,11 @@ function queueDestroyHooks(def: DirectiveDef<any>, tView: TView, i: number): voi
*
* @param currentView The current view
*/
export function executeInitHooks(currentView: LView, tView: TView, creationMode: boolean): void {
if (currentView.flags & LViewFlags.RunInit) {
executeHooks(currentView.directives !, tView.initHooks, tView.checkHooks, creationMode);
currentView.flags &= ~LViewFlags.RunInit;
export function executeInitHooks(
currentView: LViewData, tView: TView, creationMode: boolean): void {
if (currentView[FLAGS] & LViewFlags.RunInit) {
executeHooks(currentView[DIRECTIVES] !, tView.initHooks, tView.checkHooks, creationMode);
currentView[FLAGS] &= ~LViewFlags.RunInit;
}
}

Expand Down