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:
parent
490772e680
commit
6f213a74f2
|
@ -2257,7 +2257,7 @@ describe('ngc transformer command-line', () => {
|
||||||
constructor(e: Existing) {}
|
constructor(e: Existing) {}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
expect(source).toMatch(/ngInjectableDef.*return ..\(..\.inject\(Existing, undefined, 1\)/);
|
expect(source).toMatch(/ngInjectableDef.*return ..\(..\.inject\(Existing, undefined, 4\)/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('compiles a service that depends on a token', () => {
|
it('compiles a service that depends on a token', () => {
|
||||||
|
|
|
@ -217,14 +217,23 @@ export const enum DepFlags {
|
||||||
Value = 1 << 3,
|
Value = 1 << 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Injection flags for DI. */
|
/**
|
||||||
|
* Injection flags for DI.
|
||||||
|
*/
|
||||||
export const enum InjectFlags {
|
export const enum InjectFlags {
|
||||||
Default = 0,
|
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. */
|
/** Don't descend into ancestors of the node requesting injection. */
|
||||||
Self = 1 << 1,
|
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}
|
export const enum ArgumentType {Inline = 0, Dynamic = 1}
|
||||||
|
|
|
@ -81,6 +81,8 @@ export class Identifiers {
|
||||||
|
|
||||||
static directiveLifeCycle: o.ExternalReference = {name: 'ɵl', moduleName: CORE};
|
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 injectElementRef: o.ExternalReference = {name: 'ɵinjectElementRef', moduleName: CORE};
|
||||||
|
|
||||||
static injectTemplateRef: o.ExternalReference = {name: 'ɵinjectTemplateRef', moduleName: CORE};
|
static injectTemplateRef: o.ExternalReference = {name: 'ɵinjectTemplateRef', moduleName: CORE};
|
||||||
|
@ -88,7 +90,7 @@ export class Identifiers {
|
||||||
static injectViewContainerRef:
|
static injectViewContainerRef:
|
||||||
o.ExternalReference = {name: 'ɵinjectViewContainerRef', moduleName: CORE};
|
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};
|
static defineComponent: o.ExternalReference = {name: 'ɵdefineComponent', moduleName: CORE};
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* 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 {CompileReflector} from '../compile_reflector';
|
||||||
import {BindingForm, BuiltinConverter, BuiltinFunctionCall, ConvertPropertyBindingResult, EventHandlerVars, LocalResolver, convertActionBinding, convertPropertyBinding, convertPropertyBindingBuiltins} from '../compiler_util/expression_converter';
|
import {BindingForm, BuiltinConverter, BuiltinFunctionCall, ConvertPropertyBindingResult, EventHandlerVars, LocalResolver, convertActionBinding, convertPropertyBinding, convertPropertyBindingBuiltins} from '../compiler_util/expression_converter';
|
||||||
import {ConstantPool, DefinitionKind} from '../constant_pool';
|
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 {AST, AstMemoryEfficientTransformer, AstTransformer, BindingPipe, FunctionCall, ImplicitReceiver, LiteralArray, LiteralMap, LiteralPrimitive, MethodCall, ParseSpan, PropertyRead} from '../expression_parser/ast';
|
||||||
import {Identifiers} from '../identifiers';
|
import {Identifiers} from '../identifiers';
|
||||||
import {LifecycleHooks} from '../lifecycle_reflector';
|
import {LifecycleHooks} from '../lifecycle_reflector';
|
||||||
|
@ -19,9 +20,11 @@ import {CssSelector} from '../selector';
|
||||||
import {BindingParser} from '../template_parser/binding_parser';
|
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 {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 {OutputContext, error} from '../util';
|
||||||
|
|
||||||
import {Identifiers as R3} from './r3_identifiers';
|
import {Identifiers as R3} from './r3_identifiers';
|
||||||
import {BUILD_OPTIMIZER_COLOCATE, OutputMode} from './r3_types';
|
import {BUILD_OPTIMIZER_COLOCATE, OutputMode} from './r3_types';
|
||||||
|
|
||||||
|
|
||||||
/** Name of the context parameter passed into a template function */
|
/** Name of the context parameter passed into a template function */
|
||||||
const CONTEXT_NAME = 'ctx';
|
const CONTEXT_NAME = 'ctx';
|
||||||
|
|
||||||
|
@ -927,12 +930,6 @@ export function createFactory(
|
||||||
const viewContainerRef = reflector.resolveExternalReference(Identifiers.ViewContainerRef);
|
const viewContainerRef = reflector.resolveExternalReference(Identifiers.ViewContainerRef);
|
||||||
|
|
||||||
for (let dependency of type.diDeps) {
|
for (let dependency of type.diDeps) {
|
||||||
if (dependency.isValue) {
|
|
||||||
unsupported('value dependencies');
|
|
||||||
}
|
|
||||||
if (dependency.isHost) {
|
|
||||||
unsupported('host dependencies');
|
|
||||||
}
|
|
||||||
const token = dependency.token;
|
const token = dependency.token;
|
||||||
if (token) {
|
if (token) {
|
||||||
const tokenRef = tokenReference(token);
|
const tokenRef = tokenReference(token);
|
||||||
|
@ -942,10 +939,18 @@ export function createFactory(
|
||||||
args.push(o.importExpr(R3.injectTemplateRef).callFn([]));
|
args.push(o.importExpr(R3.injectTemplateRef).callFn([]));
|
||||||
} else if (tokenRef === viewContainerRef) {
|
} else if (tokenRef === viewContainerRef) {
|
||||||
args.push(o.importExpr(R3.injectViewContainerRef).callFn([]));
|
args.push(o.importExpr(R3.injectViewContainerRef).callFn([]));
|
||||||
|
} else if (dependency.isAttribute) {
|
||||||
|
args.push(o.importExpr(R3.injectAttribute).callFn([o.literal(dependency.token !.value)]));
|
||||||
} else {
|
} else {
|
||||||
const value =
|
const tokenValue =
|
||||||
token.identifier != null ? outputCtx.importExpr(tokenRef) : o.literal(tokenRef);
|
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 {
|
} else {
|
||||||
unsupported('dependency without a token');
|
unsupported('dependency without a token');
|
||||||
|
@ -979,6 +984,26 @@ export function createFactory(
|
||||||
type.reference.name ? `${type.reference.name}_Factory` : null);
|
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.
|
* Remove trailing null nodes as they are implied.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {MockDirectory, setup} from '../aot/test_util';
|
||||||
|
import {compile, expectEmit} from './mock_compile';
|
||||||
|
|
||||||
|
describe('compiler compliance: dependency injection', () => {
|
||||||
|
const angularFiles = setup({
|
||||||
|
compileAngular: true,
|
||||||
|
compileAnimations: false,
|
||||||
|
compileCommon: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create factory methods', () => {
|
||||||
|
const files = {
|
||||||
|
app: {
|
||||||
|
'spec.ts': `
|
||||||
|
import {Component, NgModule, Injectable, Attribute, Host, SkipSelf, Self, Optional} from '@angular/core';
|
||||||
|
import {CommonModule} from '@angular/common';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class MyService {}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'my-component',
|
||||||
|
template: \`\`
|
||||||
|
})
|
||||||
|
export class MyComponent {
|
||||||
|
constructor(
|
||||||
|
@Attribute('name') name:string,
|
||||||
|
s1: MyService,
|
||||||
|
@Host() s2: MyService,
|
||||||
|
@Self() s4: MyService,
|
||||||
|
@SkipSelf() s3: MyService,
|
||||||
|
@Optional() s5: MyService,
|
||||||
|
@Self() @Optional() s6: MyService,
|
||||||
|
) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({declarations: [MyComponent], imports: [CommonModule], providers: [MyService]})
|
||||||
|
export class MyModule {}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const factory = `
|
||||||
|
factory: function MyComponent_Factory() {
|
||||||
|
return new MyComponent(
|
||||||
|
$r3$.ɵinjectAttribute('name'),
|
||||||
|
$r3$.ɵdirectiveInject(MyService),
|
||||||
|
$r3$.ɵdirectiveInject(MyService, (undefined as any), 1),
|
||||||
|
$r3$.ɵdirectiveInject(MyService, (undefined as any), 2),
|
||||||
|
$r3$.ɵdirectiveInject(MyService, (undefined as any), 4),
|
||||||
|
$r3$.ɵdirectiveInject(MyService, (undefined as any), 8),
|
||||||
|
$r3$.ɵdirectiveInject(MyService, (undefined as any), 10)
|
||||||
|
);
|
||||||
|
}`;
|
||||||
|
|
||||||
|
|
||||||
|
const result = compile(files, angularFiles);
|
||||||
|
|
||||||
|
expectEmit(result.source, factory, 'Incorrect factory');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -21,7 +21,6 @@ export {
|
||||||
injectViewContainerRef as ɵinjectViewContainerRef,
|
injectViewContainerRef as ɵinjectViewContainerRef,
|
||||||
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
injectChangeDetectorRef as ɵinjectChangeDetectorRef,
|
||||||
injectAttribute as ɵinjectAttribute,
|
injectAttribute as ɵinjectAttribute,
|
||||||
InjectFlags as ɵInjectFlags,
|
|
||||||
PublicFeature as ɵPublicFeature,
|
PublicFeature as ɵPublicFeature,
|
||||||
NgOnChangesFeature as ɵNgOnChangesFeature,
|
NgOnChangesFeature as ɵNgOnChangesFeature,
|
||||||
CssSelectorList as ɵCssSelectorList,
|
CssSelectorList as ɵCssSelectorList,
|
||||||
|
|
|
@ -411,16 +411,21 @@ function getClosureSafeProperty<T>(objWithPropertyToExtract: T): string {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection flags for DI.
|
* Injection flags for DI.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
export const enum InjectFlags {
|
export const enum InjectFlags {
|
||||||
Default = 0,
|
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. */
|
/** Don't descend into ancestors of the node requesting injection. */
|
||||||
Self = 1 << 1,
|
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;
|
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
|
// We are temporarily importing the existing viewEngine_from core so we can be sure we are
|
||||||
// correctly implementing its interfaces for backwards compatibility.
|
// correctly implementing its interfaces for backwards compatibility.
|
||||||
import {ChangeDetectorRef as viewEngine_ChangeDetectorRef} from '../change_detection/change_detector_ref';
|
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 {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
|
||||||
import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref';
|
import {ElementRef as viewEngine_ElementRef} from '../linker/element_ref';
|
||||||
import {NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
|
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.
|
* 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)
|
* @param flags Injection flags (e.g. CheckParent)
|
||||||
* @returns The instance found
|
* @returns The instance found
|
||||||
*/
|
*/
|
||||||
export function directiveInject<T>(token: Type<T>, flags?: InjectFlags, defaultValue?: T): T {
|
export function directiveInject<T>(
|
||||||
return getOrCreateInjectable<T>(getOrCreateNodeInjector(), token, flags, defaultValue);
|
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
|
* @returns The instance found
|
||||||
*/
|
*/
|
||||||
export function getOrCreateInjectable<T>(
|
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);
|
const bloomHash = bloomHashBit(token);
|
||||||
|
|
||||||
// If the token has a bloom hash, then it is a directive that is public to the injection system
|
// 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 {LifecycleHooksFeature, createComponentRef, getHostElement, getRenderedText, renderComponent, whenRendered} from './component';
|
||||||
import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective, definePipe} from './definition';
|
import {NgOnChangesFeature, PublicFeature, defineComponent, defineDirective, definePipe} from './definition';
|
||||||
import {InjectFlags} from './di';
|
|
||||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveDefFlags, DirectiveType, PipeDef} from './interfaces/definition';
|
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 {RenderFlags} from './interfaces/definition';
|
||||||
export {CssSelectorList} from './interfaces/projection';
|
export {CssSelectorList} from './interfaces/projection';
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {NgForOf as NgForOfDef, NgIf as NgIfDef} from '@angular/common';
|
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 {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 NgForOf: DirectiveType<NgForOfDef<any>> = NgForOfDef as any;
|
||||||
export const NgIf: DirectiveType<NgIfDef> = NgIfDef as any;
|
export const NgIf: DirectiveType<NgIfDef> = NgIfDef as any;
|
||||||
|
@ -20,7 +20,7 @@ NgForOf.ngDirectiveDef = defineDirective({
|
||||||
selectors: [['', 'ngForOf', '']],
|
selectors: [['', 'ngForOf', '']],
|
||||||
factory: () => new NgForOfDef(
|
factory: () => new NgForOfDef(
|
||||||
injectViewContainerRef(), injectTemplateRef(),
|
injectViewContainerRef(), injectTemplateRef(),
|
||||||
directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
|
directiveInject(IterableDiffers, defaultIterableDiffers, InjectFlags.Default)),
|
||||||
features: [NgOnChangesFeature()],
|
features: [NgOnChangesFeature()],
|
||||||
inputs: {
|
inputs: {
|
||||||
ngForOf: 'ngForOf',
|
ngForOf: 'ngForOf',
|
||||||
|
|
|
@ -6,10 +6,12 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* 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 {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 * as $r3$ from '../../../src/core_render3_private_export';
|
||||||
import {renderComponent, toHtml} from '../render_util';
|
import {renderComponent, toHtml} from '../render_util';
|
||||||
|
|
||||||
|
|
||||||
/// See: `normative.md`
|
/// See: `normative.md`
|
||||||
xdescribe('NgModule', () => {
|
xdescribe('NgModule', () => {
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ xdescribe('NgModule', () => {
|
||||||
static ngInjectableDef = defineInjectable({
|
static ngInjectableDef = defineInjectable({
|
||||||
providedIn: MyModule,
|
providedIn: MyModule,
|
||||||
factory: () => new BurntToast(
|
factory: () => new BurntToast(
|
||||||
$r3$.ɵdirectiveInject(Toast, $r3$.ɵInjectFlags.Optional),
|
$r3$.ɵdirectiveInject(Toast, undefined, $core$.InjectFlags.Optional),
|
||||||
$r3$.ɵdirectiveInject(String)),
|
$r3$.ɵdirectiveInject(String)),
|
||||||
});
|
});
|
||||||
// /NORMATIVE
|
// /NORMATIVE
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* 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 {RenderFlags} from '@angular/core/src/render3/interfaces/definition';
|
||||||
|
|
||||||
import {defineComponent} from '../../src/render3/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 {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 {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';
|
import {LInjector} from '../../src/render3/interfaces/injector';
|
||||||
|
@ -1019,7 +1019,7 @@ describe('di', () => {
|
||||||
type: MyApp,
|
type: MyApp,
|
||||||
selectors: [['my-app']],
|
selectors: [['my-app']],
|
||||||
factory: () => new MyApp(
|
factory: () => new MyApp(
|
||||||
directiveInject(String as any, InjectFlags.Default, 'DefaultValue')),
|
directiveInject(String as any, 'DefaultValue', InjectFlags.Default)),
|
||||||
template: () => null
|
template: () => null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,8 +376,10 @@ export interface InjectDecorator {
|
||||||
|
|
||||||
export declare const enum InjectFlags {
|
export declare const enum InjectFlags {
|
||||||
Default = 0,
|
Default = 0,
|
||||||
SkipSelf = 1,
|
Host = 1,
|
||||||
Self = 2,
|
Self = 2,
|
||||||
|
SkipSelf = 4,
|
||||||
|
Optional = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare class InjectionToken<T> {
|
export declare class InjectionToken<T> {
|
||||||
|
|
Loading…
Reference in New Issue