refactor(core): Cleanup non-standard Injector handling. (#39621)

Due to historical reasons `Injector.__NG_ELEMENT_ID__` was set to `-1`.
This changes it to be consistent with other `*Ref.__NG_ELEMENT_ID__`
constructs.

PR Close #39621
This commit is contained in:
Misko Hevery 2020-11-09 21:09:18 -08:00 committed by atscott
parent 585875c3f4
commit 8574c3000e
22 changed files with 229 additions and 172 deletions

View File

@ -255,21 +255,6 @@
"packages/core/src/render3/definition.ts",
"packages/core/src/metadata/ng_module.ts"
],
[
"packages/core/src/application_ref.ts",
"packages/core/src/application_tokens.ts",
"packages/core/src/linker/component_factory.ts",
"packages/core/src/change_detection/change_detection.ts",
"packages/core/src/change_detection/change_detector_ref.ts",
"packages/core/src/render3/view_ref.ts",
"packages/core/src/linker/view_container_ref.ts",
"packages/core/src/render3/di.ts",
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts",
"packages/core/src/di/r3_injector.ts",
"packages/core/src/render3/definition.ts",
"packages/core/src/metadata/ng_module.ts"
],
[
"packages/core/src/application_ref.ts",
"packages/core/src/application_tokens.ts",
@ -641,16 +626,6 @@
"packages/core/src/render3/definition.ts",
"packages/core/src/metadata/ng_module.ts"
],
[
"packages/core/src/application_ref.ts",
"packages/core/src/linker/compiler.ts",
"packages/core/src/render3/ng_module_ref.ts",
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts",
"packages/core/src/di/r3_injector.ts",
"packages/core/src/render3/definition.ts",
"packages/core/src/metadata/ng_module.ts"
],
[
"packages/core/src/application_ref.ts",
"packages/core/src/linker/compiler.ts",
@ -786,20 +761,6 @@
"packages/core/src/render3/definition.ts",
"packages/core/src/metadata/ng_module.ts"
],
[
"packages/core/src/application_ref.ts",
"packages/core/src/metadata/resource_loading.ts",
"packages/core/src/metadata/directives.ts",
"packages/core/src/render3/jit/directive.ts",
"packages/core/src/render3/jit/environment.ts",
"packages/core/src/render3/index.ts",
"packages/core/src/render3/pipe.ts",
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts",
"packages/core/src/di/r3_injector.ts",
"packages/core/src/render3/definition.ts",
"packages/core/src/metadata/ng_module.ts"
],
[
"packages/core/src/application_ref.ts",
"packages/core/src/metadata/resource_loading.ts",
@ -900,6 +861,16 @@
"packages/core/src/view/entrypoint.ts",
"packages/core/src/view/services.ts"
],
[
"packages/core/src/di.ts",
"packages/core/src/di/index.ts",
"packages/core/src/di/injectable.ts",
"packages/core/src/di/jit/injectable.ts",
"packages/core/src/di/jit/environment.ts",
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts",
"packages/core/src/di/null_injector.ts"
],
[
"packages/core/src/di/injectable.ts",
"packages/core/src/di/jit/injectable.ts"
@ -908,6 +879,11 @@
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts"
],
[
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts",
"packages/core/src/di/null_injector.ts"
],
[
"packages/core/src/di/injector_compatibility.ts",
"packages/core/src/di/injector.ts",
@ -921,6 +897,10 @@
"packages/core/src/metadata/ng_module.ts",
"packages/core/src/di/util.ts"
],
[
"packages/core/src/di/injector_token.ts",
"packages/core/src/di/injector.ts"
],
[
"packages/core/src/di/injector.ts",
"packages/core/src/di/r3_injector.ts"

View File

@ -837,11 +837,11 @@ export declare interface RendererType2 {
}
export declare class ResolvedReflectiveFactory {
dependencies: ɵangular_packages_core_core_e[];
dependencies: ɵangular_packages_core_core_d[];
factory: Function;
constructor(
factory: Function,
dependencies: ɵangular_packages_core_core_e[]);
dependencies: ɵangular_packages_core_core_d[]);
}
export declare interface ResolvedReflectiveProvider {

View File

@ -12,7 +12,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 3037,
"main-es2015": 449483,
"main-es2015": 448796,
"polyfills-es2015": 52415
}
}

View File

@ -21,7 +21,7 @@
"master": {
"uncompressed": {
"runtime-es2015": 1485,
"main-es2015": 147252,
"main-es2015": 146680,
"polyfills-es2015": 36964
}
}

View File

@ -18,7 +18,8 @@ export {ɵɵdefineInjectable, defineInjectable, ɵɵdefineInjector, InjectableTy
export {forwardRef, resolveForwardRef, ForwardRefFn} from './forward_ref';
export {Injectable, InjectableDecorator, InjectableProvider} from './injectable';
export {Injector} from './injector';
export {ɵɵinject, inject, INJECTOR, ɵɵinvalidFactoryDep} from './injector_compatibility';
export {ɵɵinject, inject, ɵɵinvalidFactoryDep} from './injector_compatibility';
export {INJECTOR} from './injector_token';
export {ReflectiveInjector} from './reflective_injector';
export {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, Provider, StaticClassProvider, StaticClassSansProvider, StaticProvider, TypeProvider, ValueProvider, ValueSansProvider} from './interface/provider';
export {ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './reflective_provider';

View File

@ -0,0 +1,76 @@
/**
* @license
* Copyright Google LLC 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 {Type} from '../interface/type';
import {assertNotEqual} from '../util/assert';
import {stringify} from '../util/stringify';
import {InjectionToken} from './injection_token';
import {getInjectableDef, ɵɵInjectableDef} from './interface/defs';
import {InjectFlags} from './interface/injector';
/**
* Current implementation of inject.
*
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
* way for two reasons:
* 1. `Injector` should not depend on ivy logic.
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
*/
let _injectImplementation: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
undefined;
export function getInjectImplementation() {
return _injectImplementation;
}
/**
* Sets the current inject implementation.
*/
export function setInjectImplementation(
impl: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
undefined): (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|undefined {
const previous = _injectImplementation;
_injectImplementation = impl;
return previous;
}
/**
* Injects `root` tokens in limp mode.
*
* If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
* `"root"`. This is known as the limp mode injection. In such case the value is stored in the
* `InjectableDef`.
*/
export function injectRootLimpMode<T>(
token: Type<T>|InjectionToken<T>, notFoundValue: T|undefined, flags: InjectFlags): T|null {
const injectableDef: ɵɵInjectableDef<T>|null = getInjectableDef(token);
if (injectableDef && injectableDef.providedIn == 'root') {
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
injectableDef.value;
}
if (flags & InjectFlags.Optional) return null;
if (notFoundValue !== undefined) return notFoundValue;
throw new Error(`Injector: NOT_FOUND [${stringify(token)}]`);
}
/**
* Assert that `_injectImplementation` is not `fn`.
*
* This is useful, to prevent infinite recursion.
*
* @param fn Function which it should not equal to
*/
export function assertInjectImplementationNotEqual(
fn: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)) {
ngDevMode &&
assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
}

View File

@ -7,6 +7,7 @@
*/
import {Type} from '../interface/type';
import {assertLessThan} from '../util/assert';
import {ɵɵdefineInjectable} from './interface/defs';
@ -61,9 +62,10 @@ export class InjectionToken<T> {
}) {
this.ɵprov = undefined;
if (typeof options == 'number') {
(typeof ngDevMode === 'undefined' || ngDevMode) &&
assertLessThan(options, 0, 'Only negative numbers are supported here');
// This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
// __NG_ELEMENT_ID__ is Used by Ivy to determine bloom filter id.
// We are using it to assign `-1` which is used to identify `Injector`.
// See `InjectorMarkers`
(this as any).__NG_ELEMENT_ID__ = options;
} else if (options !== undefined) {
this.ɵprov = ɵɵdefineInjectable({

View File

@ -8,14 +8,16 @@
import {AbstractType, Type} from '../interface/type';
import {stringify} from '../util/stringify';
import {resolveForwardRef} from './forward_ref';
import {InjectionToken} from './injection_token';
import {catchInjectorError, formatError, INJECTOR, NG_TEMP_TOKEN_PATH, NullInjector, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
import {catchInjectorError, formatError, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
import {InjectorMarkers} from './injector_marker';
import {INJECTOR} from './injector_token';
import {getInjectableDef, ɵɵdefineInjectable} from './interface/defs';
import {InjectFlags} from './interface/injector';
import {ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, ValueProvider} from './interface/provider';
import {Inject, Optional, Self, SkipSelf} from './metadata';
import {NullInjector} from './null_injector';
import {createInjector} from './r3_injector';
import {INJECTOR_SCOPE} from './scope';
@ -113,7 +115,7 @@ export abstract class Injector {
* @internal
* @nocollapse
*/
static __NG_ELEMENT_ID__ = -1;
static __NG_ELEMENT_ID__ = InjectorMarkers.Injector;
}

View File

@ -14,28 +14,14 @@ import {getClosureSafeProperty} from '../util/property';
import {stringify} from '../util/stringify';
import {resolveForwardRef} from './forward_ref';
import {getInjectImplementation, injectRootLimpMode} from './inject_switch';
import {InjectionToken} from './injection_token';
import {Injector} from './injector';
import {getInjectableDef, ɵɵInjectableDef} from './interface/defs';
import {InjectFlags} from './interface/injector';
import {ValueProvider} from './interface/provider';
import {Inject, Optional, Self, SkipSelf} from './metadata';
/**
* An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
*
* Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
* project.
*
* @publicApi
*/
export const INJECTOR = new InjectionToken<Injector>(
'INJECTOR',
-1 as any // `-1` is used by Ivy DI system as special value to recognize it as `Injector`.
);
const _THROW_IF_NOT_FOUND = {};
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
@ -62,41 +48,6 @@ export function setCurrentInjector(injector: Injector|null|undefined): Injector|
return former;
}
/**
* Current implementation of inject.
*
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
* way for two reasons:
* 1. `Injector` should not depend on ivy logic.
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
*/
let _injectImplementation: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
undefined;
/**
* Sets the current inject implementation.
*/
export function setInjectImplementation(
impl: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
undefined): (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|undefined {
const previous = _injectImplementation;
_injectImplementation = impl;
return previous;
}
/**
* Assert that `_injectImplementation` is not `fn`.
*
* This is useful, to prevent infinite recursion.
*
* @param fn Function which it should not equal to
*/
export function assertInjectImplementationNot(
fn: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)) {
ngDevMode &&
assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
}
export function injectInjectorOnly<T>(token: Type<T>|InjectionToken<T>): T;
export function injectInjectorOnly<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T|
@ -128,7 +79,7 @@ export function injectInjectorOnly<T>(
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>): T;
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T|null;
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>, flags = InjectFlags.Default): T|null {
return (_injectImplementation || injectInjectorOnly)(resolveForwardRef(token), flags);
return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
}
/**
@ -181,24 +132,6 @@ Please check that 1) the type for the parameter at index ${
*/
export const inject = ɵɵinject;
/**
* Injects `root` tokens in limp mode.
*
* If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
* `"root"`. This is known as the limp mode injection. In such case the value is stored in the
* `InjectableDef`.
*/
export function injectRootLimpMode<T>(
token: Type<T>|InjectionToken<T>, notFoundValue: T|undefined, flags: InjectFlags): T|null {
const injectableDef: ɵɵInjectableDef<T>|null = getInjectableDef(token);
if (injectableDef && injectableDef.providedIn == 'root') {
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
injectableDef.value;
}
if (flags & InjectFlags.Optional) return null;
if (notFoundValue !== undefined) return notFoundValue;
throw new Error(`Injector: NOT_FOUND [${stringify(token)}]`);
}
export function injectArgs(types: (Type<any>|InjectionToken<any>|any[])[]): any[] {
const args: any[] = [];
@ -236,22 +169,6 @@ export function injectArgs(types: (Type<any>|InjectionToken<any>|any[])[]): any[
}
export class NullInjector implements Injector {
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
if (notFoundValue === THROW_IF_NOT_FOUND) {
// Intentionally left behind: With dev tools open the debugger will stop here. There is no
// reason why correctly written application should cause this exception.
// TODO(misko): uncomment the next line once `ngDevMode` works with closure.
// if (ngDevMode) debugger;
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
error.name = 'NullInjectorError';
throw error;
}
return notFoundValue;
}
}
export function catchInjectorError(
e: any, token: any, injectorErrorName: string, source: string|null): never {
const tokenPath: any[] = e[NG_TEMP_TOKEN_PATH];

View File

@ -0,0 +1,24 @@
/**
* @license
* Copyright Google LLC 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
*/
/**
* Special markers which can be left on `Type.__NG_ELEMENT_ID__` which are used by the Ivy's
* `NodeInjector`. Usually these markers contain factory functions. But in case of this special
* marker we can't leave behind a function because it would create tree shaking problem.
*
* Currently only `Injector` is special.
*
* NOTE: the numbers here must be negative, because positive numbers are used as IDs for bloom
* filter.
*/
export const enum InjectorMarkers {
/**
* Marks that the current type is `Injector`
*/
Injector = -1
}

View File

@ -0,0 +1,28 @@
/**
* @license
* Copyright Google LLC 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 {InjectionToken} from './injection_token';
import {Injector} from './injector';
import {InjectorMarkers} from './injector_marker';
/**
* An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
*
* Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
* project.
*
* @publicApi
*/
export const INJECTOR = new InjectionToken<Injector>(
'INJECTOR',
// Dissable tslint because this is const enum which gets inlined not top level prop access.
// tslint:disable-next-line: no-toplevel-property-access
InjectorMarkers.Injector as any, // Special value used by Ivy to identify `Injector`.
);

View File

@ -0,0 +1,23 @@
/**
* @license
* Copyright Google LLC 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 {stringify} from '../util/stringify';
import {Injector} from '.';
import {THROW_IF_NOT_FOUND} from './injector_compatibility';
export class NullInjector implements Injector {
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
if (notFoundValue === THROW_IF_NOT_FOUND) {
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
error.name = 'NullInjectorError';
throw error;
}
return notFoundValue;
}
}

View File

@ -19,10 +19,12 @@ import {stringify} from '../util/stringify';
import {resolveForwardRef} from './forward_ref';
import {InjectionToken} from './injection_token';
import {Injector} from './injector';
import {catchInjectorError, injectArgs, INJECTOR, NG_TEMP_TOKEN_PATH, NullInjector, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
import {catchInjectorError, injectArgs, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
import {INJECTOR} from './injector_token';
import {getInheritedInjectableDef, getInjectableDef, getInjectorDef, InjectorType, InjectorTypeWithProviders, ɵɵInjectableDef} from './interface/defs';
import {InjectFlags} from './interface/injector';
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './interface/provider';
import {NullInjector} from './null_injector';
import {INJECTOR_SCOPE} from './scope';

View File

@ -7,9 +7,10 @@
*/
import {isForwardRef, resolveForwardRef} from '../di/forward_ref';
import {injectRootLimpMode, setInjectImplementation} from '../di/inject_switch';
import {InjectionToken} from '../di/injection_token';
import {Injector} from '../di/injector';
import {injectRootLimpMode, setInjectImplementation} from '../di/injector_compatibility';
import {InjectorMarkers} from '../di/injector_marker';
import {getInjectorDef} from '../di/interface/defs';
import {InjectFlags} from '../di/interface/injector';
import {Type} from '../interface/type';
@ -415,8 +416,11 @@ export function getOrCreateInjectable<T>(
// so just call the factory function to create it.
if (typeof bloomHash === 'function') {
if (!enterDI(lView, tNode, flags)) {
// Failed to enter DI use module injector instead.
return lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue);
// Failed to enter DI, try module injector instead. If a token is injected with the @Host
// flag, the module injector is not searched for that token in Ivy.
return (flags & InjectFlags.Host) ?
notFoundValueOrThrow<T>(notFoundValue, token, flags) :
lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue);
}
try {
const value = bloomHash();
@ -429,32 +433,6 @@ export function getOrCreateInjectable<T>(
leaveDI();
}
} else if (typeof bloomHash === 'number') {
// This is a value used to identify __NG_ELEMENT_ID__
// `-1` is a special value used to identify `Injector` types in NodeInjector
// This is a workaround for the fact that if the `Injector.__NG_ELEMENT_ID__`
// would have a factory function (such as `ElementRef`) it would cause Ivy
// to be pulled into the ViewEngine, because they both share `Injector` type.
// This should be refactored to follow `ElementRef` pattern once ViewEngine is
// removed
if (bloomHash === -1) {
if (!enterDI(lView, tNode, flags)) {
// Failed to enter DI, try module injector instead. If a token is injected with the @Host
// flag, the module injector is not searched for that token in Ivy.
return (flags & InjectFlags.Host) ?
notFoundValueOrThrow<T>(notFoundValue, token, flags) :
lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue);
}
try {
// Retrieving current `TNode` and `LView` from the state (rather than using `tNode` and
// `lView`), because entering DI (by calling `enterDI`) may cause these values to change
// (in case `@SkipSelf` flag is present).
return new NodeInjector(getCurrentTNode()! as TDirectiveHostNode, getLView()) as any;
} finally {
leaveDI();
}
}
// If the token has a bloom hash, then it is a token which could be in NodeInjector.
// A reference to the previous injector TView that was found while climbing the element
// injector tree. This is used to know if viewProviders can be accessed on the current
// injector.
@ -525,6 +503,10 @@ export function getOrCreateInjectable<T>(
const NOT_FOUND = {};
export function createNodeInjector(): Injector {
return new NodeInjector(getCurrentTNode()! as TDirectiveHostNode, getLView()) as any;
}
function searchTokensOnInjector<T>(
injectorIndex: number, lView: LView, token: Type<T>|InjectionToken<T>,
previousTView: TView|null, flags: InjectFlags, hostTElementNode: TNode|null) {
@ -674,7 +656,17 @@ export function bloomHashBitOrFactory(token: Type<any>|InjectionToken<any>|strin
// First check with `hasOwnProperty` so we don't get an inherited ID.
token.hasOwnProperty(NG_ELEMENT_ID) ? (token as any)[NG_ELEMENT_ID] : undefined;
// Negative token IDs are used for special objects such as `Injector`
return (typeof tokenId === 'number' && tokenId > 0) ? tokenId & BLOOM_MASK : tokenId;
if (typeof tokenId === 'number') {
if (tokenId >= 0) {
return tokenId & BLOOM_MASK;
} else {
ngDevMode &&
assertEqual(tokenId, InjectorMarkers.Injector, 'Expecting to get Special Injector Id');
return createNodeInjector;
}
} else {
return tokenId;
}
}
export function bloomHasToken(bloomHash: number, injectorIndex: number, injectorView: LView|TData) {

View File

@ -6,7 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {InjectFlags, InjectionToken, resolveForwardRef} from '../../di';
import {assertInjectImplementationNot, ɵɵinject} from '../../di/injector_compatibility';
import {assertInjectImplementationNotEqual} from '../../di/inject_switch';
import {ɵɵinject} from '../../di/injector_compatibility';
import {Type} from '../../interface/type';
import {getOrCreateInjectable, injectAttributeImpl} from '../di';
import {TDirectiveHostNode} from '../interfaces/node';
@ -45,7 +46,7 @@ export function ɵɵdirectiveInject<T>(
// if inject utilities are used before bootstrapping.
if (lView === null) {
// Verify that we will not get into infinite loop.
ngDevMode && assertInjectImplementationNot(ɵɵdirectiveInject);
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
return ɵɵinject(token, flags);
}
const tNode = getCurrentTNode();

View File

@ -7,7 +7,7 @@
*/
import {Injector} from '../di/injector';
import {INJECTOR} from '../di/injector_compatibility';
import {INJECTOR} from '../di/injector_token';
import {InjectFlags} from '../di/interface/injector';
import {createInjectorWithoutInjectorInstances, R3Injector} from '../di/r3_injector';
import {Type} from '../interface/type';

View File

@ -8,8 +8,7 @@
import {WrappedValue} from '../change_detection/change_detection_util';
import {PipeTransform} from '../change_detection/pipe_transform';
import {setInjectImplementation} from '../di/injector_compatibility';
import {setInjectImplementation} from '../di/inject_switch';
import {getFactoryDef} from './definition';
import {setIncludeViewProviders} from './di';
import {RuntimeError, RuntimeErrorCode} from './error_code';

View File

@ -8,7 +8,8 @@
import {resolveForwardRef} from '../di/forward_ref';
import {Injector} from '../di/injector';
import {INJECTOR, setCurrentInjector} from '../di/injector_compatibility';
import {setCurrentInjector} from '../di/injector_compatibility';
import {INJECTOR} from '../di/injector_token';
import {getInjectableDef, ɵɵInjectableDef} from '../di/interface/defs';
import {INJECTOR_SCOPE} from '../di/scope';
import {NgModuleRef} from '../linker/ng_module_factory';

View File

@ -833,6 +833,9 @@
{
"name": "createLView"
},
{
"name": "createNodeInjector"
},
{
"name": "createPlatformFactory"
},

View File

@ -1073,6 +1073,9 @@
{
"name": "createNewSegmentGroup"
},
{
"name": "createNodeInjector"
},
{
"name": "createPlatformFactory"
},

View File

@ -272,6 +272,9 @@
{
"name": "createLView"
},
{
"name": "createNodeInjector"
},
{
"name": "createTView"
},

View File

@ -9,7 +9,7 @@
import {NgModuleRef, ɵINJECTOR_SCOPE as INJECTOR_SCOPE} from '@angular/core';
import {inject, InjectFlags} from '@angular/core/src/di';
import {Injector} from '@angular/core/src/di/injector';
import {INJECTOR} from '@angular/core/src/di/injector_compatibility';
import {INJECTOR} from '@angular/core/src/di/injector_token';
import {ɵɵdefineInjectable, ɵɵInjectableDef} from '@angular/core/src/di/interface/defs';
import {NgModuleDefinition, NgModuleProviderDef, NodeFlags} from '@angular/core/src/view';
import {moduleDef} from '@angular/core/src/view/ng_module';