Skip to content

Commit 5a724b3

Browse files
benleshjasonaden
authored andcommitted
refactor(ivy): move instructions (angular#29646)
- moves all publicly exported instructions to their own files - refactors namespace instructions to set state in `state.ts` - no longer exports * from `instructions.ts`. - `instructions.ts` renamed to `shared.ts` (old `shared.ts` contents folded in to `instructions.ts`) - updates `all.ts` to re-export from public instruction files. PR Close angular#29646
1 parent 03d914a commit 5a724b3

40 files changed

+3500
-3236
lines changed

packages/core/src/render3/component.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,23 @@
1111
import {Type} from '../core';
1212
import {Injector} from '../di/injector';
1313
import {Sanitizer} from '../sanitization/security';
14-
import {assertDefined} from '../util/assert';
1514

1615
import {assertComponentType} from './assert';
1716
import {getComponentDef} from './definition';
1817
import {diPublicInInjector, getOrCreateNodeInjectorForNode} from './di';
1918
import {registerPostOrderHooks, registerPreOrderHooks} from './hooks';
20-
import {CLEAN_PROMISE, addToViewTree, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions/all';
19+
import {CLEAN_PROMISE, addToViewTree, createLView, createNodeAtIndex, createTView, getOrCreateTView, initNodeFlags, instantiateRootComponent, invokeHostBindingsInCreationMode, locateHostElement, queueComponentIndexForCheck, refreshDescendantViews} from './instructions/shared';
2120
import {ComponentDef, ComponentType, RenderFlags} from './interfaces/definition';
2221
import {TElementNode, TNode, TNodeFlags, TNodeType} from './interfaces/node';
2322
import {PlayerHandler} from './interfaces/player';
2423
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
2524
import {CONTEXT, FLAGS, HEADER_OFFSET, HOST, LView, LViewFlags, RENDERER, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
2625
import {applyOnCreateInstructions} from './node_util';
27-
import {enterView, getPreviousOrParentTNode, leaveView, resetComponentState, setCurrentDirectiveDef} from './state';
26+
import {enterView, getPreviousOrParentTNode, leaveView, resetComponentState} from './state';
2827
import {renderInitialClasses, renderInitialStyles} from './styling/class_and_style_bindings';
2928
import {publishDefaultGlobalUtils} from './util/global_utils';
3029
import {defaultScheduler, renderStringify} from './util/misc_utils';
31-
import {getRootContext, getRootView} from './util/view_traversal_utils';
30+
import {getRootContext} from './util/view_traversal_utils';
3231
import {readPatchedLView, resetPreOrderHookFlags} from './util/view_utils';
3332

3433

packages/core/src/render3/component_ref.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ import {assertComponentType} from './assert';
2626
import {LifecycleHooksFeature, createRootComponent, createRootComponentView, createRootContext} from './component';
2727
import {getComponentDef} from './definition';
2828
import {NodeInjector} from './di';
29-
import {addToViewTree, assignTViewNodeToLView, createLView, createTView, elementCreate, locateHostElement, refreshDescendantViews} from './instructions/all';
29+
import {addToViewTree, assignTViewNodeToLView, createLView, createTView, elementCreate, locateHostElement, refreshDescendantViews} from './instructions/shared';
3030
import {ComponentDef} from './interfaces/definition';
3131
import {TContainerNode, TElementContainerNode, TElementNode} from './interfaces/node';
3232
import {RNode, RendererFactory3, domRendererFactory3, isProceduralRenderer} from './interfaces/renderer';
33-
import {HEADER_OFFSET, LView, LViewFlags, RootContext, TVIEW} from './interfaces/view';
33+
import {LView, LViewFlags, RootContext, TVIEW} from './interfaces/view';
3434
import {enterView, leaveView} from './state';
3535
import {defaultScheduler} from './util/misc_utils';
3636
import {getTNode} from './util/view_utils';

packages/core/src/render3/di_setup.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ import {resolveForwardRef} from '../di/forward_ref';
1111
import {ClassProvider, Provider} from '../di/interface/provider';
1212
import {isClassProvider, isTypeProvider, providerToFactory} from '../di/r3_injector';
1313

14-
import {DirectiveDef} from '.';
1514
import {diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode} from './di';
1615
import {directiveInject} from './instructions/all';
16+
import {DirectiveDef} from './interfaces/definition';
1717
import {NodeInjectorFactory} from './interfaces/injector';
18-
import {TContainerNode, TElementContainerNode, TElementNode, TNodeFlags, TNodeProviderIndexes} from './interfaces/node';
18+
import {TContainerNode, TElementContainerNode, TElementNode, TNodeProviderIndexes} from './interfaces/node';
1919
import {LView, TData, TVIEW, TView} from './interfaces/view';
2020
import {getLView, getPreviousOrParentTNode} from './state';
2121
import {isComponentDef} from './util/view_utils';

packages/core/src/render3/i18n.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import {addAllToArray} from '../util/array_utils';
1313
import {assertDefined, assertEqual, assertGreaterThan} from '../util/assert';
1414

1515
import {attachPatchData} from './context_discovery';
16-
import {allocExpando, createNodeAtIndex, elementAttribute, load, textBinding} from './instructions/all';
16+
import {elementAttribute, load, textBinding} from './instructions/all';
17+
import {allocExpando, createNodeAtIndex} from './instructions/shared';
1718
import {LContainer, NATIVE} from './interfaces/container';
1819
import {COMMENT_MARKER, ELEMENT_MARKER, I18nMutateOpCode, I18nMutateOpCodes, I18nUpdateOpCode, I18nUpdateOpCodes, IcuType, TI18n, TIcu} from './interfaces/i18n';
1920
import {TElementNode, TIcuContainerNode, TNode, TNodeType} from './interfaces/node';

packages/core/src/render3/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export {RenderFlags} from './interfaces/definition';
1919
export {CssSelectorList} from './interfaces/projection';
2020

2121

22-
2322
// clang-format off
2423
export {
2524
allocHostVars,
@@ -64,7 +63,8 @@ export {
6463
elementHostStylingApply,
6564

6665
select,
67-
66+
property,
67+
6868
listener,
6969
store,
7070
load,

packages/core/src/render3/instructions/all.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,21 @@
2525
*
2626
* Jira Issue = FW-1184
2727
*/
28-
export * from './instructions';
28+
export * from './alloc_host_vars';
29+
export * from './change_detection';
30+
export * from './container';
31+
export * from './storage';
32+
export * from './di';
33+
export * from './element';
34+
export * from './element_container';
35+
export * from './embedded_view';
36+
export * from './get_current_view';
37+
export * from './listener';
38+
export * from './namespace';
39+
export * from './next_context';
40+
export * from './projection';
41+
export * from './property';
42+
export * from './property_interpolation';
43+
export * from './select';
2944
export * from './styling_instructions';
45+
export * from './text';
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {assertEqual} from '../../util/assert';
10+
import {ComponentDef, DirectiveDef} from '../interfaces/definition';
11+
import {LView, TVIEW, TView} from '../interfaces/view';
12+
import {getCurrentDirectiveDef, getLView} from '../state';
13+
import {NO_CHANGE} from '../tokens';
14+
15+
/**
16+
* Allocates the necessary amount of slots for host vars.
17+
*
18+
* @param count Amount of vars to be allocated
19+
*/
20+
export function allocHostVars(count: number): void {
21+
const lView = getLView();
22+
const tView = lView[TVIEW];
23+
if (!tView.firstTemplatePass) return;
24+
queueHostBindingForCheck(tView, getCurrentDirectiveDef() !, count);
25+
prefillHostVars(tView, lView, count);
26+
}
27+
28+
/**
29+
* Stores host binding fn and number of host vars so it will be queued for binding refresh during
30+
* CD.
31+
*/
32+
function queueHostBindingForCheck(
33+
tView: TView, def: DirectiveDef<any>| ComponentDef<any>, hostVars: number): void {
34+
ngDevMode &&
35+
assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
36+
const expando = tView.expandoInstructions !;
37+
const length = expando.length;
38+
// Check whether a given `hostBindings` function already exists in expandoInstructions,
39+
// which can happen in case directive definition was extended from base definition (as a part of
40+
// the `InheritDefinitionFeature` logic). If we found the same `hostBindings` function in the
41+
// list, we just increase the number of host vars associated with that function, but do not add it
42+
// into the list again.
43+
if (length >= 2 && expando[length - 2] === def.hostBindings) {
44+
expando[length - 1] = (expando[length - 1] as number) + hostVars;
45+
} else {
46+
expando.push(def.hostBindings !, hostVars);
47+
}
48+
}
49+
50+
/**
51+
* On the first template pass, we need to reserve space for host binding values
52+
* after directives are matched (so all directives are saved, then bindings).
53+
* Because we are updating the blueprint, we only need to do this once.
54+
*/
55+
function prefillHostVars(tView: TView, lView: LView, totalHostVars: number): void {
56+
ngDevMode &&
57+
assertEqual(tView.firstTemplatePass, true, 'Should only be called in first template pass.');
58+
for (let i = 0; i < totalHostVars; i++) {
59+
lView.push(NO_CHANGE);
60+
tView.blueprint.push(NO_CHANGE);
61+
tView.data.push(null);
62+
}
63+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {assertDefined} from '../../util/assert';
10+
import {getComponentViewByInstance} from '../context_discovery';
11+
import {CONTEXT, RootContext, RootContextFlags} from '../interfaces/view';
12+
import {getRootView} from '../util/view_traversal_utils';
13+
import {detectChangesInternal, markViewDirty, scheduleTick, tickRootContext} from './shared';
14+
15+
/**
16+
* Synchronously perform change detection on a component (and possibly its sub-components).
17+
*
18+
* This function triggers change detection in a synchronous way on a component. There should
19+
* be very little reason to call this function directly since a preferred way to do change
20+
* detection is to {@link markDirty} the component and wait for the scheduler to call this method
21+
* at some future point in time. This is because a single user action often results in many
22+
* components being invalidated and calling change detection on each component synchronously
23+
* would be inefficient. It is better to wait until all components are marked as dirty and
24+
* then perform single change detection across all of the components
25+
*
26+
* @param component The component which the change detection should be performed on.
27+
*/
28+
export function detectChanges<T>(component: T): void {
29+
const view = getComponentViewByInstance(component);
30+
detectChangesInternal<T>(view, component);
31+
}
32+
33+
/**
34+
* Mark the component as dirty (needing change detection).
35+
*
36+
* Marking a component dirty will schedule a change detection on this
37+
* component at some point in the future. Marking an already dirty
38+
* component as dirty is a noop. Only one outstanding change detection
39+
* can be scheduled per component tree. (Two components bootstrapped with
40+
* separate `renderComponent` will have separate schedulers)
41+
*
42+
* When the root component is bootstrapped with `renderComponent`, a scheduler
43+
* can be provided.
44+
*
45+
* @param component Component to mark as dirty.
46+
*
47+
* @publicApi
48+
*/
49+
export function markDirty<T>(component: T) {
50+
ngDevMode && assertDefined(component, 'component');
51+
const rootView = markViewDirty(getComponentViewByInstance(component)) !;
52+
53+
ngDevMode && assertDefined(rootView[CONTEXT], 'rootContext should be defined');
54+
scheduleTick(rootView[CONTEXT] as RootContext, RootContextFlags.DetectChanges);
55+
}
56+
/**
57+
* Used to perform change detection on the whole application.
58+
*
59+
* This is equivalent to `detectChanges`, but invoked on root component. Additionally, `tick`
60+
* executes lifecycle hooks and conditionally checks components based on their
61+
* `ChangeDetectionStrategy` and dirtiness.
62+
*
63+
* The preferred way to trigger change detection is to call `markDirty`. `markDirty` internally
64+
* schedules `tick` using a scheduler in order to coalesce multiple `markDirty` calls into a
65+
* single change detection run. By default, the scheduler is `requestAnimationFrame`, but can
66+
* be changed when calling `renderComponent` and providing the `scheduler` option.
67+
*/
68+
export function tick<T>(component: T): void {
69+
const rootView = getRootView(component);
70+
const rootContext = rootView[CONTEXT] as RootContext;
71+
tickRootContext(rootContext);
72+
}

0 commit comments

Comments
 (0)