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(core): unify setPreviousOrParentTNode and setIsParent into single setPreviousOrParentTNode #30453

Closed
wants to merge 9 commits into from
5 changes: 3 additions & 2 deletions packages/core/src/render3/assert.ts
Expand Up @@ -36,8 +36,9 @@ export function assertPreviousIsParent(isParent: boolean) {
assertEqual(isParent, true, 'previousOrParentTNode should be a parent');
}

export function assertHasParent(tNode: TNode) {
assertDefined(tNode.parent, 'previousOrParentTNode should have a parent');
export function assertHasParent(tNode: TNode | null) {
assertDefined(tNode, 'previousOrParentTNode should exist!');
assertDefined(tNode !.parent, 'previousOrParentTNode should have a parent');
}

export function assertDataNext(lView: LView, index: number, arr?: any[]) {
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/render3/component.ts
Expand Up @@ -11,12 +11,13 @@
import {Type} from '../core';
import {Injector} from '../di/injector';
import {Sanitizer} from '../sanitization/security';
import {assertDataInRange, assertEqual} from '../util/assert';

import {assertComponentType} from './assert';
import {getComponentDef} from './definition';
import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di';
import {registerPostOrderHooks, registerPreOrderHooks} from './hooks';
import {CLEAN_PROMISE, addToViewTree, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions/shared';
import {CLEAN_PROMISE, addToViewTree, createLView, createTView, getOrCreateTNode, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions/shared';
import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition';
import {TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node';
import {PlayerHandler} from './interfaces/player';
Expand Down Expand Up @@ -172,7 +173,9 @@ export function createRootComponentView(
rendererFactory: RendererFactory3, renderer: Renderer3, sanitizer?: Sanitizer | null): LView {
resetComponentState();
const tView = rootView[TVIEW];
const tNode: TElementNode = createNodeAtIndex(0, TNodeType.Element, rNode, null, null);
ngDevMode && assertDataInRange(rootView, 0 + HEADER_OFFSET);
rootView[0 + HEADER_OFFSET] = rNode;
const tNode: TElementNode = getOrCreateTNode(tView, null, 0, TNodeType.Element, null, null);
const componentView = createLView(
rootView, getOrCreateTView(def), null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways,
rootView[HEADER_OFFSET], tNode, rendererFactory, renderer, sanitizer);
Expand Down
33 changes: 16 additions & 17 deletions packages/core/src/render3/i18n.ts
Expand Up @@ -12,12 +12,12 @@ import {SRCSET_ATTRS, URI_ATTRS, VALID_ATTRS, VALID_ELEMENTS, getTemplateContent
import {InertBodyHelper} from '../sanitization/inert_body';
import {_sanitizeUrl, sanitizeSrcset} from '../sanitization/url_sanitizer';
import {addAllToArray} from '../util/array_utils';
import {assertDefined, assertEqual, assertGreaterThan} from '../util/assert';
import {assertDataInRange, assertDefined, assertEqual, assertGreaterThan} from '../util/assert';

import {attachPatchData} from './context_discovery';
import {attachI18nOpCodesDebug} from './debug';
import {ɵɵelementAttribute, ɵɵload, ɵɵtextBinding} from './instructions/all';
import {allocExpando, createNodeAtIndex} from './instructions/shared';
import {allocExpando, getOrCreateTNode} from './instructions/shared';
import {LContainer, NATIVE} from './interfaces/container';
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nMutateOpCodes, I18nUpdateOpCode, I18nUpdateOpCodes, IcuType, TI18n, TIcu} from './interfaces/i18n';
import {TElementNode, TIcuContainerNode, TNode, TNodeType} from './interfaces/node';
Expand All @@ -26,7 +26,7 @@ import {SanitizerFn} from './interfaces/sanitization';
import {StylingContext} from './interfaces/styling';
import {BINDING_INDEX, HEADER_OFFSET, LView, RENDERER, TVIEW, TView, T_HOST} from './interfaces/view';
import {appendChild, createTextNode, nativeRemoveNode} from './node_manipulation';
import {getIsParent, getLView, getPreviousOrParentTNode, setIsParent, setPreviousOrParentTNode} from './state';
import {getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from './state';
import {NO_CHANGE} from './tokens';
import {renderStringify} from './util/misc_utils';
import {getNativeByIndex, getNativeByTNode, getTNode, isLContainer} from './util/view_utils';
Expand Down Expand Up @@ -671,10 +671,12 @@ function i18nEndFirstPass(tView: TView) {
* Creates and stores the dynamic TNode, and unhooks it from the tree for now.
*/
function createDynamicNodeAtIndex(
index: number, type: TNodeType, native: RElement | RText | null,
lView: LView, index: number, type: TNodeType, native: RElement | RText | null,
name: string | null): TElementNode|TIcuContainerNode {
const previousOrParentTNode = getPreviousOrParentTNode();
const tNode = createNodeAtIndex(index, type as any, native, name, null);
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
lView[index + HEADER_OFFSET] = native;
const tNode = getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, type as any, name, null);

// We are creating a dynamic node, the previous tNode might not be pointing at this node.
// We will link ourselves into the tree later with `appendI18nNode`.
Expand All @@ -699,9 +701,10 @@ function readCreateOpCodes(
const textNodeIndex = createOpCodes[++i] as number;
ngDevMode && ngDevMode.rendererCreateTextNode++;
previousTNode = currentTNode;
currentTNode = createDynamicNodeAtIndex(textNodeIndex, TNodeType.Element, textRNode, null);
currentTNode =
createDynamicNodeAtIndex(viewData, textNodeIndex, TNodeType.Element, textRNode, null);
visitedNodes.push(textNodeIndex);
setIsParent(false);
setIsNotParent();
} else if (typeof opCode == 'number') {
switch (opCode & I18nMutateOpCode.MASK_OPCODE) {
case I18nMutateOpCode.AppendChild:
Expand All @@ -726,17 +729,13 @@ function readCreateOpCodes(
previousTNode = currentTNode;
currentTNode = getTNode(nodeIndex, viewData);
if (currentTNode) {
setPreviousOrParentTNode(currentTNode);
if (currentTNode.type === TNodeType.Element) {
setIsParent(true);
}
setPreviousOrParentTNode(currentTNode, currentTNode.type === TNodeType.Element);
}
break;
case I18nMutateOpCode.ElementEnd:
const elementIndex = opCode >>> I18nMutateOpCode.SHIFT_REF;
previousTNode = currentTNode = getTNode(elementIndex, viewData);
setPreviousOrParentTNode(currentTNode);
setIsParent(false);
setPreviousOrParentTNode(currentTNode, false);
break;
case I18nMutateOpCode.Attr:
const elementNodeIndex = opCode >>> I18nMutateOpCode.SHIFT_REF;
Expand All @@ -759,12 +758,12 @@ function readCreateOpCodes(
ngDevMode && ngDevMode.rendererCreateComment++;
previousTNode = currentTNode;
currentTNode = createDynamicNodeAtIndex(
commentNodeIndex, TNodeType.IcuContainer, commentRNode, null);
viewData, commentNodeIndex, TNodeType.IcuContainer, commentRNode, null);
visitedNodes.push(commentNodeIndex);
attachPatchData(commentRNode, viewData);
(currentTNode as TIcuContainerNode).activeCaseIndex = null;
// We will add the case nodes later, during the update phase
setIsParent(false);
setIsNotParent();
break;
case ELEMENT_MARKER:
const tagNameValue = createOpCodes[++i] as string;
Expand All @@ -776,7 +775,7 @@ function readCreateOpCodes(
ngDevMode && ngDevMode.rendererCreateElement++;
previousTNode = currentTNode;
currentTNode = createDynamicNodeAtIndex(
elementNodeIndex, TNodeType.Element, elementRNode, tagNameValue);
viewData, elementNodeIndex, TNodeType.Element, elementRNode, tagNameValue);
visitedNodes.push(elementNodeIndex);
break;
default:
Expand All @@ -785,7 +784,7 @@ function readCreateOpCodes(
}
}

setIsParent(false);
setIsNotParent();

return visitedNodes;
}
Expand Down
29 changes: 16 additions & 13 deletions packages/core/src/render3/instructions/container.ts
Expand Up @@ -5,19 +5,21 @@
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {assertEqual} from '../../util/assert';
import {assertDataInRange, assertEqual} from '../../util/assert';
import {assertHasParent} from '../assert';
import {attachPatchData} from '../context_discovery';
import {executePreOrderHooks, registerPostOrderHooks} from '../hooks';
import {ACTIVE_INDEX, CONTAINER_HEADER_OFFSET, LContainer} from '../interfaces/container';
import {ComponentTemplate} from '../interfaces/definition';
import {LocalRefExtractor, TAttributes, TContainerNode, TNode, TNodeType} from '../interfaces/node';
import {BINDING_INDEX, HEADER_OFFSET, LView, QUERIES, RENDERER, TVIEW} from '../interfaces/view';
import {BINDING_INDEX, HEADER_OFFSET, LView, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view';
import {assertNodeType} from '../node_assert';
import {appendChild, removeView} from '../node_manipulation';
import {getCheckNoChangesMode, getIsParent, getLView, getPreviousOrParentTNode, setIsParent, setPreviousOrParentTNode} from '../state';
import {getCheckNoChangesMode, getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state';
import {getNativeByTNode, loadInternal} from '../util/view_utils';
import {addToViewTree, createDirectivesAndLocals, createLContainer, createNodeAtIndex, createTView} from './shared';

import {addToViewTree, createDirectivesAndLocals, createLContainer, createTView, getOrCreateTNode} from './shared';


/**
* Creates an LContainer for inline views, e.g.
Expand All @@ -37,7 +39,7 @@ export function ɵɵcontainer(index: number): void {
tNode.tViews = [];
}
addTContainerToQueries(lView, tNode);
setIsParent(false);
setIsNotParent();
}

/**
Expand Down Expand Up @@ -77,7 +79,7 @@ export function ɵɵtemplate(
addTContainerToQueries(lView, tContainerNode);
attachPatchData(getNativeByTNode(tContainerNode, lView), lView);
registerPostOrderHooks(tView, tContainerNode);
setIsParent(false);
setIsNotParent();
}

/**
Expand All @@ -91,10 +93,8 @@ export function ɵɵcontainerRefreshStart(index: number): void {
const lView = getLView();
const tView = lView[TVIEW];
let previousOrParentTNode = loadInternal(tView.data, index) as TNode;
setPreviousOrParentTNode(previousOrParentTNode);

ngDevMode && assertNodeType(previousOrParentTNode, TNodeType.Container);
setIsParent(true);
setPreviousOrParentTNode(previousOrParentTNode, true);

lView[index + HEADER_OFFSET][ACTIVE_INDEX] = 0;

Expand All @@ -113,12 +113,12 @@ export function ɵɵcontainerRefreshStart(index: number): void {
export function ɵɵcontainerRefreshEnd(): void {
let previousOrParentTNode = getPreviousOrParentTNode();
if (getIsParent()) {
setIsParent(false);
setIsNotParent();
} else {
ngDevMode && assertNodeType(previousOrParentTNode, TNodeType.View);
ngDevMode && assertHasParent(previousOrParentTNode);
previousOrParentTNode = previousOrParentTNode.parent !;
setPreviousOrParentTNode(previousOrParentTNode);
setPreviousOrParentTNode(previousOrParentTNode, false);
}

ngDevMode && assertNodeType(previousOrParentTNode, TNodeType.Container);
Expand Down Expand Up @@ -166,9 +166,12 @@ function containerInternal(
'container nodes should be created before any bindings');

const adjustedIndex = index + HEADER_OFFSET;
const comment = lView[RENDERER].createComment(ngDevMode ? 'container' : '');
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
ngDevMode && ngDevMode.rendererCreateComment++;
const tNode = createNodeAtIndex(index, TNodeType.Container, comment, tagName, attrs);
const comment = lView[index + HEADER_OFFSET] =
lView[RENDERER].createComment(ngDevMode ? 'container' : '');
const tNode =
getOrCreateTNode(lView[TVIEW], lView[T_HOST], index, TNodeType.Container, tagName, attrs);
const lContainer = lView[adjustedIndex] =
createLContainer(lView[adjustedIndex], lView, comment, tNode);

Expand Down
32 changes: 17 additions & 15 deletions packages/core/src/render3/instructions/element.ts
Expand Up @@ -6,19 +6,19 @@
* found in the LICENSE file at https://angular.io/license
*/
import {validateAgainstEventAttributes} from '../../sanitization/sanitization';
import {assertDataInRange, assertEqual} from '../../util/assert';
import {assertDataInRange, assertDefined, assertEqual} from '../../util/assert';
import {assertHasParent} from '../assert';
import {attachPatchData} from '../context_discovery';
import {registerPostOrderHooks} from '../hooks';
import {TAttributes, TNodeFlags, TNodeType} from '../interfaces/node';
import {RElement, isProceduralRenderer} from '../interfaces/renderer';
import {SanitizerFn} from '../interfaces/sanitization';
import {StylingContext} from '../interfaces/styling';
import {BINDING_INDEX, QUERIES, RENDERER, TVIEW} from '../interfaces/view';
import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view';
import {assertNodeType} from '../node_assert';
import {appendChild} from '../node_manipulation';
import {applyOnCreateInstructions} from '../node_util';
import {decreaseElementDepthCount, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, getSelectedIndex, increaseElementDepthCount, setIsParent, setPreviousOrParentTNode} from '../state';
import {decreaseElementDepthCount, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, getSelectedIndex, increaseElementDepthCount, setIsNotParent, setPreviousOrParentTNode} from '../state';
import {getInitialClassNameValue, getInitialStyleStringValue, initializeStaticContext, patchContextWithStaticAttrs, renderInitialClasses, renderInitialStyles} from '../styling/class_and_style_bindings';
import {getStylingContextFromLView, hasClassInput, hasStyleInput} from '../styling/util';
import {registerInitialStylingIntoContext} from '../styling_next/instructions';
Expand All @@ -27,10 +27,12 @@ import {NO_CHANGE} from '../tokens';
import {attrsStylingIndexOf, setUpAttributes} from '../util/attrs_utils';
import {renderStringify} from '../util/misc_utils';
import {getNativeByIndex, getNativeByTNode, getTNode} from '../util/view_utils';
import {createDirectivesAndLocals, createNodeAtIndex, elementCreate, executeContentQueries, initializeTNodeInputs, setInputsForProperty, setNodeStylingTemplate} from './shared';

import {createDirectivesAndLocals, elementCreate, executeContentQueries, getOrCreateTNode, initializeTNodeInputs, setInputsForProperty, setNodeStylingTemplate} from './shared';
import {getActiveDirectiveStylingIndex} from './styling';



/**
* Create DOM element. The instruction must later be followed by `elementEnd()` call.
*
Expand All @@ -55,13 +57,11 @@ export function ɵɵelementStart(
'elements should be created before any bindings ');

ngDevMode && ngDevMode.rendererCreateElement++;

const native = elementCreate(name);
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
const native = lView[index + HEADER_OFFSET] = elementCreate(name);
const renderer = lView[RENDERER];

ngDevMode && assertDataInRange(lView, index - 1);

const tNode = createNodeAtIndex(index, TNodeType.Element, native !, name, attrs || null);
const tNode =
getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.Element, name, attrs || null);
let initialStylesIndex = 0;
let initialClassesIndex = 0;

Expand All @@ -78,12 +78,13 @@ export function ɵɵelementStart(
// instantiated into a context per element)
setNodeStylingTemplate(tView, tNode, attrs, lastAttrIndex);

if (tNode.stylingTemplate) {
const stylingTemplate = tNode.stylingTemplate;
if (stylingTemplate) {
// the initial style/class values are rendered immediately after having been
// initialized into the context so the element styling is ready when directives
// are initialized (since they may read style/class values in their constructor)
initialStylesIndex = renderInitialStyles(native, tNode.stylingTemplate, renderer);
initialClassesIndex = renderInitialClasses(native, tNode.stylingTemplate, renderer);
initialStylesIndex = renderInitialStyles(native, stylingTemplate, renderer);
initialClassesIndex = renderInitialClasses(native, stylingTemplate, renderer);
}
}

Expand Down Expand Up @@ -138,12 +139,13 @@ export function ɵɵelementStart(
*/
export function ɵɵelementEnd(): void {
let previousOrParentTNode = getPreviousOrParentTNode();
ngDevMode && assertDefined(previousOrParentTNode, 'No parent node to close.');
if (getIsParent()) {
setIsParent(false);
setIsNotParent();
} else {
ngDevMode && assertHasParent(getPreviousOrParentTNode());
previousOrParentTNode = previousOrParentTNode.parent !;
setPreviousOrParentTNode(previousOrParentTNode);
setPreviousOrParentTNode(previousOrParentTNode, false);
}

// this is required for all host-level styling-related instructions to run
Expand Down
19 changes: 11 additions & 8 deletions packages/core/src/render3/instructions/element_container.ts
Expand Up @@ -10,12 +10,14 @@ import {assertHasParent} from '../assert';
import {attachPatchData} from '../context_discovery';
import {registerPostOrderHooks} from '../hooks';
import {TAttributes, TNodeType} from '../interfaces/node';
import {BINDING_INDEX, QUERIES, RENDERER, TVIEW} from '../interfaces/view';
import {BINDING_INDEX, HEADER_OFFSET, QUERIES, RENDERER, TVIEW, T_HOST} from '../interfaces/view';
import {assertNodeType} from '../node_assert';
import {appendChild} from '../node_manipulation';
import {applyOnCreateInstructions} from '../node_util';
import {getIsParent, getLView, getPreviousOrParentTNode, setIsParent, setPreviousOrParentTNode} from '../state';
import {createDirectivesAndLocals, createNodeAtIndex, executeContentQueries, setNodeStylingTemplate} from './shared';
import {getIsParent, getLView, getPreviousOrParentTNode, setIsNotParent, setPreviousOrParentTNode} from '../state';

import {createDirectivesAndLocals, executeContentQueries, getOrCreateTNode, setNodeStylingTemplate} from './shared';


/**
* Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
Expand All @@ -42,11 +44,12 @@ export function ɵɵelementContainerStart(
'element containers should be created before any bindings');

ngDevMode && ngDevMode.rendererCreateComment++;
const native = renderer.createComment(ngDevMode ? tagName : '');
ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET);
const native = lView[index + HEADER_OFFSET] = renderer.createComment(ngDevMode ? tagName : '');

ngDevMode && assertDataInRange(lView, index - 1);
const tNode =
createNodeAtIndex(index, TNodeType.ElementContainer, native, tagName, attrs || null);
const tNode = getOrCreateTNode(
tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, attrs || null);


if (attrs) {
Expand Down Expand Up @@ -77,11 +80,11 @@ export function ɵɵelementContainerEnd(): void {
const lView = getLView();
const tView = lView[TVIEW];
if (getIsParent()) {
setIsParent(false);
setIsNotParent();
} else {
ngDevMode && assertHasParent(previousOrParentTNode);
previousOrParentTNode = previousOrParentTNode.parent !;
setPreviousOrParentTNode(previousOrParentTNode);
setPreviousOrParentTNode(previousOrParentTNode, false);
}

ngDevMode && assertNodeType(previousOrParentTNode, TNodeType.ElementContainer);
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/render3/instructions/embedded_view.ts
Expand Up @@ -40,7 +40,7 @@ export function ɵɵembeddedViewStart(
let viewToRender = scanForView(lContainer, lContainer[ACTIVE_INDEX] !, viewBlockId);

if (viewToRender) {
setIsParent(true);
setIsParent();
enterView(viewToRender, viewToRender[TVIEW].node);
} else {
// When we create a new LView, we always reset the state of the instructions.
Expand Down Expand Up @@ -141,6 +141,5 @@ export function ɵɵembeddedViewEnd(): void {
const lContainer = lView[PARENT] as LContainer;
ngDevMode && assertLContainerOrUndefined(lContainer);
leaveView(lContainer[PARENT] !);
setPreviousOrParentTNode(viewHost !);
setIsParent(false);
setPreviousOrParentTNode(viewHost !, false);
}