refactor(ivy): Intruduce LFrame to store global instruction information (#33178)

`LFrame` stores information specifice to the current `LView` As the code
enters and leaves `LView`s we use `enterView()` and `leaveView()`
respectively to build a a stack of `LFrame`s. This allows us to easily
restore the previous `LView` instruction state.

PR Close #33178
This commit is contained in:
Miško Hevery
2019-10-14 13:59:17 -07:00
committed by Andrew Kushnir
parent 9ea3430a5b
commit 09a2bb839f
19 changed files with 327 additions and 259 deletions

View File

@ -10,7 +10,7 @@ import {isForwardRef, resolveForwardRef} from '../di/forward_ref';
import {InjectionToken} from '../di/injection_token';
import {Injector} from '../di/injector';
import {injectRootLimpMode, setInjectImplementation} from '../di/injector_compatibility';
import {getInjectableDef, getInjectorDef} from '../di/interface/defs';
import {getInjectorDef} from '../di/interface/defs';
import {InjectFlags} from '../di/interface/injector';
import {Type} from '../interface/type';
import {assertDefined, assertEqual} from '../util/assert';
@ -19,11 +19,11 @@ import {getFactoryDef} from './definition';
import {NG_ELEMENT_ID, NG_FACTORY_DEF} from './fields';
import {DirectiveDef, FactoryFn} from './interfaces/definition';
import {NO_PARENT_INJECTOR, NodeInjectorFactory, PARENT_INJECTOR, RelativeInjectorLocation, RelativeInjectorLocationFlags, TNODE, isFactory} from './interfaces/injector';
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeFlags, TNodeProviderIndexes, TNodeType} from './interfaces/node';
import {AttributeMarker, TContainerNode, TElementContainerNode, TElementNode, TNode, TNodeProviderIndexes, TNodeType} from './interfaces/node';
import {isComponentDef, isComponentHost} from './interfaces/type_checks';
import {DECLARATION_VIEW, INJECTOR, LView, TData, TVIEW, TView, T_HOST} from './interfaces/view';
import {assertNodeOfPossibleTypes} from './node_assert';
import {getLView, getPreviousOrParentTNode, setTNodeAndViewData} from './state';
import {enterDI, leaveDI} from './state';
import {isNameOnlyAttributeMarker} from './util/attrs_utils';
import {getParentInjectorIndex, getParentInjectorView, hasParentInjector} from './util/injector_utils';
import {stringifyForError} from './util/misc_utils';
@ -334,9 +334,7 @@ export function getOrCreateInjectable<T>(
// If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
// so just call the factory function to create it.
if (typeof bloomHash === 'function') {
const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveLView = getLView();
setTNodeAndViewData(tNode, lView);
enterDI(lView, tNode);
try {
const value = bloomHash();
if (value == null && !(flags & InjectFlags.Optional)) {
@ -345,7 +343,7 @@ export function getOrCreateInjectable<T>(
return value;
}
} finally {
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
leaveDI();
}
} else if (typeof bloomHash == 'number') {
if (bloomHash === -1) {
@ -530,8 +528,8 @@ export function locateDirectiveOrProvider<T>(
* instantiates the `injectable` and caches the value.
*/
export function getNodeInjectable(
tData: TData, lData: LView, index: number, tNode: TElementNode): any {
let value = lData[index];
tData: TData, lView: LView, index: number, tNode: TElementNode): any {
let value = lView[index];
if (isFactory(value)) {
const factory: NodeInjectorFactory = value;
if (factory.resolving) {
@ -543,16 +541,14 @@ export function getNodeInjectable(
if (factory.injectImpl) {
previousInjectImplementation = setInjectImplementation(factory.injectImpl);
}
const savePreviousOrParentTNode = getPreviousOrParentTNode();
const saveLView = getLView();
setTNodeAndViewData(tNode, lData);
enterDI(lView, tNode);
try {
value = lData[index] = factory.factory(undefined, tData, lData, tNode);
value = lView[index] = factory.factory(undefined, tData, lView, tNode);
} finally {
if (factory.injectImpl) setInjectImplementation(previousInjectImplementation);
setIncludeViewProviders(previousIncludeViewProviders);
factory.resolving = false;
setTNodeAndViewData(savePreviousOrParentTNode, saveLView);
leaveDI();
}
}
return value;