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:
@ -217,14 +217,23 @@ export const enum DepFlags {
|
||||
Value = 1 << 3,
|
||||
}
|
||||
|
||||
/** Injection flags for DI. */
|
||||
/**
|
||||
* 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,
|
||||
}
|
||||
|
||||
export const enum ArgumentType {Inline = 0, Dynamic = 1}
|
||||
|
@ -81,6 +81,8 @@ export class Identifiers {
|
||||
|
||||
static directiveLifeCycle: o.ExternalReference = {name: 'ɵl', moduleName: CORE};
|
||||
|
||||
static injectAttribute: o.ExternalReference = {name: 'ɵinjectAttribute', moduleName: CORE};
|
||||
|
||||
static injectElementRef: o.ExternalReference = {name: 'ɵinjectElementRef', moduleName: CORE};
|
||||
|
||||
static injectTemplateRef: o.ExternalReference = {name: 'ɵinjectTemplateRef', moduleName: CORE};
|
||||
@ -88,7 +90,7 @@ export class Identifiers {
|
||||
static injectViewContainerRef:
|
||||
o.ExternalReference = {name: 'ɵinjectViewContainerRef', moduleName: CORE};
|
||||
|
||||
static inject: o.ExternalReference = {name: 'ɵinject', moduleName: CORE};
|
||||
static directiveInject: o.ExternalReference = {name: 'ɵdirectiveInject', moduleName: CORE};
|
||||
|
||||
static defineComponent: o.ExternalReference = {name: 'ɵdefineComponent', moduleName: CORE};
|
||||
|
||||
|
@ -6,10 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata, CompileTypeSummary, flatten, identifierName, rendererTypeName, sanitizeIdentifier, tokenReference, viewClassName} from '../compile_metadata';
|
||||
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileQueryMetadata, CompileTokenMetadata, CompileTypeMetadata, CompileTypeSummary, flatten, identifierName, rendererTypeName, sanitizeIdentifier, tokenReference, viewClassName} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {BindingForm, BuiltinConverter, BuiltinFunctionCall, ConvertPropertyBindingResult, EventHandlerVars, LocalResolver, convertActionBinding, convertPropertyBinding, convertPropertyBindingBuiltins} from '../compiler_util/expression_converter';
|
||||
import {ConstantPool, DefinitionKind} from '../constant_pool';
|
||||
import {InjectFlags} from '../core';
|
||||
import {AST, AstMemoryEfficientTransformer, AstTransformer, BindingPipe, FunctionCall, ImplicitReceiver, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, ParseSpan, PropertyRead} from '../expression_parser/ast';
|
||||
import {Identifiers} from '../identifiers';
|
||||
import {LifecycleHooks} from '../lifecycle_reflector';
|
||||
@ -19,9 +20,11 @@ import {CssSelector} from '../selector';
|
||||
import {BindingParser} from '../template_parser/binding_parser';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAst, QueryMatch, RecursiveTemplateAstVisitor, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '../template_parser/template_ast';
|
||||
import {OutputContext, error} from '../util';
|
||||
|
||||
import {Identifiers as R3} from './r3_identifiers';
|
||||
import {BUILD_OPTIMIZER_COLOCATE, OutputMode} from './r3_types';
|
||||
|
||||
|
||||
/** Name of the context parameter passed into a template function */
|
||||
const CONTEXT_NAME = 'ctx';
|
||||
|
||||
@ -927,12 +930,6 @@ export function createFactory(
|
||||
const viewContainerRef = reflector.resolveExternalReference(Identifiers.ViewContainerRef);
|
||||
|
||||
for (let dependency of type.diDeps) {
|
||||
if (dependency.isValue) {
|
||||
unsupported('value dependencies');
|
||||
}
|
||||
if (dependency.isHost) {
|
||||
unsupported('host dependencies');
|
||||
}
|
||||
const token = dependency.token;
|
||||
if (token) {
|
||||
const tokenRef = tokenReference(token);
|
||||
@ -942,10 +939,18 @@ export function createFactory(
|
||||
args.push(o.importExpr(R3.injectTemplateRef).callFn([]));
|
||||
} else if (tokenRef === viewContainerRef) {
|
||||
args.push(o.importExpr(R3.injectViewContainerRef).callFn([]));
|
||||
} else if (dependency.isAttribute) {
|
||||
args.push(o.importExpr(R3.injectAttribute).callFn([o.literal(dependency.token !.value)]));
|
||||
} else {
|
||||
const value =
|
||||
const tokenValue =
|
||||
token.identifier != null ? outputCtx.importExpr(tokenRef) : o.literal(tokenRef);
|
||||
args.push(o.importExpr(R3.inject).callFn([value]));
|
||||
const directiveInjectArgs = [tokenValue];
|
||||
const flags = extractFlags(dependency);
|
||||
if (flags != InjectFlags.Default) {
|
||||
// Append flag information if other than default.
|
||||
directiveInjectArgs.push(o.literal(undefined), o.literal(flags));
|
||||
}
|
||||
args.push(o.importExpr(R3.directiveInject).callFn(directiveInjectArgs));
|
||||
}
|
||||
} else {
|
||||
unsupported('dependency without a token');
|
||||
@ -979,6 +984,26 @@ export function createFactory(
|
||||
type.reference.name ? `${type.reference.name}_Factory` : null);
|
||||
}
|
||||
|
||||
function extractFlags(dependency: CompileDiDependencyMetadata): InjectFlags {
|
||||
let flags = InjectFlags.Default;
|
||||
if (dependency.isHost) {
|
||||
flags |= InjectFlags.Host;
|
||||
}
|
||||
if (dependency.isOptional) {
|
||||
flags |= InjectFlags.Optional;
|
||||
}
|
||||
if (dependency.isSelf) {
|
||||
flags |= InjectFlags.Self;
|
||||
}
|
||||
if (dependency.isSkipSelf) {
|
||||
flags |= InjectFlags.SkipSelf;
|
||||
}
|
||||
if (dependency.isValue) {
|
||||
unsupported('value dependencies');
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove trailing null nodes as they are implied.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user