From de4fafb818b1648813aef227df883c7502b825fb Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 12 Apr 2021 17:32:10 +0200 Subject: [PATCH] refactor(core): add single type for injector token (#41580) Currently we have a lot of places where we repeat the type `Type|AbstractType|InjectionToken` which makes it cumbersome to add another type or to type something else with the same signature. These changes add a new type that can be used instead. Fixes #39792. PR Close #41580 --- goldens/public-api/core/core.d.ts | 24 ++++++------ goldens/public-api/core/testing/testing.d.ts | 12 +++--- packages/core/src/di/index.ts | 1 + packages/core/src/di/inject_switch.ts | 18 ++++----- packages/core/src/di/injector.ts | 12 +++--- .../core/src/di/injector_compatibility.ts | 23 +++++------- packages/core/src/di/provider_token.ts | 19 ++++++++++ packages/core/src/di/r3_injector.ts | 15 ++++---- packages/core/src/metadata/di.ts | 20 +++++----- packages/core/src/render3/component_ref.ts | 7 ++-- packages/core/src/render3/di.ts | 31 +++++++--------- packages/core/src/render3/instructions/di.ts | 12 +++--- .../core/src/render3/interfaces/injector.ts | 9 ++--- packages/core/src/render3/interfaces/query.ts | 5 +-- packages/core/src/render3/interfaces/view.ts | 7 ++-- packages/core/src/render3/query.ts | 11 +++--- packages/core/testing/src/r3_test_bed.ts | 28 +++++--------- packages/core/testing/src/test_bed.ts | 37 ++++++------------- packages/core/testing/src/test_bed_common.ts | 11 ++---- packages/examples/core/di/ts/injector_spec.ts | 6 +-- 20 files changed, 138 insertions(+), 170 deletions(-) create mode 100644 packages/core/src/di/provider_token.ts diff --git a/goldens/public-api/core/core.d.ts b/goldens/public-api/core/core.d.ts index b0d0c9b19f..21137006a1 100644 --- a/goldens/public-api/core/core.d.ts +++ b/goldens/public-api/core/core.d.ts @@ -159,11 +159,11 @@ export declare interface ConstructorSansProvider { export declare type ContentChild = Query; export declare interface ContentChildDecorator { - (selector: Type | InjectionToken | Function | string, opts?: { + (selector: ProviderToken | Function | string, opts?: { read?: any; static?: boolean; }): any; - new (selector: Type | InjectionToken | Function | string, opts?: { + new (selector: ProviderToken | Function | string, opts?: { read?: any; static?: boolean; }): ContentChild; @@ -172,12 +172,12 @@ export declare interface ContentChildDecorator { export declare type ContentChildren = Query; export declare interface ContentChildrenDecorator { - (selector: Type | InjectionToken | Function | string, opts?: { + (selector: ProviderToken | Function | string, opts?: { descendants?: boolean; emitDistinctChangesOnly?: boolean; read?: any; }): any; - new (selector: Type | InjectionToken | Function | string, opts?: { + new (selector: ProviderToken | Function | string, opts?: { descendants?: boolean; emitDistinctChangesOnly?: boolean; read?: any; @@ -448,7 +448,7 @@ export declare class InjectionToken { } export declare abstract class Injector { - abstract get(token: Type | AbstractType | InjectionToken, notFoundValue?: T, flags?: InjectFlags): T; + abstract get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; /** @deprecated */ abstract get(token: any, notFoundValue?: any): any; static NULL: Injector; static THROW_IF_NOT_FOUND: {}; @@ -680,8 +680,8 @@ export declare function ɵɵdefineInjectable(opts: { }): unknown; /** @codeGenApi */ -export declare function ɵɵinject(token: Type | AbstractType | InjectionToken): T; -export declare function ɵɵinject(token: Type | AbstractType | InjectionToken, flags?: InjectFlags): T | null; +export declare function ɵɵinject(token: ProviderToken): T; +export declare function ɵɵinject(token: ProviderToken, flags?: InjectFlags): T | null; /** @codeGenApi */ export declare function ɵɵinjectAttribute(attrNameToInject: string): string | null; @@ -725,6 +725,8 @@ export declare interface Predicate { export declare type Provider = TypeProvider | ValueProvider | ClassProvider | ConstructorProvider | ExistingProvider | FactoryProvider | any[]; +export declare type ProviderToken = Type | AbstractType | InjectionToken; + export declare interface Query { descendants: boolean; emitDistinctChangesOnly: boolean; @@ -989,11 +991,11 @@ export declare const VERSION: Version; export declare type ViewChild = Query; export declare interface ViewChildDecorator { - (selector: Type | InjectionToken | Function | string, opts?: { + (selector: ProviderToken | Function | string, opts?: { read?: any; static?: boolean; }): any; - new (selector: Type | InjectionToken | Function | string, opts?: { + new (selector: ProviderToken | Function | string, opts?: { read?: any; static?: boolean; }): ViewChild; @@ -1002,11 +1004,11 @@ export declare interface ViewChildDecorator { export declare type ViewChildren = Query; export declare interface ViewChildrenDecorator { - (selector: Type | InjectionToken | Function | string, opts?: { + (selector: ProviderToken | Function | string, opts?: { read?: any; emitDistinctChangesOnly?: boolean; }): any; - new (selector: Type | InjectionToken | Function | string, opts?: { + new (selector: ProviderToken | Function | string, opts?: { read?: any; emitDistinctChangesOnly?: boolean; }): ViewChildren; diff --git a/goldens/public-api/core/testing/testing.d.ts b/goldens/public-api/core/testing/testing.d.ts index 8144bc5d30..1ef670be54 100644 --- a/goldens/public-api/core/testing/testing.d.ts +++ b/goldens/public-api/core/testing/testing.d.ts @@ -62,11 +62,11 @@ export declare interface TestBed { configureTestingModule(moduleDef: TestModuleMetadata): void; createComponent(component: Type): ComponentFixture; execute(tokens: any[], fn: Function, context?: any): any; - /** @deprecated */ get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** @deprecated */ get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated */ get(token: any, notFoundValue?: any): any; initTestEnvironment(ngModule: Type | Type[], platform: PlatformRef, aotSummaries?: () => any[]): void; - inject(token: Type | InjectionToken | AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - inject(token: Type | InjectionToken | AbstractType, notFoundValue: null, flags?: InjectFlags): T | null; + inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T | null; overrideComponent(component: Type, override: MetadataOverride): void; overrideDirective(directive: Type, override: MetadataOverride): void; overrideModule(ngModule: Type, override: MetadataOverride): void; @@ -99,11 +99,11 @@ export declare interface TestBedStatic { }): TestBedStatic; configureTestingModule(moduleDef: TestModuleMetadata): TestBedStatic; createComponent(component: Type): ComponentFixture; - /** @deprecated */ get(token: Type | InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + /** @deprecated */ get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated */ get(token: any, notFoundValue?: any): any; initTestEnvironment(ngModule: Type | Type[], platform: PlatformRef, aotSummaries?: () => any[]): TestBed; - inject(token: Type | InjectionToken | AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - inject(token: Type | InjectionToken | AbstractType, notFoundValue: null, flags?: InjectFlags): T | null; + inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T | null; overrideComponent(component: Type, override: MetadataOverride): TestBedStatic; overrideDirective(directive: Type, override: MetadataOverride): TestBedStatic; overrideModule(ngModule: Type, override: MetadataOverride): TestBedStatic; diff --git a/packages/core/src/di/index.ts b/packages/core/src/di/index.ts index 845757d5d6..8f91f27b93 100644 --- a/packages/core/src/di/index.ts +++ b/packages/core/src/di/index.ts @@ -18,6 +18,7 @@ export {ɵɵdefineInjectable, defineInjectable, ɵɵdefineInjector, InjectableTy export {forwardRef, resolveForwardRef, ForwardRefFn} from './forward_ref'; export {Injectable, InjectableDecorator, InjectableProvider} from './injectable'; export {Injector} from './injector'; +export {ProviderToken} from './provider_token'; export {ɵɵinject, inject, ɵɵinvalidFactoryDep} from './injector_compatibility'; export {INJECTOR} from './injector_token'; export {ReflectiveInjector} from './reflective_injector'; diff --git a/packages/core/src/di/inject_switch.ts b/packages/core/src/di/inject_switch.ts index d90b6caeee..a780c13a75 100644 --- a/packages/core/src/di/inject_switch.ts +++ b/packages/core/src/di/inject_switch.ts @@ -6,13 +6,13 @@ * found in the LICENSE file at https://angular.io/license */ -import {AbstractType, Type} from '../interface/type'; import {throwProviderNotFoundError} from '../render3/errors_di'; import {assertNotEqual} from '../util/assert'; import {stringify} from '../util/stringify'; -import {InjectionToken} from './injection_token'; + import {getInjectableDef, ɵɵInjectableDeclaration} from './interface/defs'; import {InjectFlags} from './interface/injector'; +import {ProviderToken} from './provider_token'; /** @@ -24,8 +24,7 @@ import {InjectFlags} from './interface/injector'; * 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: - ((token: Type|AbstractType|InjectionToken, flags?: InjectFlags) => T | null)| +let _injectImplementation: ((token: ProviderToken, flags?: InjectFlags) => T | null)| undefined; export function getInjectImplementation() { return _injectImplementation; @@ -36,10 +35,8 @@ export function getInjectImplementation() { * Sets the current inject implementation. */ export function setInjectImplementation( - impl: ((token: Type|AbstractType|InjectionToken, flags?: InjectFlags) => T | null)| - undefined): - ((token: Type|AbstractType|InjectionToken, flags?: InjectFlags) => T | null)| - undefined { + impl: ((token: ProviderToken, flags?: InjectFlags) => T | null)| + undefined): ((token: ProviderToken, flags?: InjectFlags) => T | null)|undefined { const previous = _injectImplementation; _injectImplementation = impl; return previous; @@ -54,8 +51,7 @@ export function setInjectImplementation( * injectable definition. */ export function injectRootLimpMode( - token: Type|AbstractType|InjectionToken, notFoundValue: T|undefined, - flags: InjectFlags): T|null { + token: ProviderToken, notFoundValue: T|undefined, flags: InjectFlags): T|null { const injectableDef: ɵɵInjectableDeclaration|null = getInjectableDef(token); if (injectableDef && injectableDef.providedIn == 'root') { return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() : @@ -75,7 +71,7 @@ export function injectRootLimpMode( * @param fn Function which it should not equal to */ export function assertInjectImplementationNotEqual( - fn: ((token: Type|AbstractType|InjectionToken, flags?: InjectFlags) => T | null)) { + fn: ((token: ProviderToken, flags?: InjectFlags) => T | null)) { ngDevMode && assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion'); } diff --git a/packages/core/src/di/injector.ts b/packages/core/src/di/injector.ts index 50cc2a6dac..a299d9a664 100644 --- a/packages/core/src/di/injector.ts +++ b/packages/core/src/di/injector.ts @@ -6,10 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {AbstractType, Type} from '../interface/type'; import {stringify} from '../util/stringify'; + import {resolveForwardRef} from './forward_ref'; -import {InjectionToken} from './injection_token'; 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'; @@ -18,6 +17,7 @@ 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 {ProviderToken} from './provider_token'; import {createInjector} from './r3_injector'; import {INJECTOR_SCOPE} from './scope'; @@ -66,10 +66,9 @@ export abstract class Injector { * @returns The instance from the injector if defined, otherwise the `notFoundValue`. * @throws When the `notFoundValue` is `undefined` or `Injector.THROW_IF_NOT_FOUND`. */ - abstract get( - token: Type|AbstractType|InjectionToken, notFoundValue?: T, flags?: InjectFlags): T; + abstract get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; /** - * @deprecated from v4.0.0 use Type, AbstractType or InjectionToken + * @deprecated from v4.0.0 use ProviderToken * @suppress {duplicate} */ abstract get(token: any, notFoundValue?: any): any; @@ -156,8 +155,7 @@ export class StaticInjector implements Injector { this.scope = recursivelyProcessProviders(records, providers); } - get(token: Type|AbstractType|InjectionToken, notFoundValue?: T, flags?: InjectFlags): - T; + get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; get(token: any, notFoundValue?: any): any; get(token: any, notFoundValue?: any, flags: InjectFlags = InjectFlags.Default): any { const records = this._records; diff --git a/packages/core/src/di/injector_compatibility.ts b/packages/core/src/di/injector_compatibility.ts index 402621aef1..03d2a69d64 100644 --- a/packages/core/src/di/injector_compatibility.ts +++ b/packages/core/src/di/injector_compatibility.ts @@ -8,16 +8,16 @@ import '../util/ng_dev_mode'; -import {AbstractType, Type} from '../interface/type'; +import {Type} from '../interface/type'; 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 {DecoratorFlags, InjectFlags, InternalInjectFlags} from './interface/injector'; import {ValueProvider} from './interface/provider'; +import {ProviderToken} from './provider_token'; const _THROW_IF_NOT_FOUND = {}; @@ -53,11 +53,10 @@ export function setCurrentInjector(injector: Injector|null|undefined): Injector| return former; } -export function injectInjectorOnly(token: Type|AbstractType|InjectionToken): T; -export function injectInjectorOnly( - token: Type|AbstractType|InjectionToken, flags?: InjectFlags): T|null; -export function injectInjectorOnly( - token: Type|AbstractType|InjectionToken, flags = InjectFlags.Default): T|null { +export function injectInjectorOnly(token: ProviderToken): T; +export function injectInjectorOnly(token: ProviderToken, flags?: InjectFlags): T|null; +export function injectInjectorOnly(token: ProviderToken, flags = InjectFlags.Default): T| + null { if (_currentInjector === undefined) { throw new Error(`inject() must be called from an injection context`); } else if (_currentInjector === null) { @@ -80,11 +79,9 @@ export function injectInjectorOnly( * @codeGenApi * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm. */ -export function ɵɵinject(token: Type|AbstractType|InjectionToken): T; -export function ɵɵinject( - token: Type|AbstractType|InjectionToken, flags?: InjectFlags): T|null; -export function ɵɵinject( - token: Type|AbstractType|InjectionToken, flags = InjectFlags.Default): T|null { +export function ɵɵinject(token: ProviderToken): T; +export function ɵɵinject(token: ProviderToken, flags?: InjectFlags): T|null; +export function ɵɵinject(token: ProviderToken, flags = InjectFlags.Default): T|null { return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags); } @@ -138,7 +135,7 @@ Please check that 1) the type for the parameter at index ${ */ export const inject = ɵɵinject; -export function injectArgs(types: (Type|InjectionToken|any[])[]): any[] { +export function injectArgs(types: (ProviderToken|any[])[]): any[] { const args: any[] = []; for (let i = 0; i < types.length; i++) { const arg = resolveForwardRef(types[i]); diff --git a/packages/core/src/di/provider_token.ts b/packages/core/src/di/provider_token.ts new file mode 100644 index 0000000000..27d07dde63 --- /dev/null +++ b/packages/core/src/di/provider_token.ts @@ -0,0 +1,19 @@ +/** + * @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 {AbstractType, Type} from '../interface/type'; +import {InjectionToken} from './injection_token'; + +/** + * @description + * + * Token that can be used to retrieve an instance from an injector or through a query. + * + * @publicApi + */ +export type ProviderToken = Type|AbstractType|InjectionToken; diff --git a/packages/core/src/di/r3_injector.ts b/packages/core/src/di/r3_injector.ts index cca8801595..61947af699 100644 --- a/packages/core/src/di/r3_injector.ts +++ b/packages/core/src/di/r3_injector.ts @@ -9,7 +9,7 @@ import '../util/ng_dev_mode'; import {OnDestroy} from '../interface/lifecycle_hooks'; -import {AbstractType, Type} from '../interface/type'; +import {Type} from '../interface/type'; import {FactoryFn, getFactoryDef} from '../render3/definition_factory'; import {throwCyclicDependencyError, throwInvalidProviderError, throwMixedMultiProviderError} from '../render3/errors_di'; import {deepForEach, newArray} from '../util/array_utils'; @@ -25,6 +25,7 @@ import {getInheritedInjectableDef, getInjectableDef, getInjectorDef, InjectorTyp import {InjectFlags} from './interface/injector'; import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './interface/provider'; import {NullInjector} from './null_injector'; +import {ProviderToken} from './provider_token'; import {INJECTOR_SCOPE} from './scope'; @@ -102,7 +103,7 @@ export class R3Injector { * - `null` value implies that we don't have the record. Used by tree-shakable injectors * to prevent further searches. */ - private records = new Map|AbstractType|InjectionToken, Record|null>(); + private records = new Map, Record|null>(); /** * The transitive set of `InjectorType`s which define this injector. @@ -180,7 +181,7 @@ export class R3Injector { } get( - token: Type|AbstractType|InjectionToken, notFoundValue: any = THROW_IF_NOT_FOUND, + token: ProviderToken, notFoundValue: any = THROW_IF_NOT_FOUND, flags = InjectFlags.Default): T { this.assertNotDestroyed(); // Set the injection context. @@ -404,7 +405,7 @@ export class R3Injector { this.records.set(token, record); } - private hydrate(token: Type|AbstractType|InjectionToken, record: Record): T { + private hydrate(token: ProviderToken, record: Record): T { if (ngDevMode && record.value === CIRCULAR) { throwCyclicDependencyError(stringify(token)); } else if (record.value === NOT_YET) { @@ -430,8 +431,7 @@ export class R3Injector { } } -function injectableDefOrInjectorDefFactory(token: Type|AbstractType| - InjectionToken): FactoryFn { +function injectableDefOrInjectorDefFactory(token: ProviderToken): FactoryFn { // Most tokens will have an injectable def directly on them, which specifies a factory directly. const injectableDef = getInjectableDef(token); const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token); @@ -560,8 +560,7 @@ function hasOnDestroy(value: any): value is OnDestroy { typeof (value as OnDestroy).ngOnDestroy === 'function'; } -function couldBeInjectableType(value: any): value is Type|AbstractType| - InjectionToken { +function couldBeInjectableType(value: any): value is ProviderToken { return (typeof value === 'function') || (typeof value === 'object' && value instanceof InjectionToken); } diff --git a/packages/core/src/metadata/di.ts b/packages/core/src/metadata/di.ts index 53e317bf41..7e3d5c694f 100644 --- a/packages/core/src/metadata/di.ts +++ b/packages/core/src/metadata/di.ts @@ -7,7 +7,7 @@ */ import {InjectionToken} from '../di/injection_token'; -import {Type} from '../interface/type'; +import {ProviderToken} from '../di/provider_token'; import {makePropDecorator} from '../util/decorators'; /** @@ -169,12 +169,12 @@ export interface ContentChildrenDecorator { * * @Annotation */ - (selector: Type|InjectionToken|Function|string, opts?: { + (selector: ProviderToken|Function|string, opts?: { descendants?: boolean, emitDistinctChangesOnly?: boolean, read?: any, }): any; - new(selector: Type|InjectionToken|Function|string, + new(selector: ProviderToken|Function|string, opts?: {descendants?: boolean, emitDistinctChangesOnly?: boolean, read?: any}): Query; } @@ -240,9 +240,8 @@ export interface ContentChildDecorator { * * @Annotation */ - (selector: Type|InjectionToken|Function|string, - opts?: {read?: any, static?: boolean}): any; - new(selector: Type|InjectionToken|Function|string, + (selector: ProviderToken|Function|string, opts?: {read?: any, static?: boolean}): any; + new(selector: ProviderToken|Function|string, opts?: {read?: any, static?: boolean}): ContentChild; } @@ -304,9 +303,9 @@ export interface ViewChildrenDecorator { * * @Annotation */ - (selector: Type|InjectionToken|Function|string, + (selector: ProviderToken|Function|string, opts?: {read?: any, emitDistinctChangesOnly?: boolean}): any; - new(selector: Type|InjectionToken|Function|string, + new(selector: ProviderToken|Function|string, opts?: {read?: any, emitDistinctChangesOnly?: boolean}): ViewChildren; } @@ -379,9 +378,8 @@ export interface ViewChildDecorator { * * @Annotation */ - (selector: Type|InjectionToken|Function|string, - opts?: {read?: any, static?: boolean}): any; - new(selector: Type|InjectionToken|Function|string, + (selector: ProviderToken|Function|string, opts?: {read?: any, static?: boolean}): any; + new(selector: ProviderToken|Function|string, opts?: {read?: any, static?: boolean}): ViewChild; } diff --git a/packages/core/src/render3/component_ref.ts b/packages/core/src/render3/component_ref.ts index 0c4ebfb686..2963007ecb 100644 --- a/packages/core/src/render3/component_ref.ts +++ b/packages/core/src/render3/component_ref.ts @@ -10,7 +10,8 @@ import {ChangeDetectorRef as ViewEngine_ChangeDetectorRef} from '../change_detec import {InjectionToken} from '../di/injection_token'; import {Injector} from '../di/injector'; import {InjectFlags} from '../di/interface/injector'; -import {AbstractType, Type} from '../interface/type'; +import {ProviderToken} from '../di/provider_token'; +import {Type} from '../interface/type'; import {ComponentFactory as viewEngine_ComponentFactory, ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory'; import {ComponentFactoryResolver as viewEngine_ComponentFactoryResolver} from '../linker/component_factory_resolver'; import {createElementRef, ElementRef as viewEngine_ElementRef} from '../linker/element_ref'; @@ -80,9 +81,7 @@ export const SCHEDULER = new InjectionToken<((fn: () => void) => void)>('SCHEDUL function createChainedInjector(rootViewInjector: Injector, moduleInjector: Injector): Injector { return { - get: ( - token: Type|AbstractType|InjectionToken, notFoundValue?: T, - flags?: InjectFlags): T => { + get: (token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T => { const value = rootViewInjector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR as T, flags); if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR || diff --git a/packages/core/src/render3/di.ts b/packages/core/src/render3/di.ts index 0a634787bd..352d4baf80 100644 --- a/packages/core/src/render3/di.ts +++ b/packages/core/src/render3/di.ts @@ -8,12 +8,11 @@ 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 {InjectorMarkers} from '../di/injector_marker'; -import {getInjectableDef} from '../di/interface/defs'; import {InjectFlags} from '../di/interface/injector'; -import {AbstractType, Type} from '../interface/type'; +import {ProviderToken} from '../di/provider_token'; +import {Type} from '../interface/type'; import {assertDefined, assertEqual, assertIndexInRange} from '../util/assert'; import {noSideEffects} from '../util/closure'; @@ -106,7 +105,7 @@ let nextNgElementId = 0; * @param type The directive token to register */ export function bloomAdd( - injectorIndex: number, tView: TView, type: Type|InjectionToken|string): void { + injectorIndex: number, tView: TView, type: ProviderToken|string): void { ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true'); let id: number|undefined; if (typeof type === 'string') { @@ -264,7 +263,7 @@ export function getParentInjectorLocation(tNode: TNode, lView: LView): RelativeI * @param token The type or the injection token to be made public */ export function diPublicInInjector( - injectorIndex: number, tView: TView, token: InjectionToken|Type): void { + injectorIndex: number, tView: TView, token: ProviderToken): void { bloomAdd(injectorIndex, tView, token); } @@ -344,8 +343,7 @@ export function injectAttributeImpl(tNode: TNode, attrNameToInject: string): str function notFoundValueOrThrow( - notFoundValue: T|null, token: Type|AbstractType|InjectionToken, flags: InjectFlags): T| - null { + notFoundValue: T|null, token: ProviderToken, flags: InjectFlags): T|null { if (flags & InjectFlags.Optional) { return notFoundValue; } else { @@ -363,8 +361,7 @@ function notFoundValueOrThrow( * @returns the value from the injector or throws an exception */ function lookupTokenUsingModuleInjector( - lView: LView, token: Type|AbstractType|InjectionToken, flags: InjectFlags, - notFoundValue?: any): T|null { + lView: LView, token: ProviderToken, flags: InjectFlags, notFoundValue?: any): T|null { if (flags & InjectFlags.Optional && notFoundValue === undefined) { // This must be set or the NullInjector will throw for optional deps notFoundValue = null; @@ -406,7 +403,7 @@ function lookupTokenUsingModuleInjector( * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided */ export function getOrCreateInjectable( - tNode: TDirectiveHostNode|null, lView: LView, token: Type|AbstractType|InjectionToken, + tNode: TDirectiveHostNode|null, lView: LView, token: ProviderToken, flags: InjectFlags = InjectFlags.Default, notFoundValue?: any): T|null { if (tNode !== null) { const bloomHash = bloomHashBitOrFactory(token); @@ -506,8 +503,8 @@ export function createNodeInjector(): Injector { } function searchTokensOnInjector( - injectorIndex: number, lView: LView, token: Type|AbstractType|InjectionToken, - previousTView: TView|null, flags: InjectFlags, hostTElementNode: TNode|null) { + injectorIndex: number, lView: LView, token: ProviderToken, previousTView: TView|null, + flags: InjectFlags, hostTElementNode: TNode|null) { const currentTView = lView[TVIEW]; const tNode = currentTView.data[injectorIndex + NodeInjectorOffset.TNODE] as TNode; // First, we need to determine if view providers can be accessed by the starting element. @@ -553,8 +550,8 @@ function searchTokensOnInjector( * @returns Index of a found directive or provider, or null when none found. */ export function locateDirectiveOrProvider( - tNode: TNode, tView: TView, token: Type|AbstractType|InjectionToken|string, - canAccessViewProviders: boolean, isHostSpecialCase: boolean|number): number|null { + tNode: TNode, tView: TView, token: ProviderToken|string, canAccessViewProviders: boolean, + isHostSpecialCase: boolean|number): number|null { const nodeProviderIndexes = tNode.providerIndexes; const tInjectables = tView.data; @@ -568,8 +565,7 @@ export function locateDirectiveOrProvider( // When the host special case applies, only the viewProviders and the component are visible const endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd; for (let i = startingIndex; i < endIndex; i++) { - const providerTokenOrDef = - tInjectables[i] as InjectionToken| Type| DirectiveDef| string; + const providerTokenOrDef = tInjectables[i] as ProviderToken| DirectiveDef| string; if (i < directivesStart && token === providerTokenOrDef || i >= directivesStart && (providerTokenOrDef as DirectiveDef).type === token) { return i; @@ -644,8 +640,7 @@ export function getNodeInjectable( * @returns the matching bit to check in the bloom filter or `null` if the token is not known. * When the returned value is negative then it represents special values such as `Injector`. */ -export function bloomHashBitOrFactory(token: Type|AbstractType|InjectionToken| - string): number|Function|undefined { +export function bloomHashBitOrFactory(token: ProviderToken|string): number|Function|undefined { ngDevMode && assertDefined(token, 'token must be defined'); if (typeof token === 'string') { return token.charCodeAt(0) || 0; diff --git a/packages/core/src/render3/instructions/di.ts b/packages/core/src/render3/instructions/di.ts index 52a4dc83f8..71578e17e8 100644 --- a/packages/core/src/render3/instructions/di.ts +++ b/packages/core/src/render3/instructions/di.ts @@ -5,10 +5,10 @@ * 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 {InjectFlags, InjectionToken, resolveForwardRef} from '../../di'; +import {InjectFlags, resolveForwardRef} from '../../di'; import {assertInjectImplementationNotEqual} from '../../di/inject_switch'; import {ɵɵinject} from '../../di/injector_compatibility'; -import {AbstractType, Type} from '../../interface/type'; +import {ProviderToken} from '../../di/provider_token'; import {getOrCreateInjectable} from '../di'; import {TDirectiveHostNode} from '../interfaces/node'; import {getCurrentTNode, getLView} from '../state'; @@ -37,11 +37,9 @@ import {getCurrentTNode, getLView} from '../state'; * * @codeGenApi */ -export function ɵɵdirectiveInject(token: Type|AbstractType|InjectionToken): T; -export function ɵɵdirectiveInject( - token: Type|AbstractType|InjectionToken, flags: InjectFlags): T; -export function ɵɵdirectiveInject( - token: Type|AbstractType|InjectionToken, flags = InjectFlags.Default): T|null { +export function ɵɵdirectiveInject(token: ProviderToken): T; +export function ɵɵdirectiveInject(token: ProviderToken, flags: InjectFlags): T; +export function ɵɵdirectiveInject(token: ProviderToken, flags = InjectFlags.Default): T|null { const lView = getLView(); // Fall back to inject() if view hasn't been created. This situation can happen in tests // if inject utilities are used before bootstrapping. diff --git a/packages/core/src/render3/interfaces/injector.ts b/packages/core/src/render3/interfaces/injector.ts index 5a06dc39fb..09b7fcd10a 100644 --- a/packages/core/src/render3/interfaces/injector.ts +++ b/packages/core/src/render3/interfaces/injector.ts @@ -6,9 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {InjectionToken} from '../../di/injection_token'; import {InjectFlags} from '../../di/interface/injector'; -import {AbstractType, Type} from '../../interface/type'; +import {ProviderToken} from '../../di/provider_token'; import {assertDefined, assertEqual} from '../../util/assert'; import {TDirectiveHostNode} from './node'; @@ -176,8 +175,7 @@ export class NodeInjectorFactory { /** * The inject implementation to be activated when using the factory. */ - injectImpl: null| - ((token: Type|AbstractType|InjectionToken, flags?: InjectFlags) => T); + injectImpl: null|((token: ProviderToken, flags?: InjectFlags) => T); /** * Marker set to true during factory invocation to see if we get into recursive loop. @@ -280,8 +278,7 @@ export class NodeInjectorFactory { * Set to `true` if the token is declared in `viewProviders` (or if it is component). */ isViewProvider: boolean, - injectImplementation: null| - ((token: Type|AbstractType|InjectionToken, flags?: InjectFlags) => T)) { + injectImplementation: null|((token: ProviderToken, flags?: InjectFlags) => T)) { ngDevMode && assertDefined(factory, 'Factory not specified'); ngDevMode && assertEqual(typeof factory, 'function', 'Expected factory function.'); this.canSeeViewProviders = isViewProvider; diff --git a/packages/core/src/render3/interfaces/query.ts b/packages/core/src/render3/interfaces/query.ts index 7281967dce..ed308022e4 100644 --- a/packages/core/src/render3/interfaces/query.ts +++ b/packages/core/src/render3/interfaces/query.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {InjectionToken} from '../../di/injection_token'; -import {Type} from '../../interface/type'; +import {ProviderToken} from '../../di/provider_token'; import {QueryList} from '../../linker/query_list'; import {TNode} from './node'; @@ -17,7 +16,7 @@ import {TView} from './view'; * An object representing query metadata extracted from query annotations. */ export interface TQueryMetadata { - predicate: Type|InjectionToken|string[]; + predicate: ProviderToken|string[]; read: any; flags: QueryFlags; } diff --git a/packages/core/src/render3/interfaces/view.ts b/packages/core/src/render3/interfaces/view.ts index ba16dcf3c9..af0202bcf6 100644 --- a/packages/core/src/render3/interfaces/view.ts +++ b/packages/core/src/render3/interfaces/view.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {InjectionToken} from '../../di/injection_token'; import {Injector} from '../../di/injector'; +import {ProviderToken} from '../../di/provider_token'; import {Type} from '../../interface/type'; import {SchemaMetadata} from '../../metadata/schema'; import {Sanitizer} from '../../sanitization/sanitizer'; @@ -904,9 +904,8 @@ export type DestroyHookData = (HookEntry|HookData)[]; * * Injector bloom filters are also stored here. */ -export type TData = - (TNode|PipeDef|DirectiveDef|ComponentDef|number|TStylingRange|TStylingKey| - Type|InjectionToken|TI18n|I18nUpdateOpCodes|TIcu|null|string)[]; +export type TData = (TNode|PipeDef|DirectiveDef|ComponentDef|number|TStylingRange| + TStylingKey|ProviderToken|TI18n|I18nUpdateOpCodes|TIcu|null|string)[]; // Note: This hack is necessary so we don't erroneously get a circular dependency // failure based on types. diff --git a/packages/core/src/render3/query.ts b/packages/core/src/render3/query.ts index 3cd7b47b2e..1c40d4599c 100644 --- a/packages/core/src/render3/query.ts +++ b/packages/core/src/render3/query.ts @@ -9,8 +9,7 @@ // We are temporarily importing the existing viewEngine_from core so we can be sure we are // correctly implementing its interfaces for backwards compatibility. -import {InjectionToken} from '../di/injection_token'; -import {Type} from '../interface/type'; +import {ProviderToken} from '../di/provider_token'; import {createElementRef, ElementRef as ViewEngine_ElementRef, unwrapElementRef} from '../linker/element_ref'; import {QueryList} from '../linker/query_list'; import {createTemplateRef, TemplateRef as ViewEngine_TemplateRef} from '../linker/template_ref'; @@ -88,7 +87,7 @@ class LQueries_ implements LQueries { class TQueryMetadata_ implements TQueryMetadata { constructor( - public predicate: Type|InjectionToken|string[], public flags: QueryFlags, + public predicate: ProviderToken|string[], public flags: QueryFlags, public read: any = null) {} } @@ -456,7 +455,7 @@ export function ɵɵqueryRefresh(queryList: QueryList): boolean { * @codeGenApi */ export function ɵɵviewQuery( - predicate: Type|InjectionToken|string[], flags: QueryFlags, read?: any): void { + predicate: ProviderToken|string[], flags: QueryFlags, read?: any): void { ngDevMode && assertNumber(flags, 'Expecting flags'); const tView = getTView(); if (tView.firstCreatePass) { @@ -481,8 +480,8 @@ export function ɵɵviewQuery( * @codeGenApi */ export function ɵɵcontentQuery( - directiveIndex: number, predicate: Type|InjectionToken|string[], - flags: QueryFlags, read?: any): void { + directiveIndex: number, predicate: ProviderToken|string[], flags: QueryFlags, + read?: any): void { ngDevMode && assertNumber(flags, 'Expecting flags'); const tView = getTView(); if (tView.firstCreatePass) { diff --git a/packages/core/testing/src/r3_test_bed.ts b/packages/core/testing/src/r3_test_bed.ts index 74804de7d6..f7d6487a26 100644 --- a/packages/core/testing/src/r3_test_bed.ts +++ b/packages/core/testing/src/r3_test_bed.ts @@ -12,7 +12,6 @@ /* clang-format off */ import { - AbstractType, Component, Directive, InjectFlags, @@ -22,6 +21,7 @@ import { NgZone, Pipe, PlatformRef, + ProviderToken, Type, ɵflushModuleScopingQueueAsMuchAsPossible as flushModuleScopingQueueAsMuchAsPossible, ɵRender3ComponentFactory as ComponentFactory, @@ -156,19 +156,14 @@ export class TestBedRender3 implements TestBed { return TestBedRender3 as any as TestBedStatic; } - static inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - static inject( - token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T - |null; - static inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, - flags?: InjectFlags): T|null { + static inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + static inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T|null; + static inject(token: ProviderToken, notFoundValue?: T|null, flags?: InjectFlags): T|null { return _getTestBedRender3().inject(token, notFoundValue, flags); } /** @deprecated from v9.0.0 use TestBed.inject */ - static get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + static get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated from v9.0.0 use TestBed.inject */ static get(token: any, notFoundValue?: any): any; /** @deprecated from v9.0.0 use TestBed.inject */ @@ -263,14 +258,9 @@ export class TestBedRender3 implements TestBed { return this.compiler.compileComponents(); } - inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T - |null; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, - flags?: InjectFlags): T|null { + inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T|null; + inject(token: ProviderToken, notFoundValue?: T|null, flags?: InjectFlags): T|null { if (token as unknown === TestBedRender3) { return this as any; } @@ -281,7 +271,7 @@ export class TestBedRender3 implements TestBed { } /** @deprecated from v9.0.0 use TestBed.inject */ - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated from v9.0.0 use TestBed.inject */ get(token: any, notFoundValue?: any): any; /** @deprecated from v9.0.0 use TestBed.inject */ diff --git a/packages/core/testing/src/test_bed.ts b/packages/core/testing/src/test_bed.ts index 4dcf1b0b9e..68c413b237 100644 --- a/packages/core/testing/src/test_bed.ts +++ b/packages/core/testing/src/test_bed.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AbstractType, ApplicationInitStatus, CompilerOptions, Component, Directive, InjectFlags, InjectionToken, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵclearOverrides as clearOverrides, ɵDepFlags as DepFlags, ɵgetInjectableDef as getInjectableDef, ɵINJECTOR_SCOPE as INJECTOR_SCOPE, ɵivyEnabled as ivyEnabled, ɵNodeFlags as NodeFlags, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify, ɵɵInjectableDeclaration} from '@angular/core'; +import {ApplicationInitStatus, CompilerOptions, Component, Directive, InjectFlags, InjectionToken, Injector, NgModule, NgModuleFactory, NgModuleRef, NgZone, Optional, Pipe, PlatformRef, Provider, ProviderToken, SchemaMetadata, SkipSelf, StaticProvider, Type, ɵclearOverrides as clearOverrides, ɵDepFlags as DepFlags, ɵgetInjectableDef as getInjectableDef, ɵINJECTOR_SCOPE as INJECTOR_SCOPE, ɵivyEnabled as ivyEnabled, ɵNodeFlags as NodeFlags, ɵoverrideComponentView as overrideComponentView, ɵoverrideProvider as overrideProvider, ɵstringify as stringify, ɵɵInjectableDeclaration} from '@angular/core'; import {AsyncTestCompleter} from './async_test_completer'; import {ComponentFixture} from './component_fixture'; @@ -53,14 +53,11 @@ export interface TestBed { compileComponents(): Promise; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T - |null; + inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T|null; /** @deprecated from v9.0.0 use TestBed.inject */ - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated from v9.0.0 use TestBed.inject */ get(token: any, notFoundValue?: any): any; @@ -216,19 +213,14 @@ export class TestBedViewEngine implements TestBed { return TestBedViewEngine as any as TestBedStatic; } - static inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - static inject( - token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T - |null; - static inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, - flags?: InjectFlags): T|null { + static inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + static inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T|null; + static inject(token: ProviderToken, notFoundValue?: T|null, flags?: InjectFlags): T|null { return _getTestBedViewEngine().inject(token, notFoundValue, flags); } /** @deprecated from v9.0.0 use TestBed.inject */ - static get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + static get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** * @deprecated from v9.0.0 use TestBed.inject * @suppress {duplicate} @@ -469,14 +461,9 @@ export class TestBedViewEngine implements TestBed { } } - inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T - |null; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T|null, - flags?: InjectFlags): T|null { + inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T|null; + inject(token: ProviderToken, notFoundValue?: T|null, flags?: InjectFlags): T|null { this._initIfNeeded(); if (token as unknown === TestBed) { return this as any; @@ -490,7 +477,7 @@ export class TestBedViewEngine implements TestBed { } /** @deprecated from v9.0.0 use TestBed.inject */ - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated from v9.0.0 use TestBed.inject */ get(token: any, notFoundValue?: any): any; /** @deprecated from v9.0.0 use TestBed.inject */ diff --git a/packages/core/testing/src/test_bed_common.ts b/packages/core/testing/src/test_bed_common.ts index 48cfad0452..76163253aa 100644 --- a/packages/core/testing/src/test_bed_common.ts +++ b/packages/core/testing/src/test_bed_common.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AbstractType, Component, Directive, InjectFlags, InjectionToken, NgModule, Pipe, PlatformRef, SchemaMetadata, Type} from '@angular/core'; +import {Component, Directive, InjectFlags, InjectionToken, NgModule, Pipe, PlatformRef, ProviderToken, SchemaMetadata, Type} from '@angular/core'; import {ComponentFixture} from './component_fixture'; import {MetadataOverride} from './metadata_override'; @@ -114,14 +114,11 @@ export interface TestBedStatic { deps?: any[], }): TestBedStatic; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue?: T, flags?: InjectFlags): T; - inject( - token: Type|InjectionToken|AbstractType, notFoundValue: null, flags?: InjectFlags): T - |null; + inject(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): T; + inject(token: ProviderToken, notFoundValue: null, flags?: InjectFlags): T|null; /** @deprecated from v9.0.0 use TestBed.inject */ - get(token: Type|InjectionToken, notFoundValue?: T, flags?: InjectFlags): any; + get(token: ProviderToken, notFoundValue?: T, flags?: InjectFlags): any; /** @deprecated from v9.0.0 use TestBed.inject */ get(token: any, notFoundValue?: any): any; diff --git a/packages/examples/core/di/ts/injector_spec.ts b/packages/examples/core/di/ts/injector_spec.ts index dcb0037298..01fb555e7e 100644 --- a/packages/examples/core/di/ts/injector_spec.ts +++ b/packages/examples/core/di/ts/injector_spec.ts @@ -6,14 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {AbstractType, inject, InjectFlags, InjectionToken, Injector, Type, ɵsetCurrentInjector as setCurrentInjector} from '@angular/core'; +import {inject, InjectFlags, InjectionToken, Injector, ProviderToken, ɵsetCurrentInjector as setCurrentInjector} from '@angular/core'; class MockRootScopeInjector implements Injector { constructor(readonly parent: Injector) {} - get( - token: Type|AbstractType|InjectionToken, defaultValue?: any, - flags: InjectFlags = InjectFlags.Default): T { + get(token: ProviderToken, defaultValue?: any, flags: InjectFlags = InjectFlags.Default): T { if ((token as any).ɵprov && (token as any).ɵprov.providedIn === 'root') { const old = setCurrentInjector(this); try {