static-injector 2.1.0 → 2.2.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 +403 -211
- package/import/{es2015 → es2022}/di/create_injector.js +5 -3
- package/import/{es2015 → es2022}/di/forward_ref.js +32 -5
- package/import/{es2015 → es2022}/di/injection_token.js +20 -11
- package/import/{es2015 → es2022}/di/injector.js +15 -16
- package/import/{es2015 → es2022}/di/injector_compatibility.js +27 -13
- package/import/{es2015 → es2022}/di/injector_token.js +3 -3
- package/import/{es2015 → es2022}/di/interface/defs.js +22 -27
- package/import/{es2015 → es2022}/di/interface/injector.js +1 -1
- package/import/{es2015 → es2022}/di/interface/provider.js +3 -1
- package/import/{es2015 → es2022}/di/null_injector.js +3 -3
- package/import/es2022/di/provider_collection.js +104 -0
- package/import/{es2015 → es2022}/di/r3_injector.js +71 -37
- package/import/es2022/error_details_base_url.js +19 -0
- package/import/es2022/errors.js +44 -0
- package/import/es2022/interface/type.js +21 -0
- package/import/{es2015 → es2022}/render3/definition_factory.js +2 -3
- package/import/{es2015 → es2022}/render3/error_code.js +1 -0
- package/import/{es2015 → es2022}/render3/errors_di.js +2 -3
- package/import/es2022/render3/fields.js +22 -0
- package/import/{es2015 → es2022}/render3/instructions/di.js +0 -7
- package/import/{es2015 → es2022}/render3/util/stringify_utils.js +5 -5
- package/import/{es2015 → es2022}/util/array_utils.js +0 -7
- package/import/es2022/util/decorators.js +53 -0
- package/import/{es2015 → es2022}/util/empty.js +4 -0
- package/import/{es2015 → es2022}/util/stringify.js +5 -5
- package/import/{fesm2015 → fesm2022}/index.js +399 -209
- package/import/typings/di/create_injector.d.ts +3 -5
- package/import/typings/di/forward_ref.d.ts +30 -3
- package/import/typings/di/inject_switch.d.ts +1 -1
- package/import/typings/di/injectable.d.ts +4 -3
- package/import/typings/di/injection_token.d.ts +21 -6
- package/import/typings/di/injector.d.ts +19 -3
- package/import/typings/di/injector_compatibility.d.ts +12 -5
- package/import/typings/di/injector_token.d.ts +2 -2
- package/import/typings/di/interface/defs.d.ts +17 -9
- package/import/typings/di/interface/injector.d.ts +2 -2
- package/import/typings/di/interface/provider.d.ts +64 -4
- package/import/typings/di/metadata.d.ts +4 -4
- package/import/typings/di/null_injector.d.ts +1 -1
- package/import/typings/di/provider_collection.d.ts +53 -11
- package/import/typings/di/provider_token.d.ts +2 -2
- package/import/typings/di/r3_injector.d.ts +11 -14
- package/import/typings/di/scope.d.ts +1 -1
- package/import/typings/error_details_base_url.d.ts +19 -0
- package/import/typings/errors.d.ts +114 -0
- package/import/typings/interface/type.d.ts +45 -0
- package/import/typings/render3/errors_di.d.ts +7 -0
- package/import/typings/render3/fields.d.ts +9 -0
- package/import/typings/render3/instructions/di.d.ts +0 -7
- package/import/typings/util/array_utils.d.ts +15 -7
- package/import/typings/util/decorators.d.ts +3 -1
- package/import/typings/util/empty.d.ts +1 -0
- package/package.json +7 -7
- package/readme.md +4 -1
- package/transform/compiler/src/injectable_compiler_2.d.ts +0 -1
- package/transform/compiler/src/injectable_compiler_2.js +31 -16
- package/transform/compiler/src/output/output_ast.d.ts +53 -10
- package/transform/compiler/src/output/output_ast.js +211 -12
- package/transform/compiler/src/parse_util.js +10 -0
- package/transform/compiler/src/render3/partial/api.js +1 -1
- package/transform/compiler/src/render3/r3_factory.d.ts +0 -8
- package/transform/compiler/src/render3/r3_factory.js +5 -4
- package/transform/compiler/src/render3/r3_identifiers.js +37 -37
- package/transform/compiler/src/render3/view/util.js +1 -3
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +2 -4
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/factory.js +1 -0
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.d.ts +1 -1
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +5 -9
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +2 -1
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +12 -8
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.d.ts +2 -2
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.js +8 -4
- package/transform/compiler-cli/src/ngtsc/diagnostics/error_code.js +1 -1
- package/transform/compiler-cli/src/ngtsc/imports/src/default.js +1 -2
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +24 -173
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +2 -51
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +5 -3
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +5 -10
- package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +5 -23
- package/transform/compiler-cli/src/ngtsc/transform/src/api.js +0 -21
- package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +1 -2
- package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +7 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/context.js +1 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +4 -2
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +1 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +10 -4
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +2 -1
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +20 -16
- package/transform/injectable-transform.d.ts +2 -2
- package/transform/injectable-transform.js +32 -6
- package/import/es2015/di/provider_collection.js +0 -49
- package/import/es2015/interface/type.js +0 -8
- package/import/es2015/render3/fields.js +0 -11
- package/import/es2015/util/decorators.js +0 -30
- /package/import/{es2015 → es2022}/di/initializer_token.js +0 -0
- /package/import/{es2015 → es2022}/di/inject_switch.js +0 -0
- /package/import/{es2015 → es2022}/di/injectable.js +0 -0
- /package/import/{es2015 → es2022}/di/injector_marker.js +0 -0
- /package/import/{es2015 → es2022}/di/internal_tokens.js +0 -0
- /package/import/{es2015 → es2022}/di/metadata.js +0 -0
- /package/import/{es2015 → es2022}/di/provider_token.js +0 -0
- /package/import/{es2015 → es2022}/di/scope.js +0 -0
- /package/import/{es2015 → es2022}/index.js +0 -0
- /package/import/{es2015 → es2022}/interface/lifecycle_hooks.js +0 -0
- /package/import/{es2015 → es2022}/render3/di.js +0 -0
- /package/import/{es2015 → es2022}/util/closure.js +0 -0
- /package/import/{es2015 → es2022}/util/property.js +0 -0
|
@@ -40,6 +40,7 @@ function noSideEffects(fn) {
|
|
|
40
40
|
* Use of this source code is governed by an MIT-style license that can be
|
|
41
41
|
* found in the LICENSE file at https://angular.io/license
|
|
42
42
|
*/
|
|
43
|
+
const PARAMETERS = '__parameters__';
|
|
43
44
|
function makeMetadataCtor(props) {
|
|
44
45
|
return function ctor(...args) {
|
|
45
46
|
if (props) {
|
|
@@ -50,7 +51,7 @@ function makeMetadataCtor(props) {
|
|
|
50
51
|
}
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
|
-
function makeParamDecorator(name, props) {
|
|
54
|
+
function makeParamDecorator(name, props, parentClass) {
|
|
54
55
|
return noSideEffects(() => {
|
|
55
56
|
const metaCtor = makeMetadataCtor(props);
|
|
56
57
|
function ParamDecoratorFactory(...args) {
|
|
@@ -58,7 +59,29 @@ function makeParamDecorator(name, props) {
|
|
|
58
59
|
metaCtor.apply(this, args);
|
|
59
60
|
return this;
|
|
60
61
|
}
|
|
62
|
+
const annotationInstance = new ParamDecoratorFactory(...args);
|
|
63
|
+
ParamDecorator.annotation = annotationInstance;
|
|
64
|
+
return ParamDecorator;
|
|
65
|
+
function ParamDecorator(cls, unusedKey, index) {
|
|
66
|
+
// Use of Object.defineProperty is important since it creates non-enumerable property which
|
|
67
|
+
// prevents the property is copied during subclassing.
|
|
68
|
+
const parameters = cls.hasOwnProperty(PARAMETERS)
|
|
69
|
+
? cls[PARAMETERS]
|
|
70
|
+
: Object.defineProperty(cls, PARAMETERS, { value: [] })[PARAMETERS];
|
|
71
|
+
// there might be gaps if some in between parameters do not have annotations.
|
|
72
|
+
// we pad with nulls.
|
|
73
|
+
while (parameters.length <= index) {
|
|
74
|
+
parameters.push(null);
|
|
75
|
+
}
|
|
76
|
+
(parameters[index] = parameters[index] || []).push(annotationInstance);
|
|
77
|
+
return cls;
|
|
78
|
+
}
|
|
61
79
|
}
|
|
80
|
+
if (parentClass) {
|
|
81
|
+
ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
|
|
82
|
+
}
|
|
83
|
+
ParamDecoratorFactory.prototype.ngMetadataName = name;
|
|
84
|
+
ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
|
|
62
85
|
return ParamDecoratorFactory;
|
|
63
86
|
});
|
|
64
87
|
}
|
|
@@ -70,13 +93,42 @@ function makeParamDecorator(name, props) {
|
|
|
70
93
|
* Use of this source code is governed by an MIT-style license that can be
|
|
71
94
|
* found in the LICENSE file at https://angular.io/license
|
|
72
95
|
*/
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Class that represents a runtime error.
|
|
98
|
+
* Formats and outputs the error message in a consistent way.
|
|
99
|
+
*
|
|
100
|
+
* Example:
|
|
101
|
+
* ```
|
|
102
|
+
* throw new RuntimeError(
|
|
103
|
+
* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
|
|
104
|
+
* ngDevMode && 'Injector has already been destroyed.');
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* Note: the `message` argument contains a descriptive error message as a string in development
|
|
108
|
+
* mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
|
|
109
|
+
* `message` argument becomes `false`, thus we account for it in the typings and the runtime
|
|
110
|
+
* logic.
|
|
111
|
+
*/
|
|
112
|
+
class RuntimeError extends Error {
|
|
113
|
+
code;
|
|
114
|
+
constructor(code, message) {
|
|
115
|
+
super(formatRuntimeError(code, message));
|
|
116
|
+
this.code = code;
|
|
78
117
|
}
|
|
79
|
-
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Called to format a runtime error.
|
|
121
|
+
* See additional info on the `message` argument type in the `RuntimeError` class description.
|
|
122
|
+
*/
|
|
123
|
+
function formatRuntimeError(code, message) {
|
|
124
|
+
// Error code might be a negative number, which is a special marker that instructs the logic to
|
|
125
|
+
// generate a link to the error details page on angular.io.
|
|
126
|
+
// We also prepend `0` to non-compile-time errors.
|
|
127
|
+
const fullCode = `NG0${Math.abs(code)}`;
|
|
128
|
+
let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
|
|
129
|
+
if (false) {
|
|
130
|
+
}
|
|
131
|
+
return errorMessage;
|
|
80
132
|
}
|
|
81
133
|
|
|
82
134
|
/**
|
|
@@ -87,14 +139,14 @@ function getClosureSafeProperty(objWithPropertyToExtract) {
|
|
|
87
139
|
* found in the LICENSE file at https://angular.io/license
|
|
88
140
|
*/
|
|
89
141
|
function stringify(token) {
|
|
90
|
-
if (typeof token ===
|
|
142
|
+
if (typeof token === 'string') {
|
|
91
143
|
return token;
|
|
92
144
|
}
|
|
93
145
|
if (Array.isArray(token)) {
|
|
94
|
-
return
|
|
146
|
+
return '[' + token.map(stringify).join(', ') + ']';
|
|
95
147
|
}
|
|
96
148
|
if (token == null) {
|
|
97
|
-
return
|
|
149
|
+
return '' + token;
|
|
98
150
|
}
|
|
99
151
|
if (token.overriddenName) {
|
|
100
152
|
return `${token.overriddenName}`;
|
|
@@ -104,12 +156,28 @@ function stringify(token) {
|
|
|
104
156
|
}
|
|
105
157
|
const res = token.toString();
|
|
106
158
|
if (res == null) {
|
|
107
|
-
return
|
|
159
|
+
return '' + res;
|
|
108
160
|
}
|
|
109
|
-
const newLineIndex = res.indexOf(
|
|
161
|
+
const newLineIndex = res.indexOf('\n');
|
|
110
162
|
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
|
|
111
163
|
}
|
|
112
164
|
|
|
165
|
+
/**
|
|
166
|
+
* @license
|
|
167
|
+
* Copyright Google LLC All Rights Reserved.
|
|
168
|
+
*
|
|
169
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
170
|
+
* found in the LICENSE file at https://angular.io/license
|
|
171
|
+
*/
|
|
172
|
+
function getClosureSafeProperty(objWithPropertyToExtract) {
|
|
173
|
+
for (let key in objWithPropertyToExtract) {
|
|
174
|
+
if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
|
|
175
|
+
return key;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
throw Error('Could not find renamed property on target object.');
|
|
179
|
+
}
|
|
180
|
+
|
|
113
181
|
/**
|
|
114
182
|
* @license
|
|
115
183
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -127,9 +195,36 @@ const __forward_ref__ = getClosureSafeProperty({
|
|
|
127
195
|
* DI is declared, but not yet defined. It is also used when the `token` which we use when creating
|
|
128
196
|
* a query is not yet defined.
|
|
129
197
|
*
|
|
198
|
+
* `forwardRef` is also used to break circularities in standalone components imports.
|
|
199
|
+
*
|
|
130
200
|
* @usageNotes
|
|
131
|
-
* ###
|
|
201
|
+
* ### Circular dependency example
|
|
132
202
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
|
|
203
|
+
*
|
|
204
|
+
* ### Circular standalone reference import example
|
|
205
|
+
* ```ts
|
|
206
|
+
* @Component({
|
|
207
|
+
* standalone: true,
|
|
208
|
+
* imports: [ChildComponent],
|
|
209
|
+
* selector: 'app-parent',
|
|
210
|
+
* template: `<app-child [hideParent]="hideParent"></app-child>`,
|
|
211
|
+
* })
|
|
212
|
+
* export class ParentComponent {
|
|
213
|
+
* @Input() hideParent: boolean;
|
|
214
|
+
* }
|
|
215
|
+
*
|
|
216
|
+
*
|
|
217
|
+
* @Component({
|
|
218
|
+
* standalone: true,
|
|
219
|
+
* imports: [CommonModule, forwardRef(() => ParentComponent)],
|
|
220
|
+
* selector: 'app-child',
|
|
221
|
+
* template: `<app-parent *ngIf="!hideParent"></app-parent>`,
|
|
222
|
+
* })
|
|
223
|
+
* export class ChildComponent {
|
|
224
|
+
* @Input() hideParent: boolean;
|
|
225
|
+
* }
|
|
226
|
+
* ```
|
|
227
|
+
*
|
|
133
228
|
* @publicApi
|
|
134
229
|
*/
|
|
135
230
|
function forwardRef(forwardRefFn) {
|
|
@@ -149,7 +244,7 @@ function forwardRef(forwardRefFn) {
|
|
|
149
244
|
*
|
|
150
245
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
|
|
151
246
|
*
|
|
152
|
-
* @see
|
|
247
|
+
* @see {@link forwardRef}
|
|
153
248
|
* @publicApi
|
|
154
249
|
*/
|
|
155
250
|
function resolveForwardRef(type) {
|
|
@@ -157,79 +252,11 @@ function resolveForwardRef(type) {
|
|
|
157
252
|
}
|
|
158
253
|
/** Checks whether a function is wrapped by a `forwardRef`. */
|
|
159
254
|
function isForwardRef(fn) {
|
|
160
|
-
return (typeof fn ===
|
|
255
|
+
return (typeof fn === 'function' &&
|
|
161
256
|
fn.hasOwnProperty(__forward_ref__) &&
|
|
162
257
|
fn.__forward_ref__ === forwardRef);
|
|
163
258
|
}
|
|
164
259
|
|
|
165
|
-
/**
|
|
166
|
-
* @license
|
|
167
|
-
* Copyright Google LLC All Rights Reserved.
|
|
168
|
-
*
|
|
169
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
170
|
-
* found in the LICENSE file at https://angular.io/license
|
|
171
|
-
*/
|
|
172
|
-
class RuntimeError extends Error {
|
|
173
|
-
constructor(code, message) {
|
|
174
|
-
super(formatRuntimeError(code, message));
|
|
175
|
-
this.code = code;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
/* tslint:enable:no-toplevel-property-access */
|
|
179
|
-
/** Called to format a runtime error */
|
|
180
|
-
function formatRuntimeError(code, message) {
|
|
181
|
-
const fullCode = code ? `NG0${code}: ` : '';
|
|
182
|
-
let errorMessage = `${fullCode}${message}`;
|
|
183
|
-
// Some runtime errors are still thrown without `ngDevMode` (for example
|
|
184
|
-
// `throwProviderNotFoundError`), so we add `ngDevMode` check here to avoid pulling
|
|
185
|
-
// `RUNTIME_ERRORS_WITH_GUIDES` symbol into prod bundles.
|
|
186
|
-
// TODO: revisit all instances where `RuntimeError` is thrown and see if `ngDevMode` can be added
|
|
187
|
-
// there instead to tree-shake more devmode-only code (and eventually remove `ngDevMode` check
|
|
188
|
-
// from this code).
|
|
189
|
-
// if (ngDevMode && RUNTIME_ERRORS_WITH_GUIDES.has(code)) {
|
|
190
|
-
// errorMessage = `${errorMessage}. Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/NG0${code}`;
|
|
191
|
-
// }
|
|
192
|
-
return errorMessage;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* @license
|
|
197
|
-
* Copyright Google LLC All Rights Reserved.
|
|
198
|
-
*
|
|
199
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
200
|
-
* found in the LICENSE file at https://angular.io/license
|
|
201
|
-
*/
|
|
202
|
-
/**
|
|
203
|
-
* Used for stringify render output in Ivy.
|
|
204
|
-
* Important! This function is very performance-sensitive and we should
|
|
205
|
-
* be extra careful not to introduce megamorphic reads in it.
|
|
206
|
-
* Check `core/test/render3/perf/render_stringify` for benchmarks and alternate implementations.
|
|
207
|
-
*/
|
|
208
|
-
function renderStringify(value) {
|
|
209
|
-
if (typeof value === "string")
|
|
210
|
-
return value;
|
|
211
|
-
if (value == null)
|
|
212
|
-
return "";
|
|
213
|
-
// Use `String` so that it invokes the `toString` method of the value. Note that this
|
|
214
|
-
// appears to be faster than calling `value.toString` (see `render_stringify` benchmark).
|
|
215
|
-
return String(value);
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Used to stringify a value so that it can be displayed in an error message.
|
|
219
|
-
* Important! This function contains a megamorphic read and should only be
|
|
220
|
-
* used for error messages.
|
|
221
|
-
*/
|
|
222
|
-
function stringifyForError(value) {
|
|
223
|
-
if (typeof value === "function")
|
|
224
|
-
return value.name || value.toString();
|
|
225
|
-
if (typeof value === "object" &&
|
|
226
|
-
value != null &&
|
|
227
|
-
typeof value.type === "function") {
|
|
228
|
-
return value.type.name || value.type.toString();
|
|
229
|
-
}
|
|
230
|
-
return renderStringify(value);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
260
|
/**
|
|
234
261
|
* @license
|
|
235
262
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -240,7 +267,7 @@ function stringifyForError(value) {
|
|
|
240
267
|
/** Throws an error when a token is not found in DI. */
|
|
241
268
|
function throwProviderNotFoundError(token, injectorName) {
|
|
242
269
|
const injectorDetails = injectorName ? ` in ${injectorName}` : '';
|
|
243
|
-
throw new RuntimeError(
|
|
270
|
+
throw new RuntimeError(-201 /* RuntimeErrorCode.PROVIDER_NOT_FOUND */, null);
|
|
244
271
|
}
|
|
245
272
|
|
|
246
273
|
/**
|
|
@@ -262,7 +289,8 @@ function throwProviderNotFoundError(token, injectorName) {
|
|
|
262
289
|
* with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
|
|
263
290
|
* provided in the `'root'` injector, which will be the application-level injector in most apps.
|
|
264
291
|
* * `factory` gives the zero argument function which will create an instance of the injectable.
|
|
265
|
-
* The factory can call `inject` to access the `Injector` and request injection
|
|
292
|
+
* The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection
|
|
293
|
+
* of dependencies.
|
|
266
294
|
*
|
|
267
295
|
* @codeGenApi
|
|
268
296
|
* @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
|
|
@@ -302,7 +330,10 @@ function ɵɵdefineInjector(options) {
|
|
|
302
330
|
* @param type A type which may have its own (non-inherited) `ɵprov`.
|
|
303
331
|
*/
|
|
304
332
|
function getInjectableDef(type) {
|
|
305
|
-
return getOwnDefinition(type, NG_PROV_DEF);
|
|
333
|
+
return getOwnDefinition(type, NG_PROV_DEF) || null;
|
|
334
|
+
}
|
|
335
|
+
function isInjectable(type) {
|
|
336
|
+
return getInjectableDef(type) !== null;
|
|
306
337
|
}
|
|
307
338
|
/**
|
|
308
339
|
* Return definition only if it is defined directly on `type` and is not inherited from a base
|
|
@@ -311,9 +342,6 @@ function getInjectableDef(type) {
|
|
|
311
342
|
function getOwnDefinition(type, field) {
|
|
312
343
|
return type.hasOwnProperty(field) ? type[field] : null;
|
|
313
344
|
}
|
|
314
|
-
const NG_PROV_DEF = getClosureSafeProperty({
|
|
315
|
-
ɵprov: getClosureSafeProperty,
|
|
316
|
-
});
|
|
317
345
|
/**
|
|
318
346
|
* Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
|
|
319
347
|
*
|
|
@@ -323,36 +351,30 @@ const NG_PROV_DEF = getClosureSafeProperty({
|
|
|
323
351
|
* scenario if we find the `ɵprov` on an ancestor only.
|
|
324
352
|
*/
|
|
325
353
|
function getInheritedInjectableDef(type) {
|
|
326
|
-
const def = type && (type[NG_PROV_DEF] ||
|
|
354
|
+
const def = type && (type[NG_PROV_DEF] || null);
|
|
327
355
|
if (def) {
|
|
328
|
-
const typeName = getTypeName(type);
|
|
329
|
-
// TODO(FW-1307): Re-add ngDevMode when closure can handle it
|
|
330
|
-
// ngDevMode &&
|
|
331
|
-
console.warn(`DEPRECATED: DI is instantiating a token "${typeName}" that inherits its @Injectable decorator but does not provide one itself.\n` +
|
|
332
|
-
`This will become an error in a future version of Angular. Please add @Injectable() to the "${typeName}" class.`);
|
|
333
356
|
return def;
|
|
334
357
|
}
|
|
335
358
|
else {
|
|
336
359
|
return null;
|
|
337
360
|
}
|
|
338
361
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
// browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
|
|
349
|
-
// the issue by converting the function to a string and parsing its name out that way via a regex.
|
|
350
|
-
if (type.hasOwnProperty('name')) {
|
|
351
|
-
return type.name;
|
|
352
|
-
}
|
|
353
|
-
const match = ('' + type).match(/^function\s*([^\s(]+)/);
|
|
354
|
-
return match === null ? '' : match[1];
|
|
362
|
+
/**
|
|
363
|
+
* Read the injector def type in a way which is immune to accidentally reading inherited value.
|
|
364
|
+
*
|
|
365
|
+
* @param type type which may have an injector def (`ɵinj`)
|
|
366
|
+
*/
|
|
367
|
+
function getInjectorDef(type) {
|
|
368
|
+
return type && (type.hasOwnProperty(NG_INJ_DEF) || false)
|
|
369
|
+
? type[NG_INJ_DEF]
|
|
370
|
+
: null;
|
|
355
371
|
}
|
|
372
|
+
const NG_PROV_DEF = getClosureSafeProperty({
|
|
373
|
+
ɵprov: getClosureSafeProperty,
|
|
374
|
+
});
|
|
375
|
+
const NG_INJ_DEF = getClosureSafeProperty({
|
|
376
|
+
ɵinj: getClosureSafeProperty,
|
|
377
|
+
});
|
|
356
378
|
|
|
357
379
|
/**
|
|
358
380
|
* @license
|
|
@@ -365,7 +387,7 @@ function getTypeName(type) {
|
|
|
365
387
|
* Injection flags for DI.
|
|
366
388
|
*
|
|
367
389
|
* @publicApi
|
|
368
|
-
* @deprecated use an options object for `inject` instead.
|
|
390
|
+
* @deprecated use an options object for [`inject`](api/core/inject) instead.
|
|
369
391
|
*/
|
|
370
392
|
var InjectFlags;
|
|
371
393
|
(function (InjectFlags) {
|
|
@@ -450,10 +472,6 @@ const NG_TOKEN_PATH = 'ngTokenPath';
|
|
|
450
472
|
const NEW_LINE = /\n/gm;
|
|
451
473
|
const NO_NEW_LINE = 'ɵ';
|
|
452
474
|
const SOURCE = '__source';
|
|
453
|
-
const USE_VALUE = getClosureSafeProperty({
|
|
454
|
-
provide: String,
|
|
455
|
-
useValue: getClosureSafeProperty,
|
|
456
|
-
});
|
|
457
475
|
/**
|
|
458
476
|
* Current injector value used by `inject`.
|
|
459
477
|
* - `undefined`: it is an error to call `inject`
|
|
@@ -461,6 +479,9 @@ const USE_VALUE = getClosureSafeProperty({
|
|
|
461
479
|
* - Injector instance: Use the injector for resolution.
|
|
462
480
|
*/
|
|
463
481
|
let _currentInjector = undefined;
|
|
482
|
+
function getCurrentInjector() {
|
|
483
|
+
return _currentInjector;
|
|
484
|
+
}
|
|
464
485
|
function setCurrentInjector(injector) {
|
|
465
486
|
const former = _currentInjector;
|
|
466
487
|
_currentInjector = injector;
|
|
@@ -468,32 +489,46 @@ function setCurrentInjector(injector) {
|
|
|
468
489
|
}
|
|
469
490
|
function injectInjectorOnly(token, flags = InjectFlags.Default) {
|
|
470
491
|
if (_currentInjector === undefined) {
|
|
471
|
-
throw new
|
|
492
|
+
throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, null);
|
|
472
493
|
}
|
|
473
494
|
else if (_currentInjector === null) {
|
|
474
495
|
return injectRootLimpMode(token, undefined, flags);
|
|
475
496
|
}
|
|
476
497
|
else {
|
|
477
|
-
|
|
498
|
+
const value = _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
|
|
499
|
+
return value;
|
|
478
500
|
}
|
|
479
501
|
}
|
|
480
502
|
function ɵɵinject(token, flags = InjectFlags.Default) {
|
|
481
|
-
return injectInjectorOnly(resolveForwardRef(token), flags);
|
|
503
|
+
return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
507
|
+
* particular class.
|
|
508
|
+
*
|
|
509
|
+
* The name of the class is not mentioned here, but will be in the generated factory function name
|
|
510
|
+
* and thus in the stack trace.
|
|
511
|
+
*
|
|
512
|
+
* @codeGenApi
|
|
513
|
+
*/
|
|
514
|
+
function ɵɵinvalidFactoryDep(index) {
|
|
515
|
+
throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, null);
|
|
482
516
|
}
|
|
483
517
|
/**
|
|
484
518
|
* Injects a token from the currently active injector.
|
|
485
|
-
* `inject` is only supported
|
|
486
|
-
* during:
|
|
519
|
+
* `inject` is only supported in an [injection context](/guide/dependency-injection-context). It can
|
|
520
|
+
* be used during:
|
|
487
521
|
* - Construction (via the `constructor`) of a class being instantiated by the DI system, such
|
|
488
522
|
* as an `@Injectable` or `@Component`.
|
|
489
523
|
* - In the initializer for fields of such classes.
|
|
490
524
|
* - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
|
|
491
525
|
* - In the `factory` function specified for an `InjectionToken`.
|
|
526
|
+
* - In a stackframe of a function call in a DI context
|
|
492
527
|
*
|
|
493
528
|
* @param token A token that represents a dependency that should be injected.
|
|
494
529
|
* @param flags Optional flags that control how injection is executed.
|
|
495
530
|
* The flags correspond to injection strategies that can be specified with
|
|
496
|
-
* parameter decorators `@Host`, `@Self`, `@
|
|
531
|
+
* parameter decorators `@Host`, `@Self`, `@SkipSelf`, and `@Optional`.
|
|
497
532
|
* @returns the injected value if operation is successful, `null` otherwise.
|
|
498
533
|
* @throws if called outside of a supported context.
|
|
499
534
|
*
|
|
@@ -557,6 +592,7 @@ function convertToBitFlags(flags) {
|
|
|
557
592
|
// `InjectOptions` to `InjectFlags`.
|
|
558
593
|
return (0 /* InternalInjectFlags.Default */ | // comment to force a line break in the formatter
|
|
559
594
|
(flags.optional && 8 /* InternalInjectFlags.Optional */) |
|
|
595
|
+
0 |
|
|
560
596
|
(flags.self && 2 /* InternalInjectFlags.Self */) |
|
|
561
597
|
(flags.skipSelf &&
|
|
562
598
|
4 /* InternalInjectFlags.SkipSelf */));
|
|
@@ -567,7 +603,7 @@ function injectArgs(types) {
|
|
|
567
603
|
const arg = resolveForwardRef(types[i]);
|
|
568
604
|
if (Array.isArray(arg)) {
|
|
569
605
|
if (arg.length === 0) {
|
|
570
|
-
throw new
|
|
606
|
+
throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, null);
|
|
571
607
|
}
|
|
572
608
|
let type = undefined;
|
|
573
609
|
let flags = InjectFlags.Default;
|
|
@@ -712,6 +748,17 @@ attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* InternalInjectFlags.SkipSe
|
|
|
712
748
|
const NG_FACTORY_DEF = getClosureSafeProperty({
|
|
713
749
|
ɵfac: getClosureSafeProperty,
|
|
714
750
|
});
|
|
751
|
+
/**
|
|
752
|
+
* The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
|
|
753
|
+
* getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
|
|
754
|
+
* strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
|
|
755
|
+
*
|
|
756
|
+
* This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
|
|
757
|
+
* improve tree-shaking.
|
|
758
|
+
*/
|
|
759
|
+
const NG_ENV_ID = getClosureSafeProperty({
|
|
760
|
+
__NG_ENV_ID__: getClosureSafeProperty,
|
|
761
|
+
});
|
|
715
762
|
|
|
716
763
|
/**
|
|
717
764
|
* @license
|
|
@@ -722,19 +769,11 @@ const NG_FACTORY_DEF = getClosureSafeProperty({
|
|
|
722
769
|
*/
|
|
723
770
|
function getFactoryDef(type, throwNotFound) {
|
|
724
771
|
const hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
// }
|
|
772
|
+
if (false) {
|
|
773
|
+
}
|
|
728
774
|
return hasFactoryDef ? type[NG_FACTORY_DEF] : null;
|
|
729
775
|
}
|
|
730
776
|
|
|
731
|
-
/**
|
|
732
|
-
* @license
|
|
733
|
-
* Copyright Google LLC All Rights Reserved.
|
|
734
|
-
*
|
|
735
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
736
|
-
* found in the LICENSE file at https://angular.io/license
|
|
737
|
-
*/
|
|
738
777
|
function deepForEach(input, fn) {
|
|
739
778
|
input.forEach((value) => Array.isArray(value) ? deepForEach(value, fn) : fn(value));
|
|
740
779
|
}
|
|
@@ -759,7 +798,11 @@ function newArray(size, value) {
|
|
|
759
798
|
* allows for identity checks against these values to be consistently used by the framework
|
|
760
799
|
* code.
|
|
761
800
|
*/
|
|
801
|
+
const EMPTY_OBJ = {};
|
|
762
802
|
const EMPTY_ARRAY = [];
|
|
803
|
+
// freezing the values prevents any code from accidentally inserting new values in
|
|
804
|
+
if (false) {
|
|
805
|
+
}
|
|
763
806
|
|
|
764
807
|
/**
|
|
765
808
|
* @license
|
|
@@ -776,11 +819,11 @@ const EMPTY_ARRAY = [];
|
|
|
776
819
|
* parameterized type.
|
|
777
820
|
*
|
|
778
821
|
* `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
|
|
779
|
-
* the `Injector`. This provides additional level of type safety.
|
|
822
|
+
* the `Injector`. This provides an additional level of type safety.
|
|
780
823
|
*
|
|
781
824
|
* ```
|
|
782
825
|
* interface MyInterface {...}
|
|
783
|
-
*
|
|
826
|
+
* const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
|
|
784
827
|
* // myInterface is inferred to be MyInterface.
|
|
785
828
|
* ```
|
|
786
829
|
*
|
|
@@ -788,14 +831,18 @@ const EMPTY_ARRAY = [];
|
|
|
788
831
|
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
|
|
789
832
|
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
|
|
790
833
|
* application's root injector. If the factory function, which takes zero arguments, needs to inject
|
|
791
|
-
* dependencies, it can do so using the `inject` function.
|
|
834
|
+
* dependencies, it can do so using the [`inject`](api/core/inject) function.
|
|
835
|
+
* As you can see in the Tree-shakable InjectionToken example below.
|
|
792
836
|
*
|
|
793
837
|
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
|
|
794
|
-
* overrides the above behavior and marks the token as belonging to a particular `@NgModule
|
|
795
|
-
* mentioned above, `'root'` is the default value for
|
|
838
|
+
* overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note:
|
|
839
|
+
* this option is now deprecated). As mentioned above, `'root'` is the default value for
|
|
840
|
+
* `providedIn`.
|
|
841
|
+
*
|
|
842
|
+
* The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated.
|
|
796
843
|
*
|
|
797
844
|
* @usageNotes
|
|
798
|
-
* ### Basic
|
|
845
|
+
* ### Basic Examples
|
|
799
846
|
*
|
|
800
847
|
* ### Plain InjectionToken
|
|
801
848
|
*
|
|
@@ -809,15 +856,20 @@ const EMPTY_ARRAY = [];
|
|
|
809
856
|
* @publicApi
|
|
810
857
|
*/
|
|
811
858
|
class InjectionToken {
|
|
859
|
+
_desc;
|
|
860
|
+
/** @internal */
|
|
861
|
+
ngMetadataName = 'InjectionToken';
|
|
862
|
+
ɵprov;
|
|
863
|
+
/**
|
|
864
|
+
* @param _desc Description for the token,
|
|
865
|
+
* used only for debugging purposes,
|
|
866
|
+
* it should but does not need to be unique
|
|
867
|
+
* @param options Options for the token's usage, as described above
|
|
868
|
+
*/
|
|
812
869
|
constructor(_desc, options) {
|
|
813
870
|
this._desc = _desc;
|
|
814
871
|
this.ɵprov = undefined;
|
|
815
872
|
if (typeof options == 'number') {
|
|
816
|
-
// (typeof ngDevMode === "undefined" || ngDevMode) &&
|
|
817
|
-
// assertLessThan(options, 0, "Only negative numbers are supported here");
|
|
818
|
-
// // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
|
|
819
|
-
// // See `InjectorMarkers`
|
|
820
|
-
// (this as any).__NG_ELEMENT_ID__ = options;
|
|
821
873
|
}
|
|
822
874
|
else if (options !== undefined) {
|
|
823
875
|
this.ɵprov = ɵɵdefineInjectable({
|
|
@@ -868,12 +920,23 @@ const ENVIRONMENT_INITIALIZER = new InjectionToken('ENVIRONMENT_INITIALIZER');
|
|
|
868
920
|
*
|
|
869
921
|
* @publicApi
|
|
870
922
|
*/
|
|
871
|
-
const INJECTOR = new InjectionToken(
|
|
872
|
-
//
|
|
923
|
+
const INJECTOR = new InjectionToken('INJECTOR',
|
|
924
|
+
// Disable tslint because this is const enum which gets inlined not top level prop access.
|
|
873
925
|
// tslint:disable-next-line: no-toplevel-property-access
|
|
874
926
|
-1 /* InjectorMarkers.Injector */ // Special value used by Ivy to identify `Injector`.
|
|
875
927
|
);
|
|
876
928
|
|
|
929
|
+
/**
|
|
930
|
+
* @license
|
|
931
|
+
* Copyright Google LLC All Rights Reserved.
|
|
932
|
+
*
|
|
933
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
934
|
+
* found in the LICENSE file at https://angular.io/license
|
|
935
|
+
*/
|
|
936
|
+
function isEnvironmentProviders(value) {
|
|
937
|
+
return value && !!value.ɵproviders;
|
|
938
|
+
}
|
|
939
|
+
|
|
877
940
|
/**
|
|
878
941
|
* @license
|
|
879
942
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -894,13 +957,117 @@ class NullInjector {
|
|
|
894
957
|
get(token, notFoundValue = THROW_IF_NOT_FOUND) {
|
|
895
958
|
if (notFoundValue === THROW_IF_NOT_FOUND) {
|
|
896
959
|
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
|
|
897
|
-
error.name =
|
|
960
|
+
error.name = 'NullInjectorError';
|
|
898
961
|
throw error;
|
|
899
962
|
}
|
|
900
963
|
return notFoundValue;
|
|
901
964
|
}
|
|
902
965
|
}
|
|
903
966
|
|
|
967
|
+
/**
|
|
968
|
+
* @license
|
|
969
|
+
* Copyright Google LLC All Rights Reserved.
|
|
970
|
+
*
|
|
971
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
972
|
+
* found in the LICENSE file at https://angular.io/license
|
|
973
|
+
*/
|
|
974
|
+
/**
|
|
975
|
+
* Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally
|
|
976
|
+
* referenced in `@Component` in a component injector.
|
|
977
|
+
*/
|
|
978
|
+
function makeEnvironmentProviders(providers) {
|
|
979
|
+
return {
|
|
980
|
+
ɵproviders: providers,
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Collects providers from all NgModules and standalone components, including transitively imported
|
|
985
|
+
* ones.
|
|
986
|
+
*
|
|
987
|
+
* Providers extracted via `importProvidersFrom` are only usable in an application injector or
|
|
988
|
+
* another environment injector (such as a route injector). They should not be used in component
|
|
989
|
+
* providers.
|
|
990
|
+
*
|
|
991
|
+
* More information about standalone components can be found in [this
|
|
992
|
+
* guide](guide/standalone-components).
|
|
993
|
+
*
|
|
994
|
+
* @usageNotes
|
|
995
|
+
* The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:
|
|
996
|
+
*
|
|
997
|
+
* ```typescript
|
|
998
|
+
* await bootstrapApplication(RootComponent, {
|
|
999
|
+
* providers: [
|
|
1000
|
+
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
1001
|
+
* ]
|
|
1002
|
+
* });
|
|
1003
|
+
* ```
|
|
1004
|
+
*
|
|
1005
|
+
* You can also use the `importProvidersFrom` results in the `providers` field of a route, when a
|
|
1006
|
+
* standalone component is used:
|
|
1007
|
+
*
|
|
1008
|
+
* ```typescript
|
|
1009
|
+
* export const ROUTES: Route[] = [
|
|
1010
|
+
* {
|
|
1011
|
+
* path: 'foo',
|
|
1012
|
+
* providers: [
|
|
1013
|
+
* importProvidersFrom(NgModuleOne, NgModuleTwo)
|
|
1014
|
+
* ],
|
|
1015
|
+
* component: YourStandaloneComponent
|
|
1016
|
+
* }
|
|
1017
|
+
* ];
|
|
1018
|
+
* ```
|
|
1019
|
+
*
|
|
1020
|
+
* @returns Collected providers from the specified list of types.
|
|
1021
|
+
* @publicApi
|
|
1022
|
+
*/
|
|
1023
|
+
function importProvidersFrom(...sources) {
|
|
1024
|
+
return {
|
|
1025
|
+
ɵproviders: internalImportProvidersFrom(true, sources),
|
|
1026
|
+
ɵfromNgModule: true,
|
|
1027
|
+
};
|
|
1028
|
+
}
|
|
1029
|
+
function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
1030
|
+
const providersOut = [];
|
|
1031
|
+
const dedup = new Set(); // already seen types
|
|
1032
|
+
let injectorTypesWithProviders;
|
|
1033
|
+
const collectProviders = (provider) => {
|
|
1034
|
+
providersOut.push(provider);
|
|
1035
|
+
};
|
|
1036
|
+
// Collect all providers from `ModuleWithProviders` types.
|
|
1037
|
+
if (injectorTypesWithProviders !== undefined) {
|
|
1038
|
+
processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
|
|
1039
|
+
}
|
|
1040
|
+
return providersOut;
|
|
1041
|
+
}
|
|
1042
|
+
/**
|
|
1043
|
+
* Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
|
|
1044
|
+
* array.
|
|
1045
|
+
*/
|
|
1046
|
+
function processInjectorTypesWithProviders(typesWithProviders, visitor) {
|
|
1047
|
+
for (let i = 0; i < typesWithProviders.length; i++) {
|
|
1048
|
+
const { ngModule, providers } = typesWithProviders[i];
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
const USE_VALUE = getClosureSafeProperty({
|
|
1052
|
+
provide: String,
|
|
1053
|
+
useValue: getClosureSafeProperty,
|
|
1054
|
+
});
|
|
1055
|
+
function isValueProvider(value) {
|
|
1056
|
+
return value !== null && typeof value == 'object' && USE_VALUE in value;
|
|
1057
|
+
}
|
|
1058
|
+
function isExistingProvider(value) {
|
|
1059
|
+
return !!(value && value.useExisting);
|
|
1060
|
+
}
|
|
1061
|
+
function isFactoryProvider(value) {
|
|
1062
|
+
return !!(value && value.useFactory);
|
|
1063
|
+
}
|
|
1064
|
+
function isTypeProvider(value) {
|
|
1065
|
+
return typeof value === 'function';
|
|
1066
|
+
}
|
|
1067
|
+
function isClassProvider(value) {
|
|
1068
|
+
return !!value.useClass;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
904
1071
|
/**
|
|
905
1072
|
* @license
|
|
906
1073
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -951,29 +1118,33 @@ function getNullInjector() {
|
|
|
951
1118
|
class EnvironmentInjector {
|
|
952
1119
|
}
|
|
953
1120
|
class R3Injector extends EnvironmentInjector {
|
|
1121
|
+
parent;
|
|
1122
|
+
source;
|
|
1123
|
+
scopes;
|
|
1124
|
+
/**
|
|
1125
|
+
* Map of tokens to records which contain the instances of those tokens.
|
|
1126
|
+
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
1127
|
+
* to prevent further searches.
|
|
1128
|
+
*/
|
|
1129
|
+
records = new Map();
|
|
1130
|
+
/**
|
|
1131
|
+
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
1132
|
+
*/
|
|
1133
|
+
_ngOnDestroyHooks = new Set();
|
|
1134
|
+
_onDestroyHooks = [];
|
|
954
1135
|
/**
|
|
955
1136
|
* Flag indicating that this injector was previously destroyed.
|
|
956
1137
|
*/
|
|
957
1138
|
get destroyed() {
|
|
958
1139
|
return this._destroyed;
|
|
959
1140
|
}
|
|
1141
|
+
_destroyed = false;
|
|
1142
|
+
injectorDefTypes;
|
|
960
1143
|
constructor(providers, parent, source, scopes) {
|
|
961
1144
|
super();
|
|
962
1145
|
this.parent = parent;
|
|
963
1146
|
this.source = source;
|
|
964
1147
|
this.scopes = scopes;
|
|
965
|
-
/**
|
|
966
|
-
* Map of tokens to records which contain the instances of those tokens.
|
|
967
|
-
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
968
|
-
* to prevent further searches.
|
|
969
|
-
*/
|
|
970
|
-
this.records = new Map();
|
|
971
|
-
/**
|
|
972
|
-
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
973
|
-
*/
|
|
974
|
-
this._ngOnDestroyHooks = new Set();
|
|
975
|
-
this._onDestroyHooks = [];
|
|
976
|
-
this._destroyed = false;
|
|
977
1148
|
// Start off by creating Records for every provider.
|
|
978
1149
|
forEachSingleProvider(providers, (provider) => this.processProvider(provider));
|
|
979
1150
|
// Make sure the INJECTOR token provides this injector.
|
|
@@ -1005,7 +1176,11 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1005
1176
|
for (const service of this._ngOnDestroyHooks) {
|
|
1006
1177
|
service.ngOnDestroy();
|
|
1007
1178
|
}
|
|
1008
|
-
|
|
1179
|
+
const onDestroyHooks = this._onDestroyHooks;
|
|
1180
|
+
// Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
|
|
1181
|
+
// themselves from mutating the array during iteration.
|
|
1182
|
+
this._onDestroyHooks = [];
|
|
1183
|
+
for (const hook of onDestroyHooks) {
|
|
1009
1184
|
hook();
|
|
1010
1185
|
}
|
|
1011
1186
|
}
|
|
@@ -1014,16 +1189,19 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1014
1189
|
this.records.clear();
|
|
1015
1190
|
this._ngOnDestroyHooks.clear();
|
|
1016
1191
|
this.injectorDefTypes.clear();
|
|
1017
|
-
this._onDestroyHooks.length = 0;
|
|
1018
1192
|
}
|
|
1019
1193
|
}
|
|
1020
1194
|
onDestroy(callback) {
|
|
1195
|
+
this.assertNotDestroyed();
|
|
1021
1196
|
this._onDestroyHooks.push(callback);
|
|
1197
|
+
return () => this.removeOnDestroy(callback);
|
|
1022
1198
|
}
|
|
1023
1199
|
runInContext(fn) {
|
|
1024
1200
|
this.assertNotDestroyed();
|
|
1025
1201
|
const previousInjector = setCurrentInjector(this);
|
|
1026
1202
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1203
|
+
if (false) {
|
|
1204
|
+
}
|
|
1027
1205
|
try {
|
|
1028
1206
|
return fn();
|
|
1029
1207
|
}
|
|
@@ -1034,8 +1212,13 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1034
1212
|
}
|
|
1035
1213
|
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
|
|
1036
1214
|
this.assertNotDestroyed();
|
|
1215
|
+
if (token.hasOwnProperty(NG_ENV_ID)) {
|
|
1216
|
+
return token[NG_ENV_ID](this);
|
|
1217
|
+
}
|
|
1037
1218
|
flags = convertToBitFlags(flags);
|
|
1038
1219
|
// Set the injection context.
|
|
1220
|
+
if (false) {
|
|
1221
|
+
}
|
|
1039
1222
|
const previousInjector = setCurrentInjector(this);
|
|
1040
1223
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1041
1224
|
try {
|
|
@@ -1103,8 +1286,12 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1103
1286
|
resolveInjectorInitializers() {
|
|
1104
1287
|
const previousInjector = setCurrentInjector(this);
|
|
1105
1288
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1289
|
+
if (false) {
|
|
1290
|
+
}
|
|
1106
1291
|
try {
|
|
1107
1292
|
const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
|
|
1293
|
+
if (false) {
|
|
1294
|
+
}
|
|
1108
1295
|
for (const initializer of initializers) {
|
|
1109
1296
|
initializer();
|
|
1110
1297
|
}
|
|
@@ -1124,7 +1311,7 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1124
1311
|
}
|
|
1125
1312
|
assertNotDestroyed() {
|
|
1126
1313
|
if (this._destroyed) {
|
|
1127
|
-
throw new
|
|
1314
|
+
throw new RuntimeError(205 /* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED */, null);
|
|
1128
1315
|
}
|
|
1129
1316
|
}
|
|
1130
1317
|
/**
|
|
@@ -1139,12 +1326,16 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1139
1326
|
: resolveForwardRef(provider && provider.provide);
|
|
1140
1327
|
// Construct a `Record` for the provider.
|
|
1141
1328
|
const record = providerToRecord(provider);
|
|
1329
|
+
if (false) {
|
|
1330
|
+
}
|
|
1142
1331
|
if (!isTypeProvider(provider) && provider.multi === true) {
|
|
1143
1332
|
// If the provider indicates that it's a multi-provider, process it specially.
|
|
1144
1333
|
// First check whether it's been defined already.
|
|
1145
1334
|
let multiRecord = this.records.get(token);
|
|
1146
1335
|
if (multiRecord) {
|
|
1147
1336
|
// It has. Throw a nice error if
|
|
1337
|
+
if (false) {
|
|
1338
|
+
}
|
|
1148
1339
|
}
|
|
1149
1340
|
else {
|
|
1150
1341
|
multiRecord = makeRecord(undefined, NOT_YET, true);
|
|
@@ -1156,13 +1347,21 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1156
1347
|
}
|
|
1157
1348
|
else {
|
|
1158
1349
|
const existing = this.records.get(token);
|
|
1350
|
+
if (false) {
|
|
1351
|
+
}
|
|
1159
1352
|
}
|
|
1160
1353
|
this.records.set(token, record);
|
|
1161
1354
|
}
|
|
1162
1355
|
hydrate(token, record) {
|
|
1163
|
-
if (
|
|
1356
|
+
if (false) {
|
|
1357
|
+
}
|
|
1358
|
+
else if (record.value === NOT_YET) {
|
|
1164
1359
|
record.value = CIRCULAR;
|
|
1165
|
-
|
|
1360
|
+
if (false) {
|
|
1361
|
+
}
|
|
1362
|
+
else {
|
|
1363
|
+
record.value = record.factory();
|
|
1364
|
+
}
|
|
1166
1365
|
}
|
|
1167
1366
|
if (typeof record.value === 'object' &&
|
|
1168
1367
|
record.value &&
|
|
@@ -1183,6 +1382,12 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1183
1382
|
return this.injectorDefTypes.has(providedIn);
|
|
1184
1383
|
}
|
|
1185
1384
|
}
|
|
1385
|
+
removeOnDestroy(callback) {
|
|
1386
|
+
const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
|
|
1387
|
+
if (destroyCBIdx !== -1) {
|
|
1388
|
+
this._onDestroyHooks.splice(destroyCBIdx, 1);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1186
1391
|
}
|
|
1187
1392
|
function injectableDefOrInjectorDefFactory(token) {
|
|
1188
1393
|
// Most tokens will have an injectable def directly on them, which specifies a factory directly.
|
|
@@ -1194,21 +1399,21 @@ function injectableDefOrInjectorDefFactory(token) {
|
|
|
1194
1399
|
// InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
|
|
1195
1400
|
// If it's missing that, it's an error.
|
|
1196
1401
|
if (token instanceof InjectionToken) {
|
|
1197
|
-
throw new
|
|
1402
|
+
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1198
1403
|
}
|
|
1199
1404
|
// Undecorated types can sometimes be created if they have no constructor arguments.
|
|
1200
1405
|
if (token instanceof Function) {
|
|
1201
1406
|
return getUndecoratedInjectableFactory(token);
|
|
1202
1407
|
}
|
|
1203
1408
|
// There was no way to resolve a factory for this token.
|
|
1204
|
-
throw new
|
|
1409
|
+
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1205
1410
|
}
|
|
1206
1411
|
function getUndecoratedInjectableFactory(token) {
|
|
1207
1412
|
// If the token has parameters then it has dependencies that we cannot resolve implicitly.
|
|
1208
1413
|
const paramLength = token.length;
|
|
1209
1414
|
if (paramLength > 0) {
|
|
1210
1415
|
const args = newArray(paramLength, '?');
|
|
1211
|
-
throw new
|
|
1416
|
+
throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, null);
|
|
1212
1417
|
}
|
|
1213
1418
|
// The constructor function appears to have no parameters.
|
|
1214
1419
|
// This might be because it inherits from a super-class. In which case, use an injectable
|
|
@@ -1239,6 +1444,8 @@ function providerToRecord(provider) {
|
|
|
1239
1444
|
*/
|
|
1240
1445
|
function providerToFactory(provider, ngModuleType, providers) {
|
|
1241
1446
|
let factory = undefined;
|
|
1447
|
+
if (false) {
|
|
1448
|
+
}
|
|
1242
1449
|
if (isTypeProvider(provider)) {
|
|
1243
1450
|
const unwrappedProvider = resolveForwardRef(provider);
|
|
1244
1451
|
return (getFactoryDef(unwrappedProvider) ||
|
|
@@ -1258,9 +1465,8 @@ function providerToFactory(provider, ngModuleType, providers) {
|
|
|
1258
1465
|
const classRef = resolveForwardRef(provider &&
|
|
1259
1466
|
(provider.useClass ||
|
|
1260
1467
|
provider.provide));
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
// }
|
|
1468
|
+
if (false) {
|
|
1469
|
+
}
|
|
1264
1470
|
if (hasDeps(provider)) {
|
|
1265
1471
|
factory = () => new classRef(...injectArgs(provider.deps));
|
|
1266
1472
|
}
|
|
@@ -1278,18 +1484,6 @@ function makeRecord(factory, value, multi = false) {
|
|
|
1278
1484
|
multi: multi ? [] : undefined,
|
|
1279
1485
|
};
|
|
1280
1486
|
}
|
|
1281
|
-
function isValueProvider(value) {
|
|
1282
|
-
return value !== null && typeof value == 'object' && USE_VALUE in value;
|
|
1283
|
-
}
|
|
1284
|
-
function isExistingProvider(value) {
|
|
1285
|
-
return !!(value && value.useExisting);
|
|
1286
|
-
}
|
|
1287
|
-
function isFactoryProvider(value) {
|
|
1288
|
-
return !!(value && value.useFactory);
|
|
1289
|
-
}
|
|
1290
|
-
function isTypeProvider(value) {
|
|
1291
|
-
return typeof value === 'function';
|
|
1292
|
-
}
|
|
1293
1487
|
function hasDeps(value) {
|
|
1294
1488
|
return !!value.deps;
|
|
1295
1489
|
}
|
|
@@ -1307,6 +1501,9 @@ function forEachSingleProvider(providers, fn) {
|
|
|
1307
1501
|
if (Array.isArray(provider)) {
|
|
1308
1502
|
forEachSingleProvider(provider, fn);
|
|
1309
1503
|
}
|
|
1504
|
+
else if (provider && isEnvironmentProviders(provider)) {
|
|
1505
|
+
forEachSingleProvider(provider.ɵproviders, fn);
|
|
1506
|
+
}
|
|
1310
1507
|
else {
|
|
1311
1508
|
fn(provider);
|
|
1312
1509
|
}
|
|
@@ -1322,8 +1519,6 @@ function forEachSingleProvider(providers, fn) {
|
|
|
1322
1519
|
*/
|
|
1323
1520
|
/**
|
|
1324
1521
|
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
1325
|
-
*
|
|
1326
|
-
* @publicApi
|
|
1327
1522
|
*/
|
|
1328
1523
|
function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
1329
1524
|
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
@@ -1336,7 +1531,10 @@ function createInjector(defType, parent = null, additionalProviders = null, name
|
|
|
1336
1531
|
* should be resolved at a later point by calling `_resolveInjectorDefTypes`.
|
|
1337
1532
|
*/
|
|
1338
1533
|
function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
|
|
1339
|
-
const providers = [
|
|
1534
|
+
const providers = [
|
|
1535
|
+
additionalProviders || EMPTY_ARRAY,
|
|
1536
|
+
importProvidersFrom(defType),
|
|
1537
|
+
];
|
|
1340
1538
|
name = name || (typeof defType === 'object' ? undefined : stringify(defType));
|
|
1341
1539
|
return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
|
|
1342
1540
|
}
|
|
@@ -1354,7 +1552,7 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
|
|
|
1354
1552
|
* dependencies of various types with [injection tokens](guide/glossary#di-token).
|
|
1355
1553
|
*
|
|
1356
1554
|
* @see ["DI Providers"](guide/dependency-injection-providers).
|
|
1357
|
-
* @see
|
|
1555
|
+
* @see {@link StaticProvider}
|
|
1358
1556
|
*
|
|
1359
1557
|
* @usageNotes
|
|
1360
1558
|
*
|
|
@@ -1373,38 +1571,30 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
|
|
|
1373
1571
|
* @publicApi
|
|
1374
1572
|
*/
|
|
1375
1573
|
class Injector {
|
|
1574
|
+
static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1575
|
+
static NULL = new NullInjector();
|
|
1376
1576
|
static create(options, parent) {
|
|
1377
|
-
var _a;
|
|
1378
1577
|
if (Array.isArray(options)) {
|
|
1379
1578
|
return createInjector({ name: '' }, parent, options, '');
|
|
1380
1579
|
}
|
|
1381
1580
|
else {
|
|
1382
|
-
const name =
|
|
1581
|
+
const name = options.name ?? '';
|
|
1383
1582
|
return createInjector({ name }, options.parent, options.providers, name);
|
|
1384
1583
|
}
|
|
1385
1584
|
}
|
|
1585
|
+
/** @nocollapse */
|
|
1586
|
+
static ɵprov = /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
|
|
1587
|
+
token: Injector,
|
|
1588
|
+
providedIn: 'any',
|
|
1589
|
+
factory: () => ɵɵinject(INJECTOR),
|
|
1590
|
+
});
|
|
1591
|
+
/**
|
|
1592
|
+
* @internal
|
|
1593
|
+
* @nocollapse
|
|
1594
|
+
*/
|
|
1595
|
+
static __NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1386
1596
|
}
|
|
1387
|
-
Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1388
|
-
Injector.NULL = new NullInjector();
|
|
1389
|
-
/** @nocollapse */
|
|
1390
|
-
Injector.ɵprov = ɵɵdefineInjectable({
|
|
1391
|
-
token: Injector,
|
|
1392
|
-
providedIn: 'any',
|
|
1393
|
-
factory: () => ɵɵinject(INJECTOR),
|
|
1394
|
-
});
|
|
1395
|
-
/**
|
|
1396
|
-
* @internal
|
|
1397
|
-
* @nocollapse
|
|
1398
|
-
*/
|
|
1399
|
-
Injector.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1400
1597
|
|
|
1401
|
-
/**
|
|
1402
|
-
* @license
|
|
1403
|
-
* Copyright Google LLC All Rights Reserved.
|
|
1404
|
-
*
|
|
1405
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
1406
|
-
* found in the LICENSE file at https://angular.io/license
|
|
1407
|
-
*/
|
|
1408
1598
|
/**
|
|
1409
1599
|
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
1410
1600
|
* particular class.
|
|
@@ -1468,4 +1658,4 @@ function getFactoryOf(type) {
|
|
|
1468
1658
|
return getFactoryDef(type);
|
|
1469
1659
|
}
|
|
1470
1660
|
|
|
1471
|
-
export { EnvironmentInjector, INJECTOR_SCOPE, Inject, InjectFlags, Injectable, InjectionToken, Injector,
|
|
1661
|
+
export { EnvironmentInjector, INJECTOR_SCOPE, Inject, InjectFlags, Injectable, InjectionToken, Injector, NG_INJ_DEF, NG_PROV_DEF, NG_TEMP_TOKEN_PATH, NullInjector, Optional, R3Injector, SOURCE, Self, SkipSelf, THROW_IF_NOT_FOUND, attachInjectFlag, catchInjectorError, convertToBitFlags, formatError, getCurrentInjector, getInheritedInjectableDef, getInjectFlag, getInjectableDef, getInjectorDef, getNullInjector, inject, injectArgs, injectInjectorOnly, isInjectable, providerToFactory, setCurrentInjector, ɵɵdefineInjectable, ɵɵdefineInjector, ɵɵgetInheritedFactory, ɵɵinject, ɵɵinvalidFactory, ɵɵinvalidFactoryDep };
|