refactor(ivy): move bindingStartIndex to TView (#24262)

PR Close #24262
This commit is contained in:
Kara Erickson 2018-06-01 18:14:05 -07:00 committed by Victor Berchet
parent 5db4f1a5ba
commit 44856bfc2f
2 changed files with 29 additions and 36 deletions

View File

@ -211,10 +211,6 @@ export function enterView(newView: LView, host: LElementNode | LViewNode | null)
cleanup = newView && newView.cleanup; cleanup = newView && newView.cleanup;
renderer = newView && newView.renderer; renderer = newView && newView.renderer;
if (newView && newView.bindingIndex < 0) {
newView.bindingIndex = newView.bindingStartIndex;
}
if (host != null) { if (host != null) {
previousOrParentNode = host; previousOrParentNode = host;
isParent = true; isParent = true;
@ -316,7 +312,6 @@ export function createLView<T>(
renderer: renderer, renderer: renderer,
tail: null, tail: null,
next: null, next: null,
bindingStartIndex: -1,
bindingIndex: -1, bindingIndex: -1,
template: template, template: template,
context: context, context: context,
@ -590,8 +585,7 @@ export function elementStart(
index: number, name: string, attrs?: TAttributes | null, index: number, name: string, attrs?: TAttributes | null,
localRefs?: string[] | null): RElement { localRefs?: string[] | null): RElement {
ngDevMode && ngDevMode &&
assertEqual( assertEqual(currentView.bindingIndex, -1, 'elements should be created before any bindings');
currentView.bindingStartIndex, -1, 'elements should be created before any bindings');
ngDevMode && ngDevMode.rendererCreateElement++; ngDevMode && ngDevMode.rendererCreateElement++;
const native: RElement = renderer.createElement(name); const native: RElement = renderer.createElement(name);
@ -802,6 +796,7 @@ export function createTView(
node: null !, node: null !,
data: [], data: [],
childIndex: -1, // Children set in addToViewTree(), if any childIndex: -1, // Children set in addToViewTree(), if any
bindingStartIndex: -1, // Set in initBindings()
directives: null, directives: null,
firstTemplatePass: true, firstTemplatePass: true,
initHooks: null, initHooks: null,
@ -1253,8 +1248,7 @@ export function elementStyle<T>(
*/ */
export function text(index: number, value?: any): void { export function text(index: number, value?: any): void {
ngDevMode && ngDevMode &&
assertEqual( assertEqual(currentView.bindingIndex, -1, 'text nodes should be created before bindings');
currentView.bindingStartIndex, -1, 'text nodes should be created before bindings');
ngDevMode && ngDevMode.rendererCreateTextNode++; ngDevMode && ngDevMode.rendererCreateTextNode++;
const textNode = createTextNode(value, renderer); const textNode = createTextNode(value, renderer);
const node = createLNode(index, TNodeType.Element, textNode, null, null); const node = createLNode(index, TNodeType.Element, textNode, null, null);
@ -1356,8 +1350,7 @@ function addComponentLogic<T>(index: number, instance: T, def: ComponentDef<T>):
export function baseDirectiveCreate<T>( export function baseDirectiveCreate<T>(
index: number, directive: T, directiveDef: DirectiveDef<T>| ComponentDef<T>): T { index: number, directive: T, directiveDef: DirectiveDef<T>| ComponentDef<T>): T {
ngDevMode && ngDevMode &&
assertEqual( assertEqual(currentView.bindingIndex, -1, 'directives should be created before any bindings');
currentView.bindingStartIndex, -1, 'directives should be created before any bindings');
ngDevMode && assertPreviousIsParent(); ngDevMode && assertPreviousIsParent();
Object.defineProperty( Object.defineProperty(
@ -1499,9 +1492,9 @@ export function createLContainer(
export function container( export function container(
index: number, template?: ComponentTemplate<any>, tagName?: string | null, attrs?: TAttributes, index: number, template?: ComponentTemplate<any>, tagName?: string | null, attrs?: TAttributes,
localRefs?: string[] | null): void { localRefs?: string[] | null): void {
ngDevMode && assertEqual( ngDevMode &&
currentView.bindingStartIndex, -1, assertEqual(
'container nodes should be created before any bindings'); currentView.bindingIndex, -1, 'container nodes should be created before any bindings');
const currentParent = isParent ? previousOrParentNode : getParentLNode(previousOrParentNode) !; const currentParent = isParent ? previousOrParentNode : getParentLNode(previousOrParentNode) !;
const lContainer = createLContainer(currentParent, currentView, template); const lContainer = createLContainer(currentParent, currentView, template);
@ -2149,13 +2142,13 @@ export const NO_CHANGE = {} as NO_CHANGE;
* (ie `bind()`, `interpolationX()`, `pureFunctionX()`) * (ie `bind()`, `interpolationX()`, `pureFunctionX()`)
*/ */
function initBindings() { function initBindings() {
ngDevMode && assertEqual(
currentView.bindingStartIndex, -1,
'Binding start index should only be set once, when null');
ngDevMode && assertEqual( ngDevMode && assertEqual(
currentView.bindingIndex, -1, currentView.bindingIndex, -1,
'Binding index should not yet be set ' + currentView.bindingIndex); 'Binding index should not yet be set ' + currentView.bindingIndex);
currentView.bindingIndex = currentView.bindingStartIndex = data.length; if (currentView.tView.bindingStartIndex === -1) {
currentView.tView.bindingStartIndex = data.length;
}
currentView.bindingIndex = currentView.tView.bindingStartIndex;
} }
/** /**
@ -2176,10 +2169,10 @@ export function bind<T>(value: T): T|NO_CHANGE {
* | LNodes ... | pure function bindings | regular bindings / interpolations | * | LNodes ... | pure function bindings | regular bindings / interpolations |
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* ^ * ^
* LView.bindingStartIndex * TView.bindingStartIndex
* *
* Pure function instructions are given an offset from LView.bindingStartIndex. * Pure function instructions are given an offset from TView.bindingStartIndex.
* Subtracting the offset from LView.bindingStartIndex gives the first index where the bindings * Subtracting the offset from TView.bindingStartIndex gives the first index where the bindings
* are stored. * are stored.
* *
* NOTE: reserveSlots instructions are only ever allowed at the very end of the creation block * NOTE: reserveSlots instructions are only ever allowed at the very end of the creation block
@ -2204,7 +2197,7 @@ export function reserveSlots(numSlots: number) {
*/ */
export function moveBindingIndexToReservedSlot(offset: number): number { export function moveBindingIndexToReservedSlot(offset: number): number {
const currentSlot = currentView.bindingIndex; const currentSlot = currentView.bindingIndex;
currentView.bindingIndex = currentView.bindingStartIndex - offset; currentView.bindingIndex = currentView.tView.bindingStartIndex - offset;
return currentSlot; return currentSlot;
} }
@ -2388,18 +2381,18 @@ export function consumeBinding(): any {
/** Updates binding if changed, then returns whether it was updated. */ /** Updates binding if changed, then returns whether it was updated. */
export function bindingUpdated(value: any): boolean { export function bindingUpdated(value: any): boolean {
ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.'); ngDevMode && assertNotEqual(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
if (currentView.bindingIndex === -1) initBindings();
if (currentView.bindingStartIndex < 0) { if (currentView.bindingIndex >= data.length) {
initBindings(); data[currentView.bindingIndex++] = value;
} else if (isDifferent(data[currentView.bindingIndex], value)) { } else if (isDifferent(data[currentView.bindingIndex], value)) {
throwErrorIfNoChangesMode( throwErrorIfNoChangesMode(
creationMode, checkNoChangesMode, data[currentView.bindingIndex], value); creationMode, checkNoChangesMode, data[currentView.bindingIndex], value);
data[currentView.bindingIndex++] = value;
} else { } else {
currentView.bindingIndex++; currentView.bindingIndex++;
return false; return false;
} }
data[currentView.bindingIndex++] = value;
return true; return true;
} }
@ -2457,7 +2450,7 @@ function assertDataNext(index: number, arr?: any[]) {
*/ */
export function assertReservedSlotInitialized(slotOffset: number, numSlots: number) { export function assertReservedSlotInitialized(slotOffset: number, numSlots: number) {
if (firstTemplatePass) { if (firstTemplatePass) {
const startIndex = currentView.bindingStartIndex - slotOffset; const startIndex = currentView.tView.bindingStartIndex - slotOffset;
for (let i = 0; i < numSlots; i++) { for (let i = 0; i < numSlots; i++) {
assertEqual( assertEqual(
data[startIndex + i], NO_CHANGE, data[startIndex + i], NO_CHANGE,

View File

@ -59,14 +59,6 @@ export interface LView {
/** Renderer to be used for this view. */ /** Renderer to be used for this view. */
readonly renderer: Renderer3; readonly renderer: Renderer3;
/**
* The binding start index is the index at which the nodes array
* starts to store bindings only. Saving this value ensures that we
* will begin reading bindings at the correct point in the array when
* we are in update mode.
*/
bindingStartIndex: number;
/** /**
* The binding index we should access next. * The binding index we should access next.
* *
@ -240,6 +232,14 @@ export interface TView {
/** Static data equivalent of LView.data[]. Contains TNodes. */ /** Static data equivalent of LView.data[]. Contains TNodes. */
data: TData; data: TData;
/**
* The binding start index is the index at which the data array
* starts to store bindings only. Saving this value ensures that we
* will begin reading bindings at the correct point in the array when
* we are in update mode.
*/
bindingStartIndex: number;
/** /**
* Index of the host node of the first LView or LContainer beneath this LView in * Index of the host node of the first LView or LContainer beneath this LView in
* the hierarchy. * the hierarchy.