static-injector 1.0.10 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/import/commonjs/index.js +337 -124
- package/import/es2015/di/create_injector.js +30 -0
- package/import/es2015/di/initializer_token.js +15 -0
- package/import/es2015/di/inject_switch.js +27 -6
- package/import/es2015/di/injection_token.js +6 -0
- package/import/es2015/di/injector.js +6 -8
- package/import/es2015/di/injector_compatibility.js +90 -34
- package/import/es2015/di/injector_token.js +1 -1
- package/import/es2015/di/interface/defs.js +39 -0
- package/import/es2015/di/interface/injector.js +1 -0
- package/import/es2015/di/internal_tokens.js +9 -0
- package/import/es2015/di/metadata.js +4 -4
- package/import/es2015/di/provider_collection.js +49 -0
- package/import/es2015/di/r3_injector.js +102 -72
- package/import/es2015/di/scope.js +2 -2
- package/import/es2015/index.js +1 -1
- package/import/es2015/render3/errors_di.js +1 -1
- package/import/fesm2015/index.js +328 -114
- package/import/typings/di/create_injector.d.ts +23 -0
- package/import/typings/di/initializer_token.d.ts +15 -0
- package/import/typings/di/inject_switch.d.ts +7 -2
- package/import/typings/{decorator → di}/injectable.d.ts +2 -2
- package/import/typings/di/injection_token.d.ts +4 -0
- package/import/typings/di/injector.d.ts +20 -7
- package/import/typings/di/injector_compatibility.d.ts +42 -21
- package/import/typings/di/interface/defs.d.ts +10 -0
- package/import/typings/di/interface/injector.d.ts +26 -0
- package/import/typings/di/interface/provider.d.ts +3 -8
- package/import/typings/di/internal_tokens.d.ts +10 -0
- package/import/typings/di/provider_collection.d.ts +30 -0
- package/import/typings/di/provider_token.d.ts +1 -1
- package/import/typings/di/r3_injector.d.ts +68 -37
- package/import/typings/di/scope.d.ts +3 -2
- package/import/typings/index.d.ts +1 -1
- package/import/typings/render3/definition_factory.d.ts +1 -1
- package/package.json +5 -3
- package/{import/es2015/decorator/interface/provider.js → transform/compiler/compiler.d.ts} +1 -1
- package/transform/compiler/compiler.js +28 -0
- package/transform/compiler/index.d.ts +8 -5
- package/transform/compiler/index.js +17 -6
- package/transform/compiler/public_api.d.ts +13 -0
- package/transform/compiler/public_api.js +30 -0
- package/transform/compiler/src/compiler.d.ts +27 -0
- package/transform/compiler/src/compiler.js +47 -0
- package/transform/compiler/src/injectable_compiler_2.d.ts +7 -36
- package/transform/compiler/src/injectable_compiler_2.js +20 -23
- package/transform/compiler/src/output/output_ast.d.ts +30 -109
- package/transform/compiler/src/output/output_ast.js +66 -188
- package/transform/compiler/src/render3/partial/api.d.ts +1 -1
- package/transform/compiler/src/render3/partial/api.js +7 -0
- package/transform/compiler/src/render3/r3_factory.d.ts +8 -15
- package/transform/compiler/src/render3/r3_factory.js +46 -61
- package/transform/compiler/src/render3/util.d.ts +64 -0
- package/transform/compiler/src/render3/util.js +52 -9
- package/transform/compiler/src/render3/view/util.d.ts +0 -8
- package/transform/compiler/src/render3/view/util.js +5 -9
- package/transform/compiler-cli/src/ngtsc/annotations/common/index.d.ts +10 -0
- package/transform/compiler-cli/src/ngtsc/annotations/common/index.js +26 -0
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.d.ts +37 -0
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +197 -0
- package/transform/compiler-cli/src/ngtsc/annotations/{src → common/src}/factory.d.ts +3 -3
- package/transform/compiler-cli/src/ngtsc/annotations/{src → common/src}/factory.js +3 -3
- package/transform/compiler-cli/src/ngtsc/annotations/{src → common/src}/util.d.ts +4 -34
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +181 -0
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +3 -4
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +46 -53
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.js +6 -2
- package/transform/compiler-cli/src/ngtsc/diagnostics/index.d.ts +9 -2
- package/transform/compiler-cli/src/ngtsc/diagnostics/index.js +12 -1
- package/transform/compiler-cli/src/ngtsc/imports/index.d.ts +7 -0
- package/transform/compiler-cli/src/ngtsc/imports/index.js +12 -1
- package/transform/compiler-cli/src/ngtsc/imports/src/default.d.ts +19 -0
- package/transform/compiler-cli/src/ngtsc/imports/src/default.js +28 -0
- package/transform/compiler-cli/src/ngtsc/reflection/index.d.ts +10 -3
- package/transform/compiler-cli/src/ngtsc/reflection/index.js +12 -1
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +13 -14
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +8 -25
- package/transform/compiler-cli/src/ngtsc/reflection/src/type_to_value.d.ts +2 -2
- package/transform/compiler-cli/src/ngtsc/reflection/src/type_to_value.js +44 -55
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +1 -1
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +55 -69
- package/transform/compiler-cli/src/ngtsc/reflection/src/util.d.ts +2 -2
- package/transform/compiler-cli/src/ngtsc/reflection/src/util.js +7 -23
- package/transform/compiler-cli/src/ngtsc/transform/index.d.ts +9 -2
- package/transform/compiler-cli/src/ngtsc/transform/index.js +12 -1
- package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +4 -4
- package/transform/compiler-cli/src/ngtsc/transform/src/utils.d.ts +2 -2
- package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +16 -31
- package/transform/compiler-cli/src/ngtsc/translator/index.d.ts +12 -5
- package/transform/compiler-cli/src/ngtsc/translator/index.js +12 -1
- package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +5 -5
- package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.d.ts +4 -4
- package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +5 -21
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +2 -6
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +6 -18
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +3 -6
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +83 -90
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_translator.d.ts +4 -4
- package/transform/compiler-cli/src/ngtsc/ts_compatibility/index.d.ts +8 -0
- package/transform/compiler-cli/src/ngtsc/ts_compatibility/index.js +24 -0
- package/transform/compiler-cli/src/ngtsc/ts_compatibility/src/ts_cross_version_utils.d.ts +45 -0
- package/transform/compiler-cli/src/ngtsc/ts_compatibility/src/ts_cross_version_utils.js +86 -0
- package/transform/compiler-cli/src/ngtsc/util/src/typescript.d.ts +1 -8
- package/transform/compiler-cli/src/ngtsc/util/src/typescript.js +4 -27
- package/transform/index.js +5 -1
- package/transform/injectable-transform.js +59 -38
- package/import/typings/decorator/interface/provider.d.ts +0 -312
- package/transform/compiler/src/render3/partial/util.d.ts +0 -16
- package/transform/compiler/src/render3/partial/util.js +0 -44
- package/transform/compiler-cli/src/ngtsc/annotations/src/util.js +0 -370
- /package/import/es2015/{decorator → di}/injectable.js +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { EMPTY_ARRAY } from '../util/empty';
|
|
9
|
+
import { stringify } from '../util/stringify';
|
|
10
|
+
import { getNullInjector, R3Injector } from './r3_injector';
|
|
11
|
+
/**
|
|
12
|
+
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
13
|
+
*
|
|
14
|
+
* @publicApi
|
|
15
|
+
*/
|
|
16
|
+
export function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
17
|
+
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
18
|
+
injector.resolveInjectorInitializers();
|
|
19
|
+
return injector;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new injector without eagerly resolving its injector types. Can be used in places
|
|
23
|
+
* where resolving the injector types immediately can lead to an infinite loop. The injector types
|
|
24
|
+
* should be resolved at a later point by calling `_resolveInjectorDefTypes`.
|
|
25
|
+
*/
|
|
26
|
+
export function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
|
|
27
|
+
const providers = [additionalProviders || EMPTY_ARRAY];
|
|
28
|
+
name = name || (typeof defType === 'object' ? undefined : stringify(defType));
|
|
29
|
+
return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { InjectionToken } from './injection_token';
|
|
9
|
+
/**
|
|
10
|
+
* A multi-provider token for initialization functions that will run upon construction of an
|
|
11
|
+
* environment injector.
|
|
12
|
+
*
|
|
13
|
+
* @publicApi
|
|
14
|
+
*/
|
|
15
|
+
export const ENVIRONMENT_INITIALIZER = new InjectionToken('ENVIRONMENT_INITIALIZER');
|
|
@@ -5,10 +5,31 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import { throwProviderNotFoundError } from
|
|
9
|
-
import { stringify } from
|
|
10
|
-
import { getInjectableDef } from
|
|
11
|
-
import { InjectFlags } from
|
|
8
|
+
import { throwProviderNotFoundError } from '../render3/errors_di';
|
|
9
|
+
import { stringify } from '../util/stringify';
|
|
10
|
+
import { getInjectableDef } from './interface/defs';
|
|
11
|
+
import { InjectFlags } from './interface/injector';
|
|
12
|
+
/**
|
|
13
|
+
* Current implementation of inject.
|
|
14
|
+
*
|
|
15
|
+
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
|
|
16
|
+
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
|
|
17
|
+
* way for two reasons:
|
|
18
|
+
* 1. `Injector` should not depend on ivy logic.
|
|
19
|
+
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
|
|
20
|
+
*/
|
|
21
|
+
let _injectImplementation;
|
|
22
|
+
export function getInjectImplementation() {
|
|
23
|
+
return _injectImplementation;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sets the current inject implementation.
|
|
27
|
+
*/
|
|
28
|
+
export function setInjectImplementation(impl) {
|
|
29
|
+
const previous = _injectImplementation;
|
|
30
|
+
_injectImplementation = impl;
|
|
31
|
+
return previous;
|
|
32
|
+
}
|
|
12
33
|
/**
|
|
13
34
|
* Injects `root` tokens in limp mode.
|
|
14
35
|
*
|
|
@@ -18,7 +39,7 @@ import { InjectFlags } from "./interface/injector";
|
|
|
18
39
|
*/
|
|
19
40
|
export function injectRootLimpMode(token, notFoundValue, flags) {
|
|
20
41
|
const injectableDef = getInjectableDef(token);
|
|
21
|
-
if (injectableDef && injectableDef.providedIn ==
|
|
42
|
+
if (injectableDef && injectableDef.providedIn == 'root') {
|
|
22
43
|
return injectableDef.value === undefined
|
|
23
44
|
? (injectableDef.value = injectableDef.factory())
|
|
24
45
|
: injectableDef.value;
|
|
@@ -27,5 +48,5 @@ export function injectRootLimpMode(token, notFoundValue, flags) {
|
|
|
27
48
|
return null;
|
|
28
49
|
if (notFoundValue !== undefined)
|
|
29
50
|
return notFoundValue;
|
|
30
|
-
throwProviderNotFoundError(stringify(token),
|
|
51
|
+
throwProviderNotFoundError(stringify(token), 'Injector');
|
|
31
52
|
}
|
|
@@ -5,15 +5,11 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
+
import { createInjector } from './create_injector';
|
|
8
9
|
import { THROW_IF_NOT_FOUND, ɵɵinject } from './injector_compatibility';
|
|
9
10
|
import { INJECTOR } from './injector_token';
|
|
10
11
|
import { ɵɵdefineInjectable } from './interface/defs';
|
|
11
12
|
import { NullInjector } from './null_injector';
|
|
12
|
-
import { createInjector } from './r3_injector';
|
|
13
|
-
export function INJECTOR_IMPL__POST_R3__(providers, parent, name) {
|
|
14
|
-
return createInjector({ name: name }, parent, providers, name);
|
|
15
|
-
}
|
|
16
|
-
export const INJECTOR_IMPL = INJECTOR_IMPL__POST_R3__;
|
|
17
13
|
/**
|
|
18
14
|
* Concrete injectors implement this interface. Injectors are configured
|
|
19
15
|
* with [providers](guide/glossary#provider) that associate
|
|
@@ -40,11 +36,13 @@ export const INJECTOR_IMPL = INJECTOR_IMPL__POST_R3__;
|
|
|
40
36
|
*/
|
|
41
37
|
export class Injector {
|
|
42
38
|
static create(options, parent) {
|
|
39
|
+
var _a;
|
|
43
40
|
if (Array.isArray(options)) {
|
|
44
|
-
return
|
|
41
|
+
return createInjector({ name: '' }, parent, options, '');
|
|
45
42
|
}
|
|
46
43
|
else {
|
|
47
|
-
|
|
44
|
+
const name = (_a = options.name) !== null && _a !== void 0 ? _a : '';
|
|
45
|
+
return createInjector({ name }, options.parent, options.providers, name);
|
|
48
46
|
}
|
|
49
47
|
}
|
|
50
48
|
}
|
|
@@ -60,4 +58,4 @@ Injector.ɵprov = ɵɵdefineInjectable({
|
|
|
60
58
|
* @internal
|
|
61
59
|
* @nocollapse
|
|
62
60
|
*/
|
|
63
|
-
Injector.__NG_ELEMENT_ID__ = -1 /* Injector */;
|
|
61
|
+
Injector.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
|
-
import { getClosureSafeProperty } from
|
|
9
|
-
import { stringify } from
|
|
10
|
-
import { resolveForwardRef } from
|
|
11
|
-
import { injectRootLimpMode } from
|
|
12
|
-
import { InjectFlags, } from
|
|
8
|
+
import { getClosureSafeProperty } from '../util/property';
|
|
9
|
+
import { stringify } from '../util/stringify';
|
|
10
|
+
import { resolveForwardRef } from './forward_ref';
|
|
11
|
+
import { injectRootLimpMode } from './inject_switch';
|
|
12
|
+
import { InjectFlags, } from './interface/injector';
|
|
13
13
|
const _THROW_IF_NOT_FOUND = {};
|
|
14
14
|
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
|
15
15
|
/*
|
|
@@ -17,12 +17,12 @@ export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
|
|
17
17
|
* InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators
|
|
18
18
|
* in the code, thus making them tree-shakable.
|
|
19
19
|
*/
|
|
20
|
-
const DI_DECORATOR_FLAG =
|
|
21
|
-
export const NG_TEMP_TOKEN_PATH =
|
|
22
|
-
const NG_TOKEN_PATH =
|
|
20
|
+
const DI_DECORATOR_FLAG = '__NG_DI_FLAG__';
|
|
21
|
+
export const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
|
|
22
|
+
const NG_TOKEN_PATH = 'ngTokenPath';
|
|
23
23
|
const NEW_LINE = /\n/gm;
|
|
24
|
-
const NO_NEW_LINE =
|
|
25
|
-
export const SOURCE =
|
|
24
|
+
const NO_NEW_LINE = 'ɵ';
|
|
25
|
+
export const SOURCE = '__source';
|
|
26
26
|
export const USE_VALUE = getClosureSafeProperty({
|
|
27
27
|
provide: String,
|
|
28
28
|
useValue: getClosureSafeProperty,
|
|
@@ -55,45 +55,101 @@ export function ɵɵinject(token, flags = InjectFlags.Default) {
|
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* Injects a token from the currently active injector.
|
|
58
|
+
* `inject` is only supported during instantiation of a dependency by the DI system. It can be used
|
|
59
|
+
* during:
|
|
60
|
+
* - Construction (via the `constructor`) of a class being instantiated by the DI system, such
|
|
61
|
+
* as an `@Injectable` or `@Component`.
|
|
62
|
+
* - In the initializer for fields of such classes.
|
|
63
|
+
* - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
|
|
64
|
+
* - In the `factory` function specified for an `InjectionToken`.
|
|
58
65
|
*
|
|
59
|
-
*
|
|
60
|
-
* `InjectionToken`. Throws an error if not called from such a context.
|
|
61
|
-
*
|
|
62
|
-
* Within such a factory function, using this function to request injection of a dependency
|
|
63
|
-
* is faster and more type-safe than providing an additional array of dependencies
|
|
64
|
-
* (as has been common with `useFactory` providers).
|
|
65
|
-
*
|
|
66
|
-
* @param token The injection token for the dependency to be injected.
|
|
66
|
+
* @param token A token that represents a dependency that should be injected.
|
|
67
67
|
* @param flags Optional flags that control how injection is executed.
|
|
68
68
|
* The flags correspond to injection strategies that can be specified with
|
|
69
69
|
* parameter decorators `@Host`, `@Self`, `@SkipSef`, and `@Optional`.
|
|
70
|
-
* @returns the injected value if
|
|
70
|
+
* @returns the injected value if operation is successful, `null` otherwise.
|
|
71
|
+
* @throws if called outside of a supported context.
|
|
71
72
|
*
|
|
72
73
|
* @usageNotes
|
|
74
|
+
* In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
|
|
75
|
+
* field initializer:
|
|
76
|
+
*
|
|
77
|
+
* ```typescript
|
|
78
|
+
* @Injectable({providedIn: 'root'})
|
|
79
|
+
* export class Car {
|
|
80
|
+
* radio: Radio|undefined;
|
|
81
|
+
* // OK: field initializer
|
|
82
|
+
* spareTyre = inject(Tyre);
|
|
83
|
+
*
|
|
84
|
+
* constructor() {
|
|
85
|
+
* // OK: constructor body
|
|
86
|
+
* this.radio = inject(Radio);
|
|
87
|
+
* }
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* It is also legal to call `inject` from a provider's factory:
|
|
73
92
|
*
|
|
74
|
-
*
|
|
93
|
+
* ```typescript
|
|
94
|
+
* providers: [
|
|
95
|
+
* {provide: Car, useFactory: () => {
|
|
96
|
+
* // OK: a class factory
|
|
97
|
+
* const engine = inject(Engine);
|
|
98
|
+
* return new Car(engine);
|
|
99
|
+
* }}
|
|
100
|
+
* ]
|
|
101
|
+
* ```
|
|
75
102
|
*
|
|
76
|
-
*
|
|
103
|
+
* Calls to the `inject()` function outside of the class creation context will result in error. Most
|
|
104
|
+
* notably, calls to `inject()` are disallowed after a class instance was created, in methods
|
|
105
|
+
* (including lifecycle hooks):
|
|
106
|
+
*
|
|
107
|
+
* ```typescript
|
|
108
|
+
* @Component({ ... })
|
|
109
|
+
* export class CarComponent {
|
|
110
|
+
* ngOnInit() {
|
|
111
|
+
* // ERROR: too late, the component instance was already created
|
|
112
|
+
* const engine = inject(Engine);
|
|
113
|
+
* engine.start();
|
|
114
|
+
* }
|
|
115
|
+
* }
|
|
116
|
+
* ```
|
|
77
117
|
*
|
|
78
118
|
* @publicApi
|
|
79
119
|
*/
|
|
80
|
-
export
|
|
120
|
+
export function inject(token, flags = InjectFlags.Default) {
|
|
121
|
+
return ɵɵinject(token, convertToBitFlags(flags));
|
|
122
|
+
}
|
|
123
|
+
// Converts object-based DI flags (`InjectOptions`) to bit flags (`InjectFlags`).
|
|
124
|
+
export function convertToBitFlags(flags) {
|
|
125
|
+
if (typeof flags === 'undefined' || typeof flags === 'number') {
|
|
126
|
+
return flags;
|
|
127
|
+
}
|
|
128
|
+
// While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
|
|
129
|
+
// JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
|
|
130
|
+
// `InjectOptions` to `InjectFlags`.
|
|
131
|
+
return (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
|
|
132
|
+
(flags.optional && 8 /* InternalInjectFlags.Optional */) |
|
|
133
|
+
(flags.self && 2 /* InternalInjectFlags.Self */) |
|
|
134
|
+
(flags.skipSelf &&
|
|
135
|
+
4 /* InternalInjectFlags.SkipSelf */));
|
|
136
|
+
}
|
|
81
137
|
export function injectArgs(types) {
|
|
82
138
|
const args = [];
|
|
83
139
|
for (let i = 0; i < types.length; i++) {
|
|
84
140
|
const arg = resolveForwardRef(types[i]);
|
|
85
141
|
if (Array.isArray(arg)) {
|
|
86
142
|
if (arg.length === 0) {
|
|
87
|
-
throw new Error(
|
|
143
|
+
throw new Error('Arguments array must have arguments.');
|
|
88
144
|
}
|
|
89
145
|
let type = undefined;
|
|
90
146
|
let flags = InjectFlags.Default;
|
|
91
147
|
for (let j = 0; j < arg.length; j++) {
|
|
92
148
|
const meta = arg[j];
|
|
93
149
|
const flag = getInjectFlag(meta);
|
|
94
|
-
if (typeof flag ===
|
|
150
|
+
if (typeof flag === 'number') {
|
|
95
151
|
// Special case when we handle @Inject decorator.
|
|
96
|
-
if (flag === -1 /* Inject */) {
|
|
152
|
+
if (flag === -1 /* DecoratorFlags.Inject */) {
|
|
97
153
|
type = meta.token;
|
|
98
154
|
}
|
|
99
155
|
else {
|
|
@@ -140,33 +196,33 @@ export function catchInjectorError(e, token, injectorErrorName, source) {
|
|
|
140
196
|
if (token[SOURCE]) {
|
|
141
197
|
tokenPath.unshift(token[SOURCE]);
|
|
142
198
|
}
|
|
143
|
-
e.message = formatError(
|
|
199
|
+
e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
|
|
144
200
|
e[NG_TOKEN_PATH] = tokenPath;
|
|
145
201
|
e[NG_TEMP_TOKEN_PATH] = null;
|
|
146
202
|
throw e;
|
|
147
203
|
}
|
|
148
204
|
export function formatError(text, obj, injectorErrorName, source = null) {
|
|
149
205
|
text =
|
|
150
|
-
text && text.charAt(0) ===
|
|
151
|
-
? text.
|
|
206
|
+
text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE
|
|
207
|
+
? text.slice(2)
|
|
152
208
|
: text;
|
|
153
209
|
let context = stringify(obj);
|
|
154
210
|
if (Array.isArray(obj)) {
|
|
155
|
-
context = obj.map(stringify).join(
|
|
211
|
+
context = obj.map(stringify).join(' -> ');
|
|
156
212
|
}
|
|
157
|
-
else if (typeof obj ===
|
|
213
|
+
else if (typeof obj === 'object') {
|
|
158
214
|
let parts = [];
|
|
159
215
|
for (let key in obj) {
|
|
160
216
|
if (obj.hasOwnProperty(key)) {
|
|
161
217
|
let value = obj[key];
|
|
162
218
|
parts.push(key +
|
|
163
|
-
|
|
164
|
-
(typeof value ===
|
|
219
|
+
':' +
|
|
220
|
+
(typeof value === 'string'
|
|
165
221
|
? JSON.stringify(value)
|
|
166
222
|
: stringify(value)));
|
|
167
223
|
}
|
|
168
224
|
}
|
|
169
|
-
context = `{${parts.join(
|
|
225
|
+
context = `{${parts.join(', ')}}`;
|
|
170
226
|
}
|
|
171
|
-
return `${injectorErrorName}${source ?
|
|
227
|
+
return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n ')}`;
|
|
172
228
|
}
|
|
@@ -17,5 +17,5 @@ import { InjectionToken } from "./injection_token";
|
|
|
17
17
|
export const INJECTOR = new InjectionToken("INJECTOR",
|
|
18
18
|
// Dissable tslint because this is const enum which gets inlined not top level prop access.
|
|
19
19
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
20
|
-
-1 /* Injector */ // Special value used by Ivy to identify `Injector`.
|
|
20
|
+
-1 /* InjectorMarkers.Injector */ // Special value used by Ivy to identify `Injector`.
|
|
21
21
|
);
|
|
@@ -70,3 +70,42 @@ function getOwnDefinition(type, field) {
|
|
|
70
70
|
export const NG_PROV_DEF = getClosureSafeProperty({
|
|
71
71
|
ɵprov: getClosureSafeProperty,
|
|
72
72
|
});
|
|
73
|
+
/**
|
|
74
|
+
* Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
|
|
75
|
+
*
|
|
76
|
+
* @param type A type which may have `ɵprov`, via inheritance.
|
|
77
|
+
*
|
|
78
|
+
* @deprecated Will be removed in a future version of Angular, where an error will occur in the
|
|
79
|
+
* scenario if we find the `ɵprov` on an ancestor only.
|
|
80
|
+
*/
|
|
81
|
+
export function getInheritedInjectableDef(type) {
|
|
82
|
+
const def = type && (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]);
|
|
83
|
+
if (def) {
|
|
84
|
+
const typeName = getTypeName(type);
|
|
85
|
+
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
|
86
|
+
// ngDevMode &&
|
|
87
|
+
console.warn(`DEPRECATED: DI is instantiating a token "${typeName}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
|
88
|
+
`This will become an error in a future version of Angular. Please add @Injectable() to the "${typeName}" class.`);
|
|
89
|
+
return def;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export const NG_INJECTABLE_DEF = getClosureSafeProperty({
|
|
96
|
+
ngInjectableDef: getClosureSafeProperty,
|
|
97
|
+
});
|
|
98
|
+
/** Gets the name of a type, accounting for some cross-browser differences. */
|
|
99
|
+
function getTypeName(type) {
|
|
100
|
+
// `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
|
|
101
|
+
// it'll always return the name of the function itself, no matter how many other functions it
|
|
102
|
+
// inherits from. On IE the function doesn't have its own `name` property, but it takes it from
|
|
103
|
+
// the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
|
|
104
|
+
// browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
|
|
105
|
+
// the issue by converting the function to a string and parsing its name out that way via a regex.
|
|
106
|
+
if (type.hasOwnProperty('name')) {
|
|
107
|
+
return type.name;
|
|
108
|
+
}
|
|
109
|
+
const match = ('' + type).match(/^function\s*([^\s(]+)/);
|
|
110
|
+
return match === null ? '' : match[1];
|
|
111
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { InjectionToken } from './injection_token';
|
|
9
|
+
export const INJECTOR_DEF_TYPES = new InjectionToken('INJECTOR_DEF_TYPES');
|
|
@@ -16,7 +16,7 @@ import { attachInjectFlag } from './injector_compatibility';
|
|
|
16
16
|
export const Inject = attachInjectFlag(
|
|
17
17
|
// Disable tslint because `DecoratorFlags` is a const enum which gets inlined.
|
|
18
18
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
19
|
-
makeParamDecorator('Inject', (token) => ({ token })), -1 /* Inject */);
|
|
19
|
+
makeParamDecorator('Inject', (token) => ({ token })), -1 /* DecoratorFlags.Inject */);
|
|
20
20
|
/**
|
|
21
21
|
* Optional decorator and metadata.
|
|
22
22
|
*
|
|
@@ -26,7 +26,7 @@ makeParamDecorator('Inject', (token) => ({ token })), -1 /* Inject */);
|
|
|
26
26
|
export const Optional =
|
|
27
27
|
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
|
|
28
28
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
29
|
-
attachInjectFlag(makeParamDecorator('Optional'), 8 /* Optional */);
|
|
29
|
+
attachInjectFlag(makeParamDecorator('Optional'), 8 /* InternalInjectFlags.Optional */);
|
|
30
30
|
/**
|
|
31
31
|
* Self decorator and metadata.
|
|
32
32
|
*
|
|
@@ -36,7 +36,7 @@ attachInjectFlag(makeParamDecorator('Optional'), 8 /* Optional */);
|
|
|
36
36
|
export const Self =
|
|
37
37
|
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
|
|
38
38
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
39
|
-
attachInjectFlag(makeParamDecorator('Self'), 2 /* Self */);
|
|
39
|
+
attachInjectFlag(makeParamDecorator('Self'), 2 /* InternalInjectFlags.Self */);
|
|
40
40
|
/**
|
|
41
41
|
* `SkipSelf` decorator and metadata.
|
|
42
42
|
*
|
|
@@ -46,4 +46,4 @@ attachInjectFlag(makeParamDecorator('Self'), 2 /* Self */);
|
|
|
46
46
|
export const SkipSelf =
|
|
47
47
|
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
|
|
48
48
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
49
|
-
attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* SkipSelf */);
|
|
49
|
+
attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* InternalInjectFlags.SkipSelf */);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { getClosureSafeProperty } from '../util/property';
|
|
9
|
+
import { resolveForwardRef } from './forward_ref';
|
|
10
|
+
/**
|
|
11
|
+
* The logic visits an `InjectorType`, an `InjectorTypeWithProviders`, or a standalone
|
|
12
|
+
* `ComponentType`, and all of its transitive providers and collects providers.
|
|
13
|
+
*
|
|
14
|
+
* If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
|
|
15
|
+
* the function will return "true" to indicate that the providers of the type definition need
|
|
16
|
+
* to be processed. This allows us to process providers of injector types after all imports of
|
|
17
|
+
* an injector definition are processed. (following View Engine semantics: see FW-1349)
|
|
18
|
+
*/
|
|
19
|
+
export function walkProviderTree(container, providersOut, parents, dedup) {
|
|
20
|
+
container = resolveForwardRef(container);
|
|
21
|
+
if (!container)
|
|
22
|
+
return false;
|
|
23
|
+
// The actual type which had the definition. Usually `container`, but may be an unwrapped type
|
|
24
|
+
// from `InjectorTypeWithProviders`.
|
|
25
|
+
let defType = null;
|
|
26
|
+
defType = container;
|
|
27
|
+
// Check for multiple imports of the same module
|
|
28
|
+
return (defType !== container &&
|
|
29
|
+
container.providers !== undefined);
|
|
30
|
+
}
|
|
31
|
+
export const USE_VALUE = getClosureSafeProperty({
|
|
32
|
+
provide: String,
|
|
33
|
+
useValue: getClosureSafeProperty,
|
|
34
|
+
});
|
|
35
|
+
export function isValueProvider(value) {
|
|
36
|
+
return value !== null && typeof value == 'object' && USE_VALUE in value;
|
|
37
|
+
}
|
|
38
|
+
export function isExistingProvider(value) {
|
|
39
|
+
return !!(value && value.useExisting);
|
|
40
|
+
}
|
|
41
|
+
export function isFactoryProvider(value) {
|
|
42
|
+
return !!(value && value.useFactory);
|
|
43
|
+
}
|
|
44
|
+
export function isTypeProvider(value) {
|
|
45
|
+
return typeof value === 'function';
|
|
46
|
+
}
|
|
47
|
+
export function isClassProvider(value) {
|
|
48
|
+
return !!value.useClass;
|
|
49
|
+
}
|