Skip to content

Commit b35ef18

Browse files
pkozlowski-opensourcematsko
authored andcommitted
refactor(ivy): remove firstTemplatePass as global state (angular#28450)
PR Close angular#28450
1 parent b1e099b commit b35ef18

File tree

6 files changed

+20
-61
lines changed

6 files changed

+20
-61
lines changed

packages/core/src/render3/instructions.ts

+18-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import {InjectFlags, InjectionToken, Injector} from '../di';
1010
import {resolveForwardRef} from '../di/forward_ref';
1111
import {Type} from '../interface/type';
12-
import {QueryList} from '../linker';
1312
import {validateAttribute, validateProperty} from '../sanitization/sanitization';
1413
import {Sanitizer} from '../sanitization/security';
1514
import {StyleSanitizeFn} from '../sanitization/style_sanitizer';
@@ -36,7 +35,7 @@ import {BINDING_INDEX, CLEANUP, CONTAINER_INDEX, CONTENT_QUERIES, CONTEXT, DECLA
3635
import {assertNodeOfPossibleTypes, assertNodeType} from './node_assert';
3736
import {appendChild, appendProjectedNode, createTextNode, getLViewChild, insertView, removeView} from './node_manipulation';
3837
import {isNodeMatchingSelectorList, matchingSelectorIndex} from './node_selector_matcher';
39-
import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getCurrentQueryIndex, getElementDepthCount, getFirstTemplatePass, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setFirstTemplatePass, setIsParent, setPreviousOrParentTNode} from './state';
38+
import {decreaseElementDepthCount, enterView, getBindingsEnabled, getCheckNoChangesMode, getContextLView, getCurrentDirectiveDef, getCurrentQueryIndex, getElementDepthCount, getIsParent, getLView, getPreviousOrParentTNode, increaseElementDepthCount, isCreationMode, leaveView, nextContextImpl, resetComponentState, setBindingRoot, setCheckNoChangesMode, setCurrentDirectiveDef, setCurrentQueryIndex, setIsParent, setPreviousOrParentTNode} from './state';
4039
import {getInitialClassNameValue, initializeStaticContext as initializeStaticStylingContext, patchContextWithStaticAttrs, renderInitialStylesAndClasses, renderStyling, updateClassProp as updateElementClassProp, updateContextWithBindings, updateStyleProp as updateElementStyleProp, updateStylingMap} from './styling/class_and_style_bindings';
4140
import {BoundPlayerFactory} from './styling/player_factory';
4241
import {createEmptyStylingContext, getStylingContext, hasClassInput, hasStyling, isAnimationProp} from './styling/util';
@@ -66,7 +65,6 @@ export function refreshDescendantViews(lView: LView) {
6665
const tView = lView[TVIEW];
6766
// This needs to be set before children are processed to support recursive components
6867
tView.firstTemplatePass = false;
69-
setFirstTemplatePass(false);
7068

7169
// Resetting the bindingIndex of the current LView as the next steps may trigger change detection.
7270
lView[BINDING_INDEX] = tView.bindingStartIndex;
@@ -380,7 +378,6 @@ export function renderEmbeddedTemplate<T>(viewToRender: LView, tView: TView, con
380378
// off firstTemplatePass. If we don't set it here, instances will perform directive
381379
// matching, etc again and again.
382380
viewToRender[TVIEW].firstTemplatePass = false;
383-
setFirstTemplatePass(false);
384381

385382
refreshDescendantViews(viewToRender);
386383
} finally {
@@ -654,7 +651,7 @@ function createDirectivesAndLocals(
654651
localRefExtractor: LocalRefExtractor = getNativeByTNode) {
655652
if (!getBindingsEnabled()) return;
656653
const previousOrParentTNode = getPreviousOrParentTNode();
657-
if (getFirstTemplatePass()) {
654+
if (tView.firstTemplatePass) {
658655
ngDevMode && ngDevMode.firstTemplatePass++;
659656

660657
resolveDirectives(
@@ -1654,7 +1651,7 @@ function resolveDirectives(
16541651
tView: TView, viewData: LView, directives: DirectiveDef<any>[] | null, tNode: TNode,
16551652
localRefs: string[] | null): void {
16561653
// Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in tsickle.
1657-
ngDevMode && assertEqual(getFirstTemplatePass(), true, 'should run on first template pass only');
1654+
ngDevMode && assertEqual(tView.firstTemplatePass, true, 'should run on first template pass only');
16581655
const exportsMap: ({[key: string]: number} | null) = localRefs ? {'': -1} : null;
16591656
if (directives) {
16601657
initNodeFlags(tNode, tView.data.length, directives.length);
@@ -1691,7 +1688,7 @@ function resolveDirectives(
16911688
function instantiateAllDirectives(tView: TView, lView: LView, tNode: TNode) {
16921689
const start = tNode.directiveStart;
16931690
const end = tNode.directiveEnd;
1694-
if (!getFirstTemplatePass() && start < end) {
1691+
if (!tView.firstTemplatePass && start < end) {
16951692
getOrCreateNodeInjectorForNode(
16961693
tNode as TElementNode | TContainerNode | TElementContainerNode, lView);
16971694
}
@@ -1709,7 +1706,7 @@ function invokeDirectivesHostBindings(tView: TView, viewData: LView, tNode: TNod
17091706
const start = tNode.directiveStart;
17101707
const end = tNode.directiveEnd;
17111708
const expando = tView.expandoInstructions !;
1712-
const firstTemplatePass = getFirstTemplatePass();
1709+
const firstTemplatePass = tView.firstTemplatePass;
17131710
for (let i = start; i < end; i++) {
17141711
const def = tView.data[i] as DirectiveDef<any>;
17151712
const directive = viewData[i];
@@ -1757,7 +1754,7 @@ export function generateExpandoInstructionBlock(
17571754
*/
17581755
function prefillHostVars(tView: TView, lView: LView, totalHostVars: number): void {
17591756
ngDevMode &&
1760-
assertEqual(getFirstTemplatePass(), true, 'Should only be called in first template pass.');
1757+
assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
17611758
for (let i = 0; i < totalHostVars; i++) {
17621759
lView.push(NO_CHANGE);
17631760
tView.blueprint.push(NO_CHANGE);
@@ -1813,7 +1810,7 @@ function postProcessBaseDirective<T>(
18131810
*/
18141811
function findDirectiveMatches(tView: TView, viewData: LView, tNode: TNode): DirectiveDef<any>[]|
18151812
null {
1816-
ngDevMode && assertEqual(getFirstTemplatePass(), true, 'should run on first template pass only');
1813+
ngDevMode && assertEqual(tView.firstTemplatePass, true, 'should run on first template pass only');
18171814
const registry = tView.directiveRegistry;
18181815
let matches: any[]|null = null;
18191816
if (registry) {
@@ -1844,9 +1841,9 @@ function findDirectiveMatches(tView: TView, viewData: LView, tNode: TNode): Dire
18441841

18451842
/** Stores index of component's host element so it will be queued for view refresh during CD. */
18461843
export function queueComponentIndexForCheck(previousOrParentTNode: TNode): void {
1847-
ngDevMode &&
1848-
assertEqual(getFirstTemplatePass(), true, 'Should only be called in first template pass.');
18491844
const tView = getLView()[TVIEW];
1845+
ngDevMode &&
1846+
assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
18501847
(tView.components || (tView.components = [])).push(previousOrParentTNode.index);
18511848
}
18521849

@@ -1857,7 +1854,7 @@ export function queueComponentIndexForCheck(previousOrParentTNode: TNode): void
18571854
function queueHostBindingForCheck(
18581855
tView: TView, def: DirectiveDef<any>| ComponentDef<any>, hostVars: number): void {
18591856
ngDevMode &&
1860-
assertEqual(getFirstTemplatePass(), true, 'Should only be called in first template pass.');
1857+
assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
18611858
const expando = tView.expandoInstructions !;
18621859
const length = expando.length;
18631860
// Check whether a given `hostBindings` function already exists in expandoInstructions,
@@ -1912,7 +1909,6 @@ function saveNameToExportMap(
19121909
* @param index the initial index
19131910
*/
19141911
export function initNodeFlags(tNode: TNode, index: number, numberOfDirectives: number) {
1915-
ngDevMode && assertEqual(getFirstTemplatePass(), true, 'expected firstTemplatePass to be true');
19161912
const flags = tNode.flags;
19171913
ngDevMode && assertEqual(
19181914
flags === 0 || flags === TNodeFlags.isComponent, true,
@@ -1961,7 +1957,7 @@ function addComponentLogic<T>(
19611957
componentView[HOST] = lView[previousOrParentTNode.index];
19621958
lView[previousOrParentTNode.index] = componentView;
19631959

1964-
if (getFirstTemplatePass()) {
1960+
if (lView[TVIEW].firstTemplatePass) {
19651961
queueComponentIndexForCheck(previousOrParentTNode);
19661962
}
19671963
}
@@ -2098,7 +2094,7 @@ export function template(
20982094
// TODO: consider a separate node type for templates
20992095
const tNode = containerInternal(index, tagName || null, attrs || null);
21002096

2101-
if (getFirstTemplatePass()) {
2097+
if (tView.firstTemplatePass) {
21022098
tNode.tViews = createTView(
21032099
-1, templateFn, consts, vars, tView.directiveRegistry, tView.pipeRegistry, null);
21042100
}
@@ -2126,7 +2122,10 @@ export function template(
21262122
*/
21272123
export function container(index: number): void {
21282124
const tNode = containerInternal(index, null, null);
2129-
getFirstTemplatePass() && (tNode.tViews = []);
2125+
const lView = getLView();
2126+
if (lView[TVIEW].firstTemplatePass) {
2127+
tNode.tViews = [];
2128+
}
21302129
setIsParent(false);
21312130
}
21322131

@@ -2550,10 +2549,9 @@ export function projection(nodeIndex: number, selectorIndex: number = 0, attrs?:
25502549
export function addToViewTree<T extends LView|LContainer>(
25512550
lView: LView, adjustedHostIndex: number, state: T): T {
25522551
const tView = lView[TVIEW];
2553-
const firstTemplatePass = getFirstTemplatePass();
25542552
if (lView[TAIL]) {
25552553
lView[TAIL] ![NEXT] = state;
2556-
} else if (firstTemplatePass) {
2554+
} else if (tView.firstTemplatePass) {
25572555
tView.childIndex = adjustedHostIndex;
25582556
}
25592557
lView[TAIL] = state;
@@ -2813,9 +2811,9 @@ export function bind<T>(value: T): T|NO_CHANGE {
28132811
* @param count Amount of vars to be allocated
28142812
*/
28152813
export function allocHostVars(count: number): void {
2816-
if (!getFirstTemplatePass()) return;
28172814
const lView = getLView();
28182815
const tView = lView[TVIEW];
2816+
if (!tView.firstTemplatePass) return;
28192817
queueHostBindingForCheck(tView, getCurrentDirectiveDef() !, count);
28202818
prefillHostVars(tView, lView, count);
28212819
}

packages/core/src/render3/query.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {unusedValueExportToPlacateAjd as unused2} from './interfaces/injector';
2424
import {TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeType, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
2525
import {LQueries, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
2626
import {CONTENT_QUERIES, HEADER_OFFSET, LView, TVIEW} from './interfaces/view';
27-
import {getCurrentQueryIndex, getFirstTemplatePass, getIsParent, getLView, getOrCreateCurrentQueries, setCurrentQueryIndex} from './state';
27+
import {getCurrentQueryIndex, getIsParent, getLView, getOrCreateCurrentQueries, setCurrentQueryIndex} from './state';
2828
import {isContentQueryHost} from './util';
2929
import {createElementRef, createTemplateRef} from './view_engine_compatibility';
3030

@@ -444,7 +444,7 @@ export function contentQuery<T>(
444444
const tView = lView[TVIEW];
445445
const contentQuery: QueryList<T> = query<T>(predicate, descend, read);
446446
(lView[CONTENT_QUERIES] || (lView[CONTENT_QUERIES] = [])).push(contentQuery);
447-
if (getFirstTemplatePass()) {
447+
if (tView.firstTemplatePass) {
448448
const tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
449449
const lastSavedDirectiveIndex =
450450
tView.contentQueries.length ? tView.contentQueries[tView.contentQueries.length - 1] : -1;

packages/core/src/render3/state.ts

-12
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,6 @@ export function setCheckNoChangesMode(mode: boolean): void {
229229
checkNoChangesMode = mode;
230230
}
231231

232-
/** Whether or not this is the first time the current view has been processed. */
233-
let firstTemplatePass = true;
234-
235-
export function getFirstTemplatePass(): boolean {
236-
return firstTemplatePass;
237-
}
238-
239-
export function setFirstTemplatePass(value: boolean): void {
240-
firstTemplatePass = value;
241-
}
242-
243232
/**
244233
* The root index from which pure function instructions should calculate their binding
245234
* indices. In component views, this is TView.bindingStartIndex. In a host binding
@@ -287,7 +276,6 @@ export function enterView(newView: LView, hostTNode: TElementNode | TViewNode |
287276
const oldView = lView;
288277
if (newView) {
289278
const tView = newView[TVIEW];
290-
firstTemplatePass = tView.firstTemplatePass;
291279
bindingRootIndex = tView.bindingStartIndex;
292280
}
293281

packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json

-9
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,6 @@
287287
{
288288
"name": "findDirectiveMatches"
289289
},
290-
{
291-
"name": "firstTemplatePass"
292-
},
293290
{
294291
"name": "generateExpandoInstructionBlock"
295292
},
@@ -326,9 +323,6 @@
326323
{
327324
"name": "getElementDepthCount"
328325
},
329-
{
330-
"name": "getFirstTemplatePass"
331-
},
332326
{
333327
"name": "getHighestElementOrICUContainer"
334328
},
@@ -593,9 +587,6 @@
593587
{
594588
"name": "setCurrentQueryIndex"
595589
},
596-
{
597-
"name": "setFirstTemplatePass"
598-
},
599590
{
600591
"name": "setHostBindings"
601592
},

packages/core/test/bundling/hello_world/bundle.golden_symbols.json

-9
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,6 @@
215215
{
216216
"name": "extractPipeDef"
217217
},
218-
{
219-
"name": "firstTemplatePass"
220-
},
221218
{
222219
"name": "generateExpandoInstructionBlock"
223220
},
@@ -242,9 +239,6 @@
242239
{
243240
"name": "getDirectiveDef"
244241
},
245-
{
246-
"name": "getFirstTemplatePass"
247-
},
248242
{
249243
"name": "getHighestElementOrICUContainer"
250244
},
@@ -422,9 +416,6 @@
422416
{
423417
"name": "setCurrentQueryIndex"
424418
},
425-
{
426-
"name": "setFirstTemplatePass"
427-
},
428419
{
429420
"name": "setHostBindings"
430421
},

packages/core/test/bundling/todo/bundle.golden_symbols.json

-9
Original file line numberDiff line numberDiff line change
@@ -593,9 +593,6 @@
593593
{
594594
"name": "findViaComponent"
595595
},
596-
{
597-
"name": "firstTemplatePass"
598-
},
599596
{
600597
"name": "forwardRef"
601598
},
@@ -656,9 +653,6 @@
656653
{
657654
"name": "getElementDepthCount"
658655
},
659-
{
660-
"name": "getFirstTemplatePass"
661-
},
662656
{
663657
"name": "getHighestElementOrICUContainer"
664658
},
@@ -1142,9 +1136,6 @@
11421136
{
11431137
"name": "setDirty"
11441138
},
1145-
{
1146-
"name": "setFirstTemplatePass"
1147-
},
11481139
{
11491140
"name": "setFlag"
11501141
},

0 commit comments

Comments
 (0)