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:
Misko Hevery
2018-04-12 12:30:21 -07:00
committed by Igor Minar
parent 490772e680
commit 6f213a74f2
13 changed files with 152 additions and 46 deletions

View File

@ -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}

View File

@ -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};

View File

@ -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.
*/