fix(ivy): don't accidently read the inherited definition (#25736)
Create getter methods `getXXXDef` for each definition which uses `hasOwnProperty` to verify that we don't accidently read form the parent class. Fixes: #24011 Fixes: #25026 PR Close #25736
This commit is contained in:
parent
a9099e8f70
commit
d5bd86ae5d
|
@ -143,6 +143,23 @@ describe('ngInjectableDef Bazel Integration', () => {
|
||||||
expect(TestBed.get(Service).value).toEqual(true);
|
expect(TestBed.get(Service).value).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not override existing ngInjectableDef in case of inheritance', () => {
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
useValue: new ParentService(false),
|
||||||
|
})
|
||||||
|
class ParentService {
|
||||||
|
constructor(public value: boolean) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChildServices exteds ParentService but does not have @Injectable
|
||||||
|
class ChildService extends ParentService {}
|
||||||
|
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
// We are asserting that system throws an error, rather than taking the inherited annotation.
|
||||||
|
expect(() => TestBed.get(ChildService).value).toThrowError(/ChildService/);
|
||||||
|
});
|
||||||
|
|
||||||
it('NgModule injector understands requests for INJECTABLE', () => {
|
it('NgModule injector understands requests for INJECTABLE', () => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [{provide: 'foo', useValue: 'bar'}],
|
providers: [{provide: 'foo', useValue: 'bar'}],
|
||||||
|
|
|
@ -13,7 +13,7 @@ export {devModeEqual as ɵdevModeEqual} from './change_detection/change_detectio
|
||||||
export {isListLikeIterable as ɵisListLikeIterable} from './change_detection/change_detection_util';
|
export {isListLikeIterable as ɵisListLikeIterable} from './change_detection/change_detection_util';
|
||||||
export {ChangeDetectorStatus as ɵChangeDetectorStatus, isDefaultChangeDetectionStrategy as ɵisDefaultChangeDetectionStrategy} from './change_detection/constants';
|
export {ChangeDetectorStatus as ɵChangeDetectorStatus, isDefaultChangeDetectionStrategy as ɵisDefaultChangeDetectionStrategy} from './change_detection/constants';
|
||||||
export {Console as ɵConsole} from './console';
|
export {Console as ɵConsole} from './console';
|
||||||
export {InjectableDef as ɵInjectableDef, InjectorDef as ɵInjectorDef} from './di/defs';
|
export {InjectableDef as ɵInjectableDef, InjectorDef as ɵInjectorDef, getInjectableDef as ɵgetInjectableDef} from './di/defs';
|
||||||
export {inject as ɵinject, setCurrentInjector as ɵsetCurrentInjector} from './di/injector';
|
export {inject as ɵinject, setCurrentInjector as ɵsetCurrentInjector} from './di/injector';
|
||||||
export {APP_ROOT as ɵAPP_ROOT} from './di/scope';
|
export {APP_ROOT as ɵAPP_ROOT} from './di/scope';
|
||||||
export {ivyEnabled as ɵivyEnabled} from './ivy_switch';
|
export {ivyEnabled as ɵivyEnabled} from './ivy_switch';
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {NG_INJECTABLE_DEF, NG_INJECTOR_DEF} from '../render3/fields';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
|
||||||
import {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, StaticClassProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './provider';
|
import {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, StaticClassProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './provider';
|
||||||
|
@ -160,3 +161,21 @@ export function defineInjector(options: {factory: () => any, providers?: any[],
|
||||||
factory: options.factory, providers: options.providers || [], imports: options.imports || [],
|
factory: options.factory, providers: options.providers || [], imports: options.imports || [],
|
||||||
} as InjectorDef<any>) as never;
|
} as InjectorDef<any>) as never;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the `ngInjectableDef` type in a way which is immune to accidentally reading inherited value.
|
||||||
|
*
|
||||||
|
* @param type type which may have `ngInjectableDef`
|
||||||
|
*/
|
||||||
|
export function getInjectableDef<T>(type: any): InjectableDef<T>|null {
|
||||||
|
return type.hasOwnProperty(NG_INJECTABLE_DEF) ? (type as any)[NG_INJECTABLE_DEF] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the `ngInjectorDef` type in a way which is immune to accidentally reading inherited value.
|
||||||
|
*
|
||||||
|
* @param type type which may have `ngInjectorDef`
|
||||||
|
*/
|
||||||
|
export function getInjectorDef<T>(type: any): InjectorDef<T>|null {
|
||||||
|
return type.hasOwnProperty(NG_INJECTOR_DEF) ? (type as any)[NG_INJECTOR_DEF] : null;
|
||||||
|
}
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
import {stringify} from '../util';
|
import {stringify} from '../util';
|
||||||
|
import {getClosureSafeProperty} from '../util/property';
|
||||||
|
|
||||||
import {InjectableDef, defineInjectable} from './defs';
|
import {InjectableDef, defineInjectable, getInjectableDef} from './defs';
|
||||||
import {resolveForwardRef} from './forward_ref';
|
import {resolveForwardRef} from './forward_ref';
|
||||||
import {InjectionToken} from './injection_token';
|
import {InjectionToken} from './injection_token';
|
||||||
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
||||||
|
@ -115,9 +116,8 @@ const CIRCULAR = IDENT;
|
||||||
const MULTI_PROVIDER_FN = function(): any[] {
|
const MULTI_PROVIDER_FN = function(): any[] {
|
||||||
return Array.prototype.slice.call(arguments);
|
return Array.prototype.slice.call(arguments);
|
||||||
};
|
};
|
||||||
const GET_PROPERTY_NAME = {} as any;
|
|
||||||
export const USE_VALUE =
|
export const USE_VALUE =
|
||||||
getClosureSafeProperty<ValueProvider>({provide: String, useValue: GET_PROPERTY_NAME});
|
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
|
||||||
const NG_TOKEN_PATH = 'ngTokenPath';
|
const NG_TOKEN_PATH = 'ngTokenPath';
|
||||||
const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
|
const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
|
||||||
const enum OptionFlags {
|
const enum OptionFlags {
|
||||||
|
@ -397,15 +397,6 @@ function staticError(text: string, obj: any): Error {
|
||||||
return new Error(formatError(text, obj));
|
return new Error(formatError(text, obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClosureSafeProperty<T>(objWithPropertyToExtract: T): string {
|
|
||||||
for (let key in objWithPropertyToExtract) {
|
|
||||||
if (objWithPropertyToExtract[key] === GET_PROPERTY_NAME) {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw Error('!prop');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection flags for DI.
|
* Injection flags for DI.
|
||||||
*/
|
*/
|
||||||
|
@ -462,7 +453,7 @@ export function inject<T>(token: Type<T>| InjectionToken<T>, flags = InjectFlags
|
||||||
if (_currentInjector === undefined) {
|
if (_currentInjector === undefined) {
|
||||||
throw new Error(`inject() must be called from an injection context`);
|
throw new Error(`inject() must be called from an injection context`);
|
||||||
} else if (_currentInjector === null) {
|
} else if (_currentInjector === null) {
|
||||||
const injectableDef: InjectableDef<T> = (token as any).ngInjectableDef;
|
const injectableDef: InjectableDef<T>|null = getInjectableDef(token);
|
||||||
if (injectableDef && injectableDef.providedIn == 'root') {
|
if (injectableDef && injectableDef.providedIn == 'root') {
|
||||||
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
|
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
|
||||||
injectableDef.value;
|
injectableDef.value;
|
||||||
|
|
|
@ -10,9 +10,9 @@ import {OnDestroy} from '../metadata/lifecycle_hooks';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
import {stringify} from '../util';
|
import {stringify} from '../util';
|
||||||
|
|
||||||
import {InjectableDef, InjectableType, InjectorDef, InjectorType, InjectorTypeWithProviders} from './defs';
|
import {InjectableDef, InjectableType, InjectorType, InjectorTypeWithProviders, getInjectableDef, getInjectorDef} from './defs';
|
||||||
import {resolveForwardRef} from './forward_ref';
|
import {resolveForwardRef} from './forward_ref';
|
||||||
import {InjectableDefToken, InjectionToken} from './injection_token';
|
import {InjectionToken} from './injection_token';
|
||||||
import {INJECTOR, InjectFlags, Injector, NullInjector, THROW_IF_NOT_FOUND, USE_VALUE, inject, injectArgs, setCurrentInjector} from './injector';
|
import {INJECTOR, InjectFlags, Injector, NullInjector, THROW_IF_NOT_FOUND, USE_VALUE, inject, injectArgs, setCurrentInjector} from './injector';
|
||||||
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, Provider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './provider';
|
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, Provider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './provider';
|
||||||
import {APP_ROOT} from './scope';
|
import {APP_ROOT} from './scope';
|
||||||
|
@ -161,10 +161,8 @@ export class R3Injector {
|
||||||
if (record === undefined) {
|
if (record === undefined) {
|
||||||
// No record, but maybe the token is scoped to this injector. Look for an ngInjectableDef
|
// No record, but maybe the token is scoped to this injector. Look for an ngInjectableDef
|
||||||
// with a scope matching this injector.
|
// with a scope matching this injector.
|
||||||
const def = couldBeInjectableType(token) &&
|
const def = couldBeInjectableType(token) && getInjectableDef(token);
|
||||||
(token as InjectableType<any>| InjectableDefToken<any>).ngInjectableDef ||
|
if (def && this.injectableDefInScope(def)) {
|
||||||
undefined;
|
|
||||||
if (def !== undefined && this.injectableDefInScope(def)) {
|
|
||||||
// Found an ngInjectableDef and it's scoped to this injector. Pretend as if it was here
|
// Found an ngInjectableDef and it's scoped to this injector. Pretend as if it was here
|
||||||
// all along.
|
// all along.
|
||||||
record = injectableDefRecord(token);
|
record = injectableDefRecord(token);
|
||||||
|
@ -207,7 +205,7 @@ export class R3Injector {
|
||||||
// read, so care is taken to only do the read once.
|
// read, so care is taken to only do the read once.
|
||||||
|
|
||||||
// First attempt to read the ngInjectorDef.
|
// First attempt to read the ngInjectorDef.
|
||||||
let def = (defOrWrappedDef as InjectorType<any>).ngInjectorDef as(InjectorDef<any>| undefined);
|
let def = getInjectorDef(defOrWrappedDef);
|
||||||
|
|
||||||
// If that's not present, then attempt to read ngModule from the InjectorDefTypeWithProviders.
|
// If that's not present, then attempt to read ngModule from the InjectorDefTypeWithProviders.
|
||||||
const ngModule =
|
const ngModule =
|
||||||
|
@ -228,7 +226,7 @@ export class R3Injector {
|
||||||
// Finally, if defOrWrappedType was an `InjectorDefTypeWithProviders`, then the actual
|
// Finally, if defOrWrappedType was an `InjectorDefTypeWithProviders`, then the actual
|
||||||
// `InjectorDef` is on its `ngModule`.
|
// `InjectorDef` is on its `ngModule`.
|
||||||
if (ngModule !== undefined) {
|
if (ngModule !== undefined) {
|
||||||
def = ngModule.ngInjectorDef;
|
def = getInjectorDef(ngModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no definition was found, it might be from exports. Remove it.
|
// If no definition was found, it might be from exports. Remove it.
|
||||||
|
@ -331,8 +329,8 @@ export class R3Injector {
|
||||||
}
|
}
|
||||||
|
|
||||||
function injectableDefRecord(token: Type<any>| InjectionToken<any>): Record<any> {
|
function injectableDefRecord(token: Type<any>| InjectionToken<any>): Record<any> {
|
||||||
const def = (token as InjectableType<any>).ngInjectableDef as InjectableDef<any>;
|
const injectableDef = getInjectableDef(token as InjectableType<any>);
|
||||||
if (def === undefined) {
|
if (injectableDef === null) {
|
||||||
if (token instanceof InjectionToken) {
|
if (token instanceof InjectionToken) {
|
||||||
throw new Error(`Token ${stringify(token)} is missing an ngInjectableDef definition.`);
|
throw new Error(`Token ${stringify(token)} is missing an ngInjectableDef definition.`);
|
||||||
}
|
}
|
||||||
|
@ -340,7 +338,7 @@ function injectableDefRecord(token: Type<any>| InjectionToken<any>): Record<any>
|
||||||
// no-args constructor.
|
// no-args constructor.
|
||||||
return makeRecord(() => new (token as Type<any>)());
|
return makeRecord(() => new (token as Type<any>)());
|
||||||
}
|
}
|
||||||
return makeRecord(def.factory);
|
return makeRecord(injectableDef.factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
function providerToRecord(provider: SingleProvider): Record<any> {
|
function providerToRecord(provider: SingleProvider): Record<any> {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {InjectableType, InjectorType, defineInjectable, defineInjector} from './di/defs';
|
import {InjectableType, InjectorType, defineInjectable, defineInjector, getInjectableDef} from './di/defs';
|
||||||
import {InjectableProvider} from './di/injectable';
|
import {InjectableProvider} from './di/injectable';
|
||||||
import {inject, injectArgs} from './di/injector';
|
import {inject, injectArgs} from './di/injector';
|
||||||
import {ClassSansProvider, ConstructorSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './di/provider';
|
import {ClassSansProvider, ConstructorSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from './di/provider';
|
||||||
|
@ -59,9 +59,8 @@ function preR3NgModuleCompile(moduleType: InjectorType<any>, metadata: NgModule)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const GET_PROPERTY_NAME = {} as any;
|
const USE_VALUE =
|
||||||
const USE_VALUE = getClosureSafeProperty<ValueProvider>(
|
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
|
||||||
{provide: String, useValue: GET_PROPERTY_NAME}, GET_PROPERTY_NAME);
|
|
||||||
const EMPTY_ARRAY: any[] = [];
|
const EMPTY_ARRAY: any[] = [];
|
||||||
|
|
||||||
function convertInjectableProviderToFactory(type: Type<any>, provider?: InjectableProvider): () =>
|
function convertInjectableProviderToFactory(type: Type<any>, provider?: InjectableProvider): () =>
|
||||||
|
@ -106,7 +105,7 @@ function convertInjectableProviderToFactory(type: Type<any>, provider?: Injectab
|
||||||
function preR3InjectableCompile(
|
function preR3InjectableCompile(
|
||||||
injectableType: InjectableType<any>,
|
injectableType: InjectableType<any>,
|
||||||
options: {providedIn?: Type<any>| 'root' | null} & InjectableProvider): void {
|
options: {providedIn?: Type<any>| 'root' | null} & InjectableProvider): void {
|
||||||
if (options && options.providedIn !== undefined && injectableType.ngInjectableDef === undefined) {
|
if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) {
|
||||||
injectableType.ngInjectableDef = defineInjectable({
|
injectableType.ngInjectableDef = defineInjectable({
|
||||||
providedIn: options.providedIn,
|
providedIn: options.providedIn,
|
||||||
factory: convertInjectableProviderToFactory(injectableType, options),
|
factory: convertInjectableProviderToFactory(injectableType, options),
|
||||||
|
|
|
@ -9,12 +9,15 @@
|
||||||
import {ChangeDetectionStrategy} from '../change_detection/constants';
|
import {ChangeDetectionStrategy} from '../change_detection/constants';
|
||||||
import {Provider} from '../di';
|
import {Provider} from '../di';
|
||||||
import {R3_COMPILE_COMPONENT, R3_COMPILE_DIRECTIVE, R3_COMPILE_PIPE} from '../ivy_switch';
|
import {R3_COMPILE_COMPONENT, R3_COMPILE_DIRECTIVE, R3_COMPILE_PIPE} from '../ivy_switch';
|
||||||
|
import {NG_BASE_DEF} from '../render3/fields';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
import {TypeDecorator, makeDecorator, makePropDecorator} from '../util/decorators';
|
import {TypeDecorator, makeDecorator, makePropDecorator} from '../util/decorators';
|
||||||
import {fillProperties} from '../util/property';
|
import {fillProperties} from '../util/property';
|
||||||
|
|
||||||
import {ViewEncapsulation} from './view';
|
import {ViewEncapsulation} from './view';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type of the Directive decorator / constructor function.
|
* Type of the Directive decorator / constructor function.
|
||||||
*/
|
*/
|
||||||
|
@ -778,11 +781,6 @@ const initializeBaseDef = (target: any): void => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to get the minified alias of ngBaseDef
|
|
||||||
*/
|
|
||||||
const NG_BASE_DEF = Object.keys({ngBaseDef: true})[0];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the work of creating the `ngBaseDef` property for the @Input and @Output decorators.
|
* Does the work of creating the `ngBaseDef` property for the @Input and @Output decorators.
|
||||||
* @param key "inputs" or "outputs"
|
* @param key "inputs" or "outputs"
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {getComponentDef, getNgModuleDef} from './definition';
|
||||||
|
|
||||||
// The functions in this file verify that the assumptions we are making
|
// The functions in this file verify that the assumptions we are making
|
||||||
// about state in an instruction are correct before implementing any logic.
|
// about state in an instruction are correct before implementing any logic.
|
||||||
// They are meant only to be called in dev mode as sanity checks.
|
// They are meant only to be called in dev mode as sanity checks.
|
||||||
|
@ -62,7 +64,7 @@ export function assertComponentType(
|
||||||
actual: any,
|
actual: any,
|
||||||
msg: string =
|
msg: string =
|
||||||
'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.') {
|
'Type passed in is not ComponentType, it does not have \'ngComponentDef\' property.') {
|
||||||
if (!actual.ngComponentDef) {
|
if (!getComponentDef(actual)) {
|
||||||
throwError(msg);
|
throwError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +73,7 @@ export function assertNgModuleType(
|
||||||
actual: any,
|
actual: any,
|
||||||
msg: string =
|
msg: string =
|
||||||
'Type passed in is not NgModuleType, it does not have \'ngModuleDef\' property.') {
|
'Type passed in is not NgModuleType, it does not have \'ngModuleDef\' property.') {
|
||||||
if (!actual.ngModuleDef) {
|
if (!getNgModuleDef(actual)) {
|
||||||
throwError(msg);
|
throwError(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {LElementNode} from './interfaces/node';
|
||||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||||
import {LViewData, LViewFlags, RootContext, BINDING_INDEX, INJECTOR, CONTEXT, TVIEW} from './interfaces/view';
|
import {LViewData, LViewFlags, RootContext, BINDING_INDEX, INJECTOR, CONTEXT, TVIEW} from './interfaces/view';
|
||||||
import {stringify} from './util';
|
import {stringify} from './util';
|
||||||
|
import {getComponentDef} from './definition';
|
||||||
|
|
||||||
|
|
||||||
/** Options that control how the component should be bootstrapped. */
|
/** Options that control how the component should be bootstrapped. */
|
||||||
|
@ -96,8 +97,7 @@ export function renderComponent<T>(
|
||||||
ngDevMode && assertComponentType(componentType);
|
ngDevMode && assertComponentType(componentType);
|
||||||
const rendererFactory = opts.rendererFactory || domRendererFactory3;
|
const rendererFactory = opts.rendererFactory || domRendererFactory3;
|
||||||
const sanitizer = opts.sanitizer || null;
|
const sanitizer = opts.sanitizer || null;
|
||||||
const componentDef =
|
const componentDef = getComponentDef<T>(componentType) !;
|
||||||
(componentType as ComponentType<T>).ngComponentDef as ComponentDefInternal<T>;
|
|
||||||
if (componentDef.type != componentType) componentDef.type = componentType;
|
if (componentDef.type != componentType) componentDef.type = componentType;
|
||||||
|
|
||||||
// The first index of the first selector is the tag name.
|
// The first index of the first selector is the tag name.
|
||||||
|
|
|
@ -18,6 +18,7 @@ import {Type} from '../type';
|
||||||
|
|
||||||
import {assertComponentType, assertDefined} from './assert';
|
import {assertComponentType, assertDefined} from './assert';
|
||||||
import {LifecycleHooksFeature, createRootContext} from './component';
|
import {LifecycleHooksFeature, createRootContext} from './component';
|
||||||
|
import {getComponentDef} from './definition';
|
||||||
import {adjustBlueprintForNewNode, baseDirectiveCreate, createLNode, createLViewData, createTView, elementCreate, enterView, hostElement, initChangeDetectorIfExisting, locateHostElement, queueHostBindingForCheck, renderEmbeddedTemplate, setHostBindings} from './instructions';
|
import {adjustBlueprintForNewNode, baseDirectiveCreate, createLNode, createLViewData, createTView, elementCreate, enterView, hostElement, initChangeDetectorIfExisting, locateHostElement, queueHostBindingForCheck, renderEmbeddedTemplate, setHostBindings} from './instructions';
|
||||||
import {ComponentDefInternal, ComponentType, RenderFlags} from './interfaces/definition';
|
import {ComponentDefInternal, ComponentType, RenderFlags} from './interfaces/definition';
|
||||||
import {LElementNode, TNode, TNodeType} from './interfaces/node';
|
import {LElementNode, TNode, TNodeType} from './interfaces/node';
|
||||||
|
@ -28,7 +29,7 @@ import {RootViewRef, ViewRef} from './view_ref';
|
||||||
export class ComponentFactoryResolver extends viewEngine_ComponentFactoryResolver {
|
export class ComponentFactoryResolver extends viewEngine_ComponentFactoryResolver {
|
||||||
resolveComponentFactory<T>(component: Type<T>): viewEngine_ComponentFactory<T> {
|
resolveComponentFactory<T>(component: Type<T>): viewEngine_ComponentFactory<T> {
|
||||||
ngDevMode && assertComponentType(component);
|
ngDevMode && assertComponentType(component);
|
||||||
const componentDef = (component as ComponentType<T>).ngComponentDef;
|
const componentDef = getComponentDef(component) !;
|
||||||
return new ComponentFactory(componentDef);
|
return new ComponentFactory(componentDef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {NgModuleDef, NgModuleDefInternal} from '../metadata/ng_module';
|
||||||
import {ViewEncapsulation} from '../metadata/view';
|
import {ViewEncapsulation} from '../metadata/view';
|
||||||
import {Type} from '../type';
|
import {Type} from '../type';
|
||||||
|
|
||||||
|
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields';
|
||||||
import {BaseDef, ComponentDefFeature, ComponentDefInternal, ComponentQuery, ComponentTemplate, ComponentType, DirectiveDefFeature, DirectiveDefInternal, DirectiveType, DirectiveTypesOrFactory, PipeDefInternal, PipeType, PipeTypesOrFactory} from './interfaces/definition';
|
import {BaseDef, ComponentDefFeature, ComponentDefInternal, ComponentQuery, ComponentTemplate, ComponentType, DirectiveDefFeature, DirectiveDefInternal, DirectiveType, DirectiveTypesOrFactory, PipeDefInternal, PipeType, PipeTypesOrFactory} from './interfaces/definition';
|
||||||
import {CssSelectorList, SelectorFlags} from './interfaces/projection';
|
import {CssSelectorList, SelectorFlags} from './interfaces/projection';
|
||||||
|
|
||||||
|
@ -328,19 +329,19 @@ export function defineComponent<T>(componentDefinition: {
|
||||||
|
|
||||||
export function extractDirectiveDef(type: DirectiveType<any>& ComponentType<any>):
|
export function extractDirectiveDef(type: DirectiveType<any>& ComponentType<any>):
|
||||||
DirectiveDefInternal<any>|ComponentDefInternal<any> {
|
DirectiveDefInternal<any>|ComponentDefInternal<any> {
|
||||||
const def = type.ngComponentDef || type.ngDirectiveDef;
|
const def = getComponentDef(type) || getDirectiveDef(type);
|
||||||
if (ngDevMode && !def) {
|
if (ngDevMode && !def) {
|
||||||
throw new Error(`'${type.name}' is neither 'ComponentType' or 'DirectiveType'.`);
|
throw new Error(`'${type.name}' is neither 'ComponentType' or 'DirectiveType'.`);
|
||||||
}
|
}
|
||||||
return def;
|
return def !;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractPipeDef(type: PipeType<any>): PipeDefInternal<any> {
|
export function extractPipeDef(type: PipeType<any>): PipeDefInternal<any> {
|
||||||
const def = type.ngPipeDef;
|
const def = getPipeDef(type);
|
||||||
if (ngDevMode && !def) {
|
if (ngDevMode && !def) {
|
||||||
throw new Error(`'${type.name}' is not a 'PipeType'.`);
|
throw new Error(`'${type.name}' is not a 'PipeType'.`);
|
||||||
}
|
}
|
||||||
return def;
|
return def !;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T, any, any, any>>): never {
|
export function defineNgModule<T>(def: {type: T} & Partial<NgModuleDef<T, any, any, any>>): never {
|
||||||
|
@ -662,3 +663,25 @@ export function definePipe<T>(pipeDef: {
|
||||||
onDestroy: pipeDef.type.prototype.ngOnDestroy || null
|
onDestroy: pipeDef.type.prototype.ngOnDestroy || null
|
||||||
}) as never;
|
}) as never;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following getter methods retrieve the definition form the type. Currently the retrieval
|
||||||
|
* honors inheritance, but in the future we may change the rule to require that definitions are
|
||||||
|
* explicit. This would require some sort of migration strategy.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function getComponentDef<T>(type: any): ComponentDefInternal<T>|null {
|
||||||
|
return (type as any)[NG_COMPONENT_DEF] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDirectiveDef<T>(type: any): DirectiveDefInternal<T>|null {
|
||||||
|
return (type as any)[NG_DIRECTIVE_DEF] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPipeDef<T>(type: any): PipeDefInternal<T>|null {
|
||||||
|
return (type as any)[NG_PIPE_DEF] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getNgModuleDef<T>(type: any): NgModuleDefInternal<T>|null {
|
||||||
|
return (type as any)[NG_MODULE_DEF] || null;
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
// 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 {getInjectableDef, getInjectorDef} from '../di/defs';
|
||||||
import {InjectionToken} from '../di/injection_token';
|
import {InjectionToken} from '../di/injection_token';
|
||||||
import {InjectFlags, Injector, NullInjector, inject, setCurrentInjector} from '../di/injector';
|
import {InjectFlags, Injector, NullInjector, inject, setCurrentInjector} 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';
|
||||||
|
@ -24,6 +25,7 @@ import {Type} from '../type';
|
||||||
|
|
||||||
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
|
import {assertDefined, assertGreaterThan, assertLessThan} from './assert';
|
||||||
import {ComponentFactoryResolver} from './component_ref';
|
import {ComponentFactoryResolver} from './component_ref';
|
||||||
|
import {getComponentDef, getDirectiveDef, getPipeDef} from './definition';
|
||||||
import {addToViewTree, assertPreviousIsParent, createEmbeddedViewNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentNode, getPreviousOrParentTNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
|
import {addToViewTree, assertPreviousIsParent, createEmbeddedViewNode, createLContainer, createLNodeObject, createTNode, getPreviousOrParentNode, getPreviousOrParentTNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
|
||||||
import {VIEWS} from './interfaces/container';
|
import {VIEWS} from './interfaces/container';
|
||||||
import {DirectiveDefInternal, RenderFlags} from './interfaces/definition';
|
import {DirectiveDefInternal, RenderFlags} from './interfaces/definition';
|
||||||
|
@ -797,9 +799,9 @@ export function getOrCreateTemplateRef<T>(di: LInjector): viewEngine_TemplateRef
|
||||||
|
|
||||||
export function getFactoryOf<T>(type: Type<any>): ((type?: Type<T>) => T)|null {
|
export function getFactoryOf<T>(type: Type<any>): ((type?: Type<T>) => T)|null {
|
||||||
const typeAny = type as any;
|
const typeAny = type as any;
|
||||||
const def = typeAny.ngComponentDef || typeAny.ngDirectiveDef || typeAny.ngPipeDef ||
|
const def = getComponentDef<T>(typeAny) || getDirectiveDef<T>(typeAny) ||
|
||||||
typeAny.ngInjectableDef || typeAny.ngInjectorDef;
|
getPipeDef<T>(typeAny) || getInjectableDef<T>(typeAny) || getInjectorDef<T>(typeAny);
|
||||||
if (def === undefined || def.factory === undefined) {
|
if (!def || def.factory === undefined) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return def.factory;
|
return def.factory;
|
||||||
|
|
|
@ -39,11 +39,13 @@ export function InheritDefinitionFeature(
|
||||||
while (superType) {
|
while (superType) {
|
||||||
let superDef: DirectiveDefInternal<any>|ComponentDefInternal<any>|undefined = undefined;
|
let superDef: DirectiveDefInternal<any>|ComponentDefInternal<any>|undefined = undefined;
|
||||||
if (isComponentDef(definition)) {
|
if (isComponentDef(definition)) {
|
||||||
|
// Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
|
||||||
superDef = superType.ngComponentDef || superType.ngDirectiveDef;
|
superDef = superType.ngComponentDef || superType.ngDirectiveDef;
|
||||||
} else {
|
} else {
|
||||||
if (superType.ngComponentDef) {
|
if (superType.ngComponentDef) {
|
||||||
throw new Error('Directives cannot inherit Components');
|
throw new Error('Directives cannot inherit Components');
|
||||||
}
|
}
|
||||||
|
// Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
|
||||||
superDef = superType.ngDirectiveDef;
|
superDef = superType.ngDirectiveDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,12 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {getClosureSafeProperty} from '../../util/property';
|
import {getClosureSafeProperty} from '../util/property';
|
||||||
|
|
||||||
const TARGET = {} as any;
|
export const NG_COMPONENT_DEF = getClosureSafeProperty({ngComponentDef: getClosureSafeProperty});
|
||||||
|
export const NG_DIRECTIVE_DEF = getClosureSafeProperty({ngDirectiveDef: getClosureSafeProperty});
|
||||||
export const NG_COMPONENT_DEF = getClosureSafeProperty({ngComponentDef: TARGET}, TARGET);
|
export const NG_INJECTABLE_DEF = getClosureSafeProperty({ngInjectableDef: getClosureSafeProperty});
|
||||||
export const NG_DIRECTIVE_DEF = getClosureSafeProperty({ngDirectiveDef: TARGET}, TARGET);
|
export const NG_INJECTOR_DEF = getClosureSafeProperty({ngInjectorDef: getClosureSafeProperty});
|
||||||
export const NG_INJECTABLE_DEF = getClosureSafeProperty({ngInjectableDef: TARGET}, TARGET);
|
export const NG_PIPE_DEF = getClosureSafeProperty({ngPipeDef: getClosureSafeProperty});
|
||||||
export const NG_INJECTOR_DEF = getClosureSafeProperty({ngInjectorDef: TARGET}, TARGET);
|
export const NG_MODULE_DEF = getClosureSafeProperty({ngModuleDef: getClosureSafeProperty});
|
||||||
export const NG_PIPE_DEF = getClosureSafeProperty({ngPipeDef: TARGET}, TARGET);
|
export const NG_BASE_DEF = getClosureSafeProperty({ngBaseDef: getClosureSafeProperty});
|
||||||
export const NG_MODULE_DEF = getClosureSafeProperty({ngModuleDef: TARGET}, TARGET);
|
|
|
@ -13,9 +13,9 @@ import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from
|
||||||
import {ViewEncapsulation} from '../../metadata/view';
|
import {ViewEncapsulation} from '../../metadata/view';
|
||||||
import {Type} from '../../type';
|
import {Type} from '../../type';
|
||||||
import {stringify} from '../../util';
|
import {stringify} from '../../util';
|
||||||
|
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from '../fields';
|
||||||
|
|
||||||
import {angularCoreEnv} from './environment';
|
import {angularCoreEnv} from './environment';
|
||||||
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from './fields';
|
|
||||||
import {patchComponentDefWithScope, transitiveScopesFor} from './module';
|
import {patchComponentDefWithScope, transitiveScopesFor} from './module';
|
||||||
import {getReflect, reflectDependencies} from './util';
|
import {getReflect, reflectDependencies} from './util';
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@ import {Injectable} from '../../di/injectable';
|
||||||
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
|
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
|
||||||
import {Type} from '../../type';
|
import {Type} from '../../type';
|
||||||
import {getClosureSafeProperty} from '../../util/property';
|
import {getClosureSafeProperty} from '../../util/property';
|
||||||
|
import {NG_INJECTABLE_DEF} from '../fields';
|
||||||
|
|
||||||
import {angularCoreEnv} from './environment';
|
import {angularCoreEnv} from './environment';
|
||||||
import {NG_INJECTABLE_DEF} from './fields';
|
|
||||||
import {convertDependencies, reflectDependencies} from './util';
|
import {convertDependencies, reflectDependencies} from './util';
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,9 +106,8 @@ function isUseClassProvider(meta: Injectable): meta is UseClassProvider {
|
||||||
return (meta as UseClassProvider).useClass !== undefined;
|
return (meta as UseClassProvider).useClass !== undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const GET_PROPERTY_NAME = {} as any;
|
const USE_VALUE =
|
||||||
const USE_VALUE = getClosureSafeProperty<ValueProvider>(
|
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
|
||||||
{provide: String, useValue: GET_PROPERTY_NAME}, GET_PROPERTY_NAME);
|
|
||||||
|
|
||||||
function isUseValueProvider(meta: Injectable): meta is Injectable&ValueSansProvider {
|
function isUseValueProvider(meta: Injectable): meta is Injectable&ValueSansProvider {
|
||||||
return USE_VALUE in meta;
|
return USE_VALUE in meta;
|
||||||
|
|
|
@ -10,10 +10,11 @@ import {Expression, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, Wrapped
|
||||||
|
|
||||||
import {ModuleWithProviders, NgModule, NgModuleDefInternal, NgModuleTransitiveScopes} from '../../metadata/ng_module';
|
import {ModuleWithProviders, NgModule, NgModuleDefInternal, NgModuleTransitiveScopes} from '../../metadata/ng_module';
|
||||||
import {Type} from '../../type';
|
import {Type} from '../../type';
|
||||||
|
import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../definition';
|
||||||
|
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields';
|
||||||
import {ComponentDefInternal} from '../interfaces/definition';
|
import {ComponentDefInternal} from '../interfaces/definition';
|
||||||
|
|
||||||
import {angularCoreEnv} from './environment';
|
import {angularCoreEnv} from './environment';
|
||||||
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from './fields';
|
|
||||||
import {reflectDependencies} from './util';
|
import {reflectDependencies} from './util';
|
||||||
|
|
||||||
const EMPTY_ARRAY: Type<any>[] = [];
|
const EMPTY_ARRAY: Type<any>[] = [];
|
||||||
|
@ -100,7 +101,7 @@ function setScopeOnDeclaredComponents(moduleType: Type<any>, ngModule: NgModule)
|
||||||
if (declaration.hasOwnProperty(NG_COMPONENT_DEF)) {
|
if (declaration.hasOwnProperty(NG_COMPONENT_DEF)) {
|
||||||
// An `ngComponentDef` field exists - go ahead and patch the component directly.
|
// An `ngComponentDef` field exists - go ahead and patch the component directly.
|
||||||
const component = declaration as Type<any>& {ngComponentDef: ComponentDefInternal<any>};
|
const component = declaration as Type<any>& {ngComponentDef: ComponentDefInternal<any>};
|
||||||
const componentDef = component.ngComponentDef;
|
const componentDef = getComponentDef(component) !;
|
||||||
patchComponentDefWithScope(componentDef, transitiveScopes);
|
patchComponentDefWithScope(componentDef, transitiveScopes);
|
||||||
} else if (
|
} else if (
|
||||||
!declaration.hasOwnProperty(NG_DIRECTIVE_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
|
!declaration.hasOwnProperty(NG_DIRECTIVE_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
|
||||||
|
@ -117,10 +118,10 @@ function setScopeOnDeclaredComponents(moduleType: Type<any>, ngModule: NgModule)
|
||||||
export function patchComponentDefWithScope<C>(
|
export function patchComponentDefWithScope<C>(
|
||||||
componentDef: ComponentDefInternal<C>, transitiveScopes: NgModuleTransitiveScopes) {
|
componentDef: ComponentDefInternal<C>, transitiveScopes: NgModuleTransitiveScopes) {
|
||||||
componentDef.directiveDefs = () => Array.from(transitiveScopes.compilation.directives)
|
componentDef.directiveDefs = () => Array.from(transitiveScopes.compilation.directives)
|
||||||
.map(dir => dir.ngDirectiveDef || dir.ngComponentDef)
|
.map(dir => getDirectiveDef(dir) || getComponentDef(dir) !)
|
||||||
.filter(def => !!def);
|
.filter(def => !!def);
|
||||||
componentDef.pipeDefs = () =>
|
componentDef.pipeDefs = () =>
|
||||||
Array.from(transitiveScopes.compilation.pipes).map(pipe => pipe.ngPipeDef);
|
Array.from(transitiveScopes.compilation.pipes).map(pipe => getPipeDef(pipe) !);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,7 +135,7 @@ export function transitiveScopesFor<T>(moduleType: Type<T>): NgModuleTransitiveS
|
||||||
if (!isNgModule(moduleType)) {
|
if (!isNgModule(moduleType)) {
|
||||||
throw new Error(`${moduleType.name} does not have an ngModuleDef`);
|
throw new Error(`${moduleType.name} does not have an ngModuleDef`);
|
||||||
}
|
}
|
||||||
const def = moduleType.ngModuleDef;
|
const def = getNgModuleDef(moduleType) !;
|
||||||
|
|
||||||
if (def.transitiveCompileScopes !== null) {
|
if (def.transitiveCompileScopes !== null) {
|
||||||
return def.transitiveCompileScopes;
|
return def.transitiveCompileScopes;
|
||||||
|
@ -154,7 +155,7 @@ export function transitiveScopesFor<T>(moduleType: Type<T>): NgModuleTransitiveS
|
||||||
def.declarations.forEach(declared => {
|
def.declarations.forEach(declared => {
|
||||||
const declaredWithDefs = declared as Type<any>& { ngPipeDef?: any; };
|
const declaredWithDefs = declared as Type<any>& { ngPipeDef?: any; };
|
||||||
|
|
||||||
if (declaredWithDefs.ngPipeDef !== undefined) {
|
if (getPipeDef(declaredWithDefs)) {
|
||||||
scopes.compilation.pipes.add(declared);
|
scopes.compilation.pipes.add(declared);
|
||||||
} else {
|
} else {
|
||||||
// Either declared has an ngComponentDef or ngDirectiveDef, or it's a component which hasn't
|
// Either declared has an ngComponentDef or ngDirectiveDef, or it's a component which hasn't
|
||||||
|
@ -204,7 +205,7 @@ export function transitiveScopesFor<T>(moduleType: Type<T>): NgModuleTransitiveS
|
||||||
scopes.compilation.pipes.add(entry);
|
scopes.compilation.pipes.add(entry);
|
||||||
scopes.exported.pipes.add(entry);
|
scopes.exported.pipes.add(entry);
|
||||||
});
|
});
|
||||||
} else if (exportedTyped.ngPipeDef !== undefined) {
|
} else if (getNgModuleDef(exportedTyped)) {
|
||||||
scopes.exported.pipes.add(exportedTyped);
|
scopes.exported.pipes.add(exportedTyped);
|
||||||
} else {
|
} else {
|
||||||
scopes.exported.directives.add(exportedTyped);
|
scopes.exported.directives.add(exportedTyped);
|
||||||
|
@ -248,5 +249,5 @@ function isModuleWithProviders(value: any): value is ModuleWithProviders {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNgModule<T>(value: Type<T>): value is Type<T>&{ngModuleDef: NgModuleDefInternal<T>} {
|
function isNgModule<T>(value: Type<T>): value is Type<T>&{ngModuleDef: NgModuleDefInternal<T>} {
|
||||||
return (value as{ngModuleDef?: NgModuleDefInternal<T>}).ngModuleDef !== undefined;
|
return !!getNgModuleDef(value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,10 @@ import {WrappedNodeExpr, compilePipeFromMetadata, jitExpression} from '@angular/
|
||||||
|
|
||||||
import {Pipe} from '../../metadata/directives';
|
import {Pipe} from '../../metadata/directives';
|
||||||
import {Type} from '../../type';
|
import {Type} from '../../type';
|
||||||
|
import {NG_PIPE_DEF} from '../fields';
|
||||||
import {stringify} from '../util';
|
import {stringify} from '../util';
|
||||||
|
|
||||||
import {angularCoreEnv} from './environment';
|
import {angularCoreEnv} from './environment';
|
||||||
import {NG_PIPE_DEF} from './fields';
|
|
||||||
import {reflectDependencies} from './util';
|
import {reflectDependencies} from './util';
|
||||||
|
|
||||||
export function compilePipe(type: Type<any>, meta: Pipe): void {
|
export function compilePipe(type: Type<any>, meta: Pipe): void {
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {Type} from '../type';
|
||||||
import {stringify} from '../util';
|
import {stringify} from '../util';
|
||||||
import {assertDefined} from './assert';
|
import {assertDefined} from './assert';
|
||||||
import {ComponentFactoryResolver} from './component_ref';
|
import {ComponentFactoryResolver} from './component_ref';
|
||||||
|
import {getNgModuleDef} from './definition';
|
||||||
|
|
||||||
export interface NgModuleType { ngModuleDef: NgModuleDefInternal<any>; }
|
export interface NgModuleType { ngModuleDef: NgModuleDefInternal<any>; }
|
||||||
|
|
||||||
|
@ -35,12 +36,12 @@ export class NgModuleRef<T> extends viewEngine_NgModuleRef<T> implements Interna
|
||||||
|
|
||||||
constructor(ngModuleType: Type<T>, parentInjector: Injector|null) {
|
constructor(ngModuleType: Type<T>, parentInjector: Injector|null) {
|
||||||
super();
|
super();
|
||||||
const ngModuleDef = (ngModuleType as any as NgModuleType).ngModuleDef;
|
const ngModuleDef = getNgModuleDef(ngModuleType);
|
||||||
ngDevMode && assertDefined(
|
ngDevMode && assertDefined(
|
||||||
ngModuleDef,
|
ngModuleDef,
|
||||||
`NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
|
`NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
|
||||||
|
|
||||||
this._bootstrapComponents = ngModuleDef.bootstrap;
|
this._bootstrapComponents = ngModuleDef !.bootstrap;
|
||||||
const additionalProviders: StaticProvider[] = [
|
const additionalProviders: StaticProvider[] = [
|
||||||
COMPONENT_FACTORY_RESOLVER, {
|
COMPONENT_FACTORY_RESOLVER, {
|
||||||
provide: viewEngine_NgModuleRef,
|
provide: viewEngine_NgModuleRef,
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function getClosureSafeProperty<T>(objWithPropertyToExtract: T, target: any): string {
|
export function getClosureSafeProperty<T>(objWithPropertyToExtract: T): string {
|
||||||
for (let key in objWithPropertyToExtract) {
|
for (let key in objWithPropertyToExtract) {
|
||||||
if (objWithPropertyToExtract[key] === target) {
|
if (objWithPropertyToExtract[key] === getClosureSafeProperty as any) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {InjectableDef} from '../di/defs';
|
import {InjectableDef, getInjectableDef} from '../di/defs';
|
||||||
import {resolveForwardRef} from '../di/forward_ref';
|
import {resolveForwardRef} from '../di/forward_ref';
|
||||||
import {INJECTOR, InjectFlags, Injector, setCurrentInjector} from '../di/injector';
|
import {INJECTOR, InjectFlags, Injector, setCurrentInjector} from '../di/injector';
|
||||||
import {APP_ROOT} from '../di/scope';
|
import {APP_ROOT} from '../di/scope';
|
||||||
|
@ -97,6 +97,7 @@ export function resolveNgModuleDep(
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
const providerDef = data._def.providersByKey[tokenKey];
|
const providerDef = data._def.providersByKey[tokenKey];
|
||||||
|
let injectableDef: InjectableDef<any>|null;
|
||||||
if (providerDef) {
|
if (providerDef) {
|
||||||
let providerInstance = data._providers[providerDef.index];
|
let providerInstance = data._providers[providerDef.index];
|
||||||
if (providerInstance === undefined) {
|
if (providerInstance === undefined) {
|
||||||
|
@ -104,9 +105,8 @@ export function resolveNgModuleDep(
|
||||||
_createProviderInstance(data, providerDef);
|
_createProviderInstance(data, providerDef);
|
||||||
}
|
}
|
||||||
return providerInstance === UNDEFINED_VALUE ? undefined : providerInstance;
|
return providerInstance === UNDEFINED_VALUE ? undefined : providerInstance;
|
||||||
} else if (depDef.token.ngInjectableDef && targetsModule(data, depDef.token.ngInjectableDef)) {
|
} else if (
|
||||||
const injectableDef = depDef.token.ngInjectableDef as InjectableDef<any>;
|
(injectableDef = getInjectableDef(depDef.token)) && targetsModule(data, injectableDef)) {
|
||||||
const key = tokenKey;
|
|
||||||
const index = data._providers.length;
|
const index = data._providers.length;
|
||||||
data._def.providersByKey[depDef.tokenKey] = {
|
data._def.providersByKey[depDef.tokenKey] = {
|
||||||
flags: NodeFlags.TypeFactoryProvider | NodeFlags.LazyProvider,
|
flags: NodeFlags.TypeFactoryProvider | NodeFlags.LazyProvider,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node';
|
import {DebugElement, DebugNode, EventListener, getDebugNode, indexDebugNode, removeDebugNodeFromIndex} from '../debug/debug_node';
|
||||||
import {Injector} from '../di';
|
import {Injector} from '../di';
|
||||||
|
import {InjectableDef, getInjectableDef} from '../di/defs';
|
||||||
import {InjectableType} from '../di/injectable';
|
import {InjectableType} from '../di/injectable';
|
||||||
import {ErrorHandler} from '../error_handler';
|
import {ErrorHandler} from '../error_handler';
|
||||||
import {isDevMode} from '../is_dev_mode';
|
import {isDevMode} from '../is_dev_mode';
|
||||||
|
@ -169,8 +170,9 @@ const viewDefOverrides = new Map<any, ViewDefinition>();
|
||||||
|
|
||||||
function debugOverrideProvider(override: ProviderOverride) {
|
function debugOverrideProvider(override: ProviderOverride) {
|
||||||
providerOverrides.set(override.token, override);
|
providerOverrides.set(override.token, override);
|
||||||
if (typeof override.token === 'function' && override.token.ngInjectableDef &&
|
let injectableDef: InjectableDef<any>|null;
|
||||||
typeof override.token.ngInjectableDef.providedIn === 'function') {
|
if (typeof override.token === 'function' && (injectableDef = getInjectableDef(override.token)) &&
|
||||||
|
typeof injectableDef.providedIn === 'function') {
|
||||||
providerOverridesWithScope.set(override.token as InjectableType<any>, override);
|
providerOverridesWithScope.set(override.token as InjectableType<any>, override);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,7 +278,7 @@ function applyProviderOverridesToNgModule(def: NgModuleDefinition): NgModuleDefi
|
||||||
});
|
});
|
||||||
def.modules.forEach(module => {
|
def.modules.forEach(module => {
|
||||||
providerOverridesWithScope.forEach((override, token) => {
|
providerOverridesWithScope.forEach((override, token) => {
|
||||||
if (token.ngInjectableDef.providedIn === module) {
|
if (getInjectableDef(token) !.providedIn === module) {
|
||||||
hasOverrides = true;
|
hasOverrides = true;
|
||||||
hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
|
hasDeprecatedOverrides = hasDeprecatedOverrides || override.deprecatedBehavior;
|
||||||
}
|
}
|
||||||
|
@ -304,7 +306,7 @@ function applyProviderOverridesToNgModule(def: NgModuleDefinition): NgModuleDefi
|
||||||
if (providerOverridesWithScope.size > 0) {
|
if (providerOverridesWithScope.size > 0) {
|
||||||
let moduleSet = new Set<any>(def.modules);
|
let moduleSet = new Set<any>(def.modules);
|
||||||
providerOverridesWithScope.forEach((override, token) => {
|
providerOverridesWithScope.forEach((override, token) => {
|
||||||
if (moduleSet.has(token.ngInjectableDef.providedIn)) {
|
if (moduleSet.has(getInjectableDef(token) !.providedIn)) {
|
||||||
let provider = {
|
let provider = {
|
||||||
token: token,
|
token: token,
|
||||||
flags:
|
flags:
|
||||||
|
|
|
@ -50,9 +50,18 @@
|
||||||
{
|
{
|
||||||
"name": "NEXT"
|
"name": "NEXT"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_COMPONENT_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_DIRECTIVE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_ELEMENT_ID"
|
"name": "NG_ELEMENT_ID"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_PIPE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_PROJECT_AS_ATTR_NAME"
|
"name": "NG_PROJECT_AS_ATTR_NAME"
|
||||||
},
|
},
|
||||||
|
@ -200,6 +209,15 @@
|
||||||
{
|
{
|
||||||
"name": "getChildLNode"
|
"name": "getChildLNode"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getClosureSafeProperty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "getComponentDef"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "getDirectiveDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getLElementFromComponent"
|
"name": "getLElementFromComponent"
|
||||||
},
|
},
|
||||||
|
@ -221,6 +239,9 @@
|
||||||
{
|
{
|
||||||
"name": "getParentLNode"
|
"name": "getParentLNode"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getPipeDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getPreviousOrParentNode"
|
"name": "getPreviousOrParentNode"
|
||||||
},
|
},
|
||||||
|
|
|
@ -710,12 +710,6 @@
|
||||||
{
|
{
|
||||||
"name": "FunctionExpr"
|
"name": "FunctionExpr"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "GET_PROPERTY_NAME"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "GET_PROPERTY_NAME$2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "GOOG_GET_MSG"
|
"name": "GOOG_GET_MSG"
|
||||||
},
|
},
|
||||||
|
@ -1001,6 +995,9 @@
|
||||||
{
|
{
|
||||||
"name": "NG_CONTENT_SELECT_ATTR"
|
"name": "NG_CONTENT_SELECT_ATTR"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTABLE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_NON_BINDABLE_ATTR"
|
"name": "NG_NON_BINDABLE_ATTR"
|
||||||
},
|
},
|
||||||
|
@ -2939,9 +2936,6 @@
|
||||||
{
|
{
|
||||||
"name": "getClosureSafeProperty"
|
"name": "getClosureSafeProperty"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "getClosureSafeProperty$1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "getComponentViewDefinitionFactory"
|
"name": "getComponentViewDefinitionFactory"
|
||||||
},
|
},
|
||||||
|
@ -2969,6 +2963,9 @@
|
||||||
{
|
{
|
||||||
"name": "getHtmlTagDefinition"
|
"name": "getHtmlTagDefinition"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getInjectableDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getNgZone"
|
"name": "getNgZone"
|
||||||
},
|
},
|
||||||
|
|
|
@ -8,9 +8,6 @@
|
||||||
{
|
{
|
||||||
"name": "EMPTY_ARRAY$2"
|
"name": "EMPTY_ARRAY$2"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "GET_PROPERTY_NAME"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "INJECTOR"
|
"name": "INJECTOR"
|
||||||
},
|
},
|
||||||
|
@ -20,6 +17,12 @@
|
||||||
{
|
{
|
||||||
"name": "InjectionToken"
|
"name": "InjectionToken"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTABLE_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTOR_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NOT_YET"
|
"name": "NOT_YET"
|
||||||
},
|
},
|
||||||
|
@ -86,6 +89,12 @@
|
||||||
{
|
{
|
||||||
"name": "getClosureSafeProperty"
|
"name": "getClosureSafeProperty"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getInjectableDef"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "getInjectorDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getNullInjector"
|
"name": "getNullInjector"
|
||||||
},
|
},
|
||||||
|
|
|
@ -80,9 +80,21 @@
|
||||||
{
|
{
|
||||||
"name": "NEXT"
|
"name": "NEXT"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_COMPONENT_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_DIRECTIVE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_ELEMENT_ID"
|
"name": "NG_ELEMENT_ID"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTABLE_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_PIPE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_PROJECT_AS_ATTR_NAME"
|
"name": "NG_PROJECT_AS_ATTR_NAME"
|
||||||
},
|
},
|
||||||
|
@ -557,18 +569,30 @@
|
||||||
{
|
{
|
||||||
"name": "getClosestComponentAncestor"
|
"name": "getClosestComponentAncestor"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getClosureSafeProperty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "getComponentDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getCurrentSanitizer"
|
"name": "getCurrentSanitizer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "getCurrentView"
|
"name": "getCurrentView"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getDirectiveDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getInitialIndex"
|
"name": "getInitialIndex"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "getInitialValue"
|
"name": "getInitialValue"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getInjectableDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getLElementFromComponent"
|
"name": "getLElementFromComponent"
|
||||||
},
|
},
|
||||||
|
@ -620,6 +644,9 @@
|
||||||
{
|
{
|
||||||
"name": "getParentState"
|
"name": "getParentState"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getPipeDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getPointers"
|
"name": "getPointers"
|
||||||
},
|
},
|
||||||
|
|
|
@ -311,9 +311,6 @@
|
||||||
{
|
{
|
||||||
"name": "FormatWidth"
|
"name": "FormatWidth"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "GET_PROPERTY_NAME"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "GROUP_SEP"
|
"name": "GROUP_SEP"
|
||||||
},
|
},
|
||||||
|
@ -461,9 +458,27 @@
|
||||||
{
|
{
|
||||||
"name": "NEXT"
|
"name": "NEXT"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_COMPONENT_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_DIRECTIVE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_ELEMENT_ID"
|
"name": "NG_ELEMENT_ID"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTABLE_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_INJECTOR_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_MODULE_DEF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "NG_PIPE_DEF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "NG_PROJECT_AS_ATTR_NAME"
|
"name": "NG_PROJECT_AS_ATTR_NAME"
|
||||||
},
|
},
|
||||||
|
@ -1553,6 +1568,9 @@
|
||||||
{
|
{
|
||||||
"name": "getClosureSafeProperty"
|
"name": "getClosureSafeProperty"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getComponentDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getCurrencySymbol"
|
"name": "getCurrencySymbol"
|
||||||
},
|
},
|
||||||
|
@ -1580,6 +1598,9 @@
|
||||||
{
|
{
|
||||||
"name": "getDebugNode"
|
"name": "getDebugNode"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getDirectiveDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getErrorLogger"
|
"name": "getErrorLogger"
|
||||||
},
|
},
|
||||||
|
@ -1592,6 +1613,12 @@
|
||||||
{
|
{
|
||||||
"name": "getInitialValue"
|
"name": "getInitialValue"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getInjectableDef"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "getInjectorDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getLElementFromComponent"
|
"name": "getLElementFromComponent"
|
||||||
},
|
},
|
||||||
|
@ -1655,6 +1682,9 @@
|
||||||
{
|
{
|
||||||
"name": "getNamedFormat"
|
"name": "getNamedFormat"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getNgModuleDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getNgZone"
|
"name": "getNgZone"
|
||||||
},
|
},
|
||||||
|
@ -1703,6 +1733,9 @@
|
||||||
{
|
{
|
||||||
"name": "getParentState"
|
"name": "getParentState"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "getPipeDef"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "getPlatform"
|
"name": "getPlatform"
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Component, Directive, Injector, NgModule, Pipe, PlatformRef, Provider, RendererFactory2, SchemaMetadata, Type, ɵNgModuleDefInternal as NgModuleDefInternal, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵRender3ComponentFactory as ComponentFactory, ɵRender3DebugRendererFactory2 as Render3DebugRendererFactory2, ɵRender3NgModuleRef as NgModuleRef, ɵWRAP_RENDERER_FACTORY2 as WRAP_RENDERER_FACTORY2, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵstringify as stringify} from '@angular/core';
|
import {Component, Directive, Injector, NgModule, Pipe, PlatformRef, Provider, RendererFactory2, SchemaMetadata, Type, ɵInjectableDef as InjectableDef, ɵNgModuleDefInternal as NgModuleDefInternal, ɵNgModuleTransitiveScopes as NgModuleTransitiveScopes, ɵRender3ComponentFactory as ComponentFactory, ɵRender3DebugRendererFactory2 as Render3DebugRendererFactory2, ɵRender3NgModuleRef as NgModuleRef, ɵWRAP_RENDERER_FACTORY2 as WRAP_RENDERER_FACTORY2, ɵcompileComponent as compileComponent, ɵcompileDirective as compileDirective, ɵcompileNgModuleDefs as compileNgModuleDefs, ɵcompilePipe as compilePipe, ɵgetInjectableDef as getInjectableDef, ɵpatchComponentDefWithScope as patchComponentDefWithScope, ɵstringify as stringify} from '@angular/core';
|
||||||
|
|
||||||
import {ComponentFixture} from './component_fixture';
|
import {ComponentFixture} from './component_fixture';
|
||||||
import {MetadataOverride} from './metadata_override';
|
import {MetadataOverride} from './metadata_override';
|
||||||
|
@ -314,9 +314,10 @@ export class TestBedRender3 implements Injector, TestBed {
|
||||||
*/
|
*/
|
||||||
overrideProvider(token: any, provider: {useFactory?: Function, useValue?: any, deps?: any[]}):
|
overrideProvider(token: any, provider: {useFactory?: Function, useValue?: any, deps?: any[]}):
|
||||||
void {
|
void {
|
||||||
|
let injectableDef: InjectableDef<any>|null;
|
||||||
const isRoot =
|
const isRoot =
|
||||||
(typeof token !== 'string' && token.ngInjectableDef &&
|
(typeof token !== 'string' && (injectableDef = getInjectableDef(token)) &&
|
||||||
token.ngInjectableDef.providedIn === 'root');
|
injectableDef.providedIn === 'root');
|
||||||
const overrides = isRoot ? this._rootProviderOverrides : this._providerOverrides;
|
const overrides = isRoot ? this._rootProviderOverrides : this._providerOverrides;
|
||||||
|
|
||||||
if (provider.useFactory) {
|
if (provider.useFactory) {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ApplicationInitStatus, CompilerOptions, Component, Directive, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵAPP_ROOT as APP_ROOT, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵivyEnabled as ivyEnabled, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core';
|
import {ApplicationInitStatus, CompilerOptions, Component, Directive, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵAPP_ROOT as APP_ROOT, ɵDepFlags as DepFlags, ɵInjectableDef as InjectableDef, ɵNodeFlags as NodeFlags, ɵclearOverrides as clearOverrides, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵgetInjectableDef as getInjectableDef, ɵivyEnabled as ivyEnabled, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify} from '@angular/core';
|
||||||
|
|
||||||
import {AsyncTestCompleter} from './async_test_completer';
|
import {AsyncTestCompleter} from './async_test_completer';
|
||||||
import {ComponentFixture} from './component_fixture';
|
import {ComponentFixture} from './component_fixture';
|
||||||
|
@ -549,8 +549,8 @@ export class TestBedViewEngine implements Injector, TestBed {
|
||||||
deps?: any[],
|
deps?: any[],
|
||||||
},
|
},
|
||||||
deprecated = false): void {
|
deprecated = false): void {
|
||||||
if (typeof token !== 'string' && token.ngInjectableDef &&
|
let def: InjectableDef<any>|null = null;
|
||||||
token.ngInjectableDef.providedIn === 'root') {
|
if (typeof token !== 'string' && (def = getInjectableDef(token)) && def.providedIn === 'root') {
|
||||||
if (provider.useFactory) {
|
if (provider.useFactory) {
|
||||||
this._rootProviderOverrides.push(
|
this._rootProviderOverrides.push(
|
||||||
{provide: token, useFactory: provider.useFactory, deps: provider.deps || []});
|
{provide: token, useFactory: provider.useFactory, deps: provider.deps || []});
|
||||||
|
|
Loading…
Reference in New Issue