feat(ivy): support generation of flags for directive injection (#23345)
This change changes: - compiler uses `directiveInject` instead of `inject` for `Directive`s - unifies the flags in `di` as well as `render3` - changes the signature of `directiveInject` to match `inject` In prep for #23330 - compiler now generates flags for injection. Compiler portion of #23342 Prep for #23330 PR Close #23345
This commit is contained in:
@ -21,7 +21,6 @@ export {
|
||||
injectViewContainerRef as ɵinjectViewContainerRef,
|
||||
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
||||
injectAttribute as ɵinjectAttribute,
|
||||
InjectFlags as ɵInjectFlags,
|
||||
PublicFeature as ɵPublicFeature,
|
||||
NgOnChangesFeature as ɵNgOnChangesFeature,
|
||||
CssSelectorList as ɵCssSelectorList,
|
||||
|
@ -411,16 +411,21 @@ function getClosureSafeProperty<T>(objWithPropertyToExtract: T): string {
|
||||
|
||||
/**
|
||||
* Injection flags for DI.
|
||||
*
|
||||
*
|
||||
*/
|
||||
export const enum InjectFlags {
|
||||
Default = 0,
|
||||
|
||||
/** Skip the node that is requesting injection. */
|
||||
SkipSelf = 1 << 0,
|
||||
/**
|
||||
* Specifies that an injector should retrieve a dependency from any injector until reaching the
|
||||
* host element of the current component. (Only used with Element Injector)
|
||||
*/
|
||||
Host = 1 << 0,
|
||||
/** Don't descend into ancestors of the node requesting injection. */
|
||||
Self = 1 << 1,
|
||||
/** Skip the node that is requesting injection. */
|
||||
SkipSelf = 1 << 2,
|
||||
/** Inject `defaultValue` instead if token not found. */
|
||||
Optional = 1 << 3,
|
||||
}
|
||||
|
||||
let _currentInjector: Injector|null = null;
|
||||
|
@ -9,7 +9,7 @@
|
||||
// We are temporarily importing the existing viewEngine_from core so we can be sure we are
|
||||
// correctly implementing its interfaces for backwards compatibility.
|
||||
import {ChangeDetectorRef as viewEngine_ChangeDetectorRef} from '../change_detection/change_detector_ref';
|
||||
import {Injector} from '../di/injector';
|
||||
import {InjectFlags, Injector} from '../di/injector';
|
||||
import {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
|
||||
import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref';
|
||||
import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
|
||||
@ -133,19 +133,6 @@ export function getOrCreateNodeInjectorForNode(node: LElementNode | LContainerNo
|
||||
};
|
||||
}
|
||||
|
||||
/** Injection flags for DI. */
|
||||
export const enum InjectFlags {
|
||||
/** Dependency is not required. Null will be injected if there is no provider for the dependency.
|
||||
*/
|
||||
Optional = 1 << 0,
|
||||
/** When resolving a dependency, include the node that is requesting injection. */
|
||||
CheckSelf = 1 << 1,
|
||||
/** When resolving a dependency, include ancestors of the node requesting injection. */
|
||||
CheckParent = 1 << 2,
|
||||
/** Default injection options: required, checks both self and ancestors. */
|
||||
Default = CheckSelf | CheckParent,
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an injection error with the given text and token.
|
||||
*
|
||||
@ -201,8 +188,14 @@ export function diPublic(def: DirectiveDef<any>): void {
|
||||
* @param flags Injection flags (e.g. CheckParent)
|
||||
* @returns The instance found
|
||||
*/
|
||||
export function directiveInject<T>(token: Type<T>, flags?: InjectFlags, defaultValue?: T): T {
|
||||
return getOrCreateInjectable<T>(getOrCreateNodeInjector(), token, flags, defaultValue);
|
||||
export function directiveInject<T>(
|
||||
token: Type<T>, notFoundValue?: undefined, flags?: InjectFlags): T;
|
||||
export function directiveInject<T>(token: Type<T>, notFoundValue: T, flags?: InjectFlags): T;
|
||||
export function directiveInject<T>(token: Type<T>, notFoundValue: null, flags?: InjectFlags): T|
|
||||
null;
|
||||
export function directiveInject<T>(
|
||||
token: Type<T>, notFoundValue?: T | null, flags = InjectFlags.Default): T|null {
|
||||
return getOrCreateInjectable<T>(getOrCreateNodeInjector(), token, flags, notFoundValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,7 +345,7 @@ function getClosestComponentAncestor(node: LViewNode | LElementNode): LElementNo
|
||||
* @returns The instance found
|
||||
*/
|
||||
export function getOrCreateInjectable<T>(
|
||||
di: LInjector, token: Type<T>, flags?: InjectFlags, defaultValue?: T): T {
|
||||
di: LInjector, token: Type<T>, flags?: InjectFlags, defaultValue?: T | null): T|null {
|
||||
const bloomHash = bloomHashBit(token);
|
||||
|
||||
// If the token has a bloom hash, then it is a directive that is public to the injection system
|
||||
|
@ -8,10 +8,9 @@
|
||||
|
||||
import {LifecycleHooksFeature, createComponentRef, getHostElement, getRenderedText, renderComponent, whenRendered} from './component';
|
||||
import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective, definePipe} from './definition';
|
||||
import {InjectFlags} from './di';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType, PipeDef} from './interfaces/definition';
|
||||
|
||||
export {InjectFlags, QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, directiveInject, injectAttribute, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di';
|
||||
export {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, directiveInject, injectAttribute, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from './di';
|
||||
export {RenderFlags} from './interfaces/definition';
|
||||
export {CssSelectorList} from './interfaces/projection';
|
||||
|
||||
|
@ -7,10 +7,10 @@
|
||||
*/
|
||||
|
||||
import {NgForOf as NgForOfDef, NgIf as NgIfDef} from '@angular/common';
|
||||
import {IterableDiffers} from '@angular/core';
|
||||
import {InjectFlags, IterableDiffers} from '@angular/core';
|
||||
|
||||
import {defaultIterableDiffers} from '../../src/change_detection/change_detection';
|
||||
import {DirectiveType, InjectFlags, NgOnChangesFeature, defineDirective, directiveInject, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {DirectiveType, NgOnChangesFeature, defineDirective, directiveInject, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
|
||||
export const NgForOf: DirectiveType<NgForOfDef<any>> = NgForOfDef as any;
|
||||
export const NgIf: DirectiveType<NgIfDef> = NgIfDef as any;
|
||||
@ -20,7 +20,7 @@ NgForOf.ngDirectiveDef = defineDirective({
|
||||
selectors: [['', 'ngForOf', '']],
|
||||
factory: () => new NgForOfDef(
|
||||
injectViewContainerRef(), injectTemplateRef(),
|
||||
directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
|
||||
directiveInject(IterableDiffers, defaultIterableDiffers, InjectFlags.Default)),
|
||||
features: [NgOnChangesFeature()],
|
||||
inputs: {
|
||||
ngForOf: 'ngForOf',
|
||||
|
@ -6,10 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as $core$ from '../../../index';
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren, ViewContainerRef} from '../../../src/core';
|
||||
import * as $r3$ from '../../../src/core_render3_private_export';
|
||||
import {renderComponent, toHtml} from '../render_util';
|
||||
|
||||
|
||||
/// See: `normative.md`
|
||||
xdescribe('NgModule', () => {
|
||||
|
||||
@ -69,7 +71,7 @@ xdescribe('NgModule', () => {
|
||||
static ngInjectableDef = defineInjectable({
|
||||
providedIn: MyModule,
|
||||
factory: () => new BurntToast(
|
||||
$r3$.ɵdirectiveInject(Toast, $r3$.ɵInjectFlags.Optional),
|
||||
$r3$.ɵdirectiveInject(Toast, undefined, $core$.InjectFlags.Optional),
|
||||
$r3$.ɵdirectiveInject(String)),
|
||||
});
|
||||
// /NORMATIVE
|
||||
|
@ -6,11 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectorRef, ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
import {ChangeDetectorRef, ElementRef, InjectFlags, TemplateRef, ViewContainerRef} from '@angular/core';
|
||||
import {RenderFlags} from '@angular/core/src/render3/interfaces/definition';
|
||||
|
||||
import {defineComponent} from '../../src/render3/definition';
|
||||
import {InjectFlags, bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||
import {bloomAdd, bloomFindPossibleInjector, getOrCreateNodeInjector, injectAttribute} from '../../src/render3/di';
|
||||
import {NgOnChangesFeature, PublicFeature, defineDirective, directiveInject, injectChangeDetectorRef, injectElementRef, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
|
||||
import {bind, container, containerRefreshEnd, containerRefreshStart, createLNode, createLView, createTView, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, enterView, interpolation2, leaveView, load, projection, projectionDef, text, textBinding} from '../../src/render3/instructions';
|
||||
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||
@ -1019,7 +1019,7 @@ describe('di', () => {
|
||||
type: MyApp,
|
||||
selectors: [['my-app']],
|
||||
factory: () => new MyApp(
|
||||
directiveInject(String as any, InjectFlags.Default, 'DefaultValue')),
|
||||
directiveInject(String as any, 'DefaultValue', InjectFlags.Default)),
|
||||
template: () => null
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user