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.
Files changed (111) hide show
  1. package/import/commonjs/index.js +337 -124
  2. package/import/es2015/di/create_injector.js +30 -0
  3. package/import/es2015/di/initializer_token.js +15 -0
  4. package/import/es2015/di/inject_switch.js +27 -6
  5. package/import/es2015/di/injection_token.js +6 -0
  6. package/import/es2015/di/injector.js +6 -8
  7. package/import/es2015/di/injector_compatibility.js +90 -34
  8. package/import/es2015/di/injector_token.js +1 -1
  9. package/import/es2015/di/interface/defs.js +39 -0
  10. package/import/es2015/di/interface/injector.js +1 -0
  11. package/import/es2015/di/internal_tokens.js +9 -0
  12. package/import/es2015/di/metadata.js +4 -4
  13. package/import/es2015/di/provider_collection.js +49 -0
  14. package/import/es2015/di/r3_injector.js +102 -72
  15. package/import/es2015/di/scope.js +2 -2
  16. package/import/es2015/index.js +1 -1
  17. package/import/es2015/render3/errors_di.js +1 -1
  18. package/import/fesm2015/index.js +328 -114
  19. package/import/typings/di/create_injector.d.ts +23 -0
  20. package/import/typings/di/initializer_token.d.ts +15 -0
  21. package/import/typings/di/inject_switch.d.ts +7 -2
  22. package/import/typings/{decorator → di}/injectable.d.ts +2 -2
  23. package/import/typings/di/injection_token.d.ts +4 -0
  24. package/import/typings/di/injector.d.ts +20 -7
  25. package/import/typings/di/injector_compatibility.d.ts +42 -21
  26. package/import/typings/di/interface/defs.d.ts +10 -0
  27. package/import/typings/di/interface/injector.d.ts +26 -0
  28. package/import/typings/di/interface/provider.d.ts +3 -8
  29. package/import/typings/di/internal_tokens.d.ts +10 -0
  30. package/import/typings/di/provider_collection.d.ts +30 -0
  31. package/import/typings/di/provider_token.d.ts +1 -1
  32. package/import/typings/di/r3_injector.d.ts +68 -37
  33. package/import/typings/di/scope.d.ts +3 -2
  34. package/import/typings/index.d.ts +1 -1
  35. package/import/typings/render3/definition_factory.d.ts +1 -1
  36. package/package.json +5 -3
  37. package/{import/es2015/decorator/interface/provider.js → transform/compiler/compiler.d.ts} +1 -1
  38. package/transform/compiler/compiler.js +28 -0
  39. package/transform/compiler/index.d.ts +8 -5
  40. package/transform/compiler/index.js +17 -6
  41. package/transform/compiler/public_api.d.ts +13 -0
  42. package/transform/compiler/public_api.js +30 -0
  43. package/transform/compiler/src/compiler.d.ts +27 -0
  44. package/transform/compiler/src/compiler.js +47 -0
  45. package/transform/compiler/src/injectable_compiler_2.d.ts +7 -36
  46. package/transform/compiler/src/injectable_compiler_2.js +20 -23
  47. package/transform/compiler/src/output/output_ast.d.ts +30 -109
  48. package/transform/compiler/src/output/output_ast.js +66 -188
  49. package/transform/compiler/src/render3/partial/api.d.ts +1 -1
  50. package/transform/compiler/src/render3/partial/api.js +7 -0
  51. package/transform/compiler/src/render3/r3_factory.d.ts +8 -15
  52. package/transform/compiler/src/render3/r3_factory.js +46 -61
  53. package/transform/compiler/src/render3/util.d.ts +64 -0
  54. package/transform/compiler/src/render3/util.js +52 -9
  55. package/transform/compiler/src/render3/view/util.d.ts +0 -8
  56. package/transform/compiler/src/render3/view/util.js +5 -9
  57. package/transform/compiler-cli/src/ngtsc/annotations/common/index.d.ts +10 -0
  58. package/transform/compiler-cli/src/ngtsc/annotations/common/index.js +26 -0
  59. package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.d.ts +37 -0
  60. package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +197 -0
  61. package/transform/compiler-cli/src/ngtsc/annotations/{src → common/src}/factory.d.ts +3 -3
  62. package/transform/compiler-cli/src/ngtsc/annotations/{src → common/src}/factory.js +3 -3
  63. package/transform/compiler-cli/src/ngtsc/annotations/{src → common/src}/util.d.ts +4 -34
  64. package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +181 -0
  65. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +3 -4
  66. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +46 -53
  67. package/transform/compiler-cli/src/ngtsc/diagnostics/error.js +6 -2
  68. package/transform/compiler-cli/src/ngtsc/diagnostics/index.d.ts +9 -2
  69. package/transform/compiler-cli/src/ngtsc/diagnostics/index.js +12 -1
  70. package/transform/compiler-cli/src/ngtsc/imports/index.d.ts +7 -0
  71. package/transform/compiler-cli/src/ngtsc/imports/index.js +12 -1
  72. package/transform/compiler-cli/src/ngtsc/imports/src/default.d.ts +19 -0
  73. package/transform/compiler-cli/src/ngtsc/imports/src/default.js +28 -0
  74. package/transform/compiler-cli/src/ngtsc/reflection/index.d.ts +10 -3
  75. package/transform/compiler-cli/src/ngtsc/reflection/index.js +12 -1
  76. package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +13 -14
  77. package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +8 -25
  78. package/transform/compiler-cli/src/ngtsc/reflection/src/type_to_value.d.ts +2 -2
  79. package/transform/compiler-cli/src/ngtsc/reflection/src/type_to_value.js +44 -55
  80. package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +1 -1
  81. package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +55 -69
  82. package/transform/compiler-cli/src/ngtsc/reflection/src/util.d.ts +2 -2
  83. package/transform/compiler-cli/src/ngtsc/reflection/src/util.js +7 -23
  84. package/transform/compiler-cli/src/ngtsc/transform/index.d.ts +9 -2
  85. package/transform/compiler-cli/src/ngtsc/transform/index.js +12 -1
  86. package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +4 -4
  87. package/transform/compiler-cli/src/ngtsc/transform/src/utils.d.ts +2 -2
  88. package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +16 -31
  89. package/transform/compiler-cli/src/ngtsc/translator/index.d.ts +12 -5
  90. package/transform/compiler-cli/src/ngtsc/translator/index.js +12 -1
  91. package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +5 -5
  92. package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.d.ts +4 -4
  93. package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +5 -21
  94. package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +2 -6
  95. package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +6 -18
  96. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +3 -6
  97. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +83 -90
  98. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_translator.d.ts +4 -4
  99. package/transform/compiler-cli/src/ngtsc/ts_compatibility/index.d.ts +8 -0
  100. package/transform/compiler-cli/src/ngtsc/ts_compatibility/index.js +24 -0
  101. package/transform/compiler-cli/src/ngtsc/ts_compatibility/src/ts_cross_version_utils.d.ts +45 -0
  102. package/transform/compiler-cli/src/ngtsc/ts_compatibility/src/ts_cross_version_utils.js +86 -0
  103. package/transform/compiler-cli/src/ngtsc/util/src/typescript.d.ts +1 -8
  104. package/transform/compiler-cli/src/ngtsc/util/src/typescript.js +4 -27
  105. package/transform/index.js +5 -1
  106. package/transform/injectable-transform.js +59 -38
  107. package/import/typings/decorator/interface/provider.d.ts +0 -312
  108. package/transform/compiler/src/render3/partial/util.d.ts +0 -16
  109. package/transform/compiler/src/render3/partial/util.js +0 -44
  110. package/transform/compiler-cli/src/ngtsc/annotations/src/util.js +0 -370
  111. /package/import/es2015/{decorator → di}/injectable.js +0 -0
@@ -6,14 +6,18 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { getFactoryDef } from '../render3/definition_factory';
9
- import { deepForEach, newArray } from '../util/array_utils';
9
+ import { newArray } from '../util/array_utils';
10
+ import { EMPTY_ARRAY } from '../util/empty';
10
11
  import { stringify } from '../util/stringify';
11
12
  import { resolveForwardRef } from './forward_ref';
13
+ import { ENVIRONMENT_INITIALIZER } from './initializer_token';
12
14
  import { InjectionToken } from './injection_token';
13
- import { catchInjectorError, injectArgs, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject, } from './injector_compatibility';
15
+ import { catchInjectorError, convertToBitFlags, injectArgs, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject, } from './injector_compatibility';
14
16
  import { INJECTOR } from './injector_token';
15
- import { getInjectableDef, } from './interface/defs';
17
+ import { setInjectImplementation } from './inject_switch';
18
+ import { getInheritedInjectableDef, getInjectableDef, } from './interface/defs';
16
19
  import { InjectFlags } from './interface/injector';
20
+ import { INJECTOR_DEF_TYPES } from './internal_tokens';
17
21
  import { NullInjector } from './null_injector';
18
22
  import { INJECTOR_SCOPE } from './scope';
19
23
  /**
@@ -32,67 +36,57 @@ const CIRCULAR = {};
32
36
  * A lazily initialized NullInjector.
33
37
  */
34
38
  let NULL_INJECTOR = undefined;
35
- function getNullInjector() {
39
+ export function getNullInjector() {
36
40
  if (NULL_INJECTOR === undefined) {
37
41
  NULL_INJECTOR = new NullInjector();
38
42
  }
39
43
  return NULL_INJECTOR;
40
44
  }
41
45
  /**
42
- * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
43
- *
44
- * @publicApi
45
- */
46
- export function createInjector(defType, parent = null, additionalProviders = null, name) {
47
- const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
48
- injector._resolveInjectorDefTypes();
49
- return injector;
50
- }
51
- /**
52
- * Creates a new injector without eagerly resolving its injector types. Can be used in places
53
- * where resolving the injector types immediately can lead to an infinite loop. The injector types
54
- * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
46
+ * An `Injector` that's part of the environment injector hierarchy, which exists outside of the
47
+ * component tree.
55
48
  */
56
- export function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name) {
57
- return new R3Injector(defType, additionalProviders, parent || getNullInjector(), name);
49
+ export class EnvironmentInjector {
58
50
  }
59
- export class R3Injector {
60
- constructor(def, additionalProviders, parent, source = null) {
51
+ export class R3Injector extends EnvironmentInjector {
52
+ /**
53
+ * Flag indicating that this injector was previously destroyed.
54
+ */
55
+ get destroyed() {
56
+ return this._destroyed;
57
+ }
58
+ constructor(providers, parent, source, scopes) {
59
+ super();
61
60
  this.parent = parent;
61
+ this.source = source;
62
+ this.scopes = scopes;
62
63
  /**
63
64
  * Map of tokens to records which contain the instances of those tokens.
64
65
  * - `null` value implies that we don't have the record. Used by tree-shakable injectors
65
66
  * to prevent further searches.
66
67
  */
67
68
  this.records = new Map();
68
- /**
69
- * The transitive set of `InjectorType`s which define this injector.
70
- */
71
- this.injectorDefTypes = new Set();
72
69
  /**
73
70
  * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
74
71
  */
75
- this.onDestroy = new Set();
72
+ this._ngOnDestroyHooks = new Set();
73
+ this._onDestroyHooks = [];
76
74
  this._destroyed = false;
77
- // Start off by creating Records for every provider declared in every InjectorType
78
- // included transitively in additional providers then do the same for `def`. This order is
79
- // important because `def` may include providers that override ones in additionalProviders.
80
- additionalProviders &&
81
- deepForEach(additionalProviders, (provider) => this.processProvider(provider, def, additionalProviders));
75
+ // Start off by creating Records for every provider.
76
+ forEachSingleProvider(providers, (provider) => this.processProvider(provider));
82
77
  // Make sure the INJECTOR token provides this injector.
83
78
  this.records.set(INJECTOR, makeRecord(undefined, this));
79
+ // And `EnvironmentInjector` if the current injector is supposed to be env-scoped.
80
+ if (scopes.has('environment')) {
81
+ this.records.set(EnvironmentInjector, makeRecord(undefined, this));
82
+ }
84
83
  // Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
85
84
  // any injectable scoped to APP_ROOT_SCOPE.
86
85
  const record = this.records.get(INJECTOR_SCOPE);
87
- this.scope = record != null ? record.value : null;
88
- // Source name, used for debugging
89
- this.source = source || (typeof def === 'object' ? null : stringify(def));
90
- }
91
- /**
92
- * Flag indicating that this injector was previously destroyed.
93
- */
94
- get destroyed() {
95
- return this._destroyed;
86
+ if (record != null && typeof record.value === 'string') {
87
+ this.scopes.add(record.value);
88
+ }
89
+ this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES.multi, EMPTY_ARRAY, InjectFlags.Self));
96
90
  }
97
91
  /**
98
92
  * Destroy the injector and release references to every instance or provider associated with it.
@@ -106,19 +100,42 @@ export class R3Injector {
106
100
  this._destroyed = true;
107
101
  try {
108
102
  // Call all the lifecycle hooks.
109
- this.onDestroy.forEach((service) => service.ngOnDestroy());
103
+ for (const service of this._ngOnDestroyHooks) {
104
+ service.ngOnDestroy();
105
+ }
106
+ for (const hook of this._onDestroyHooks) {
107
+ hook();
108
+ }
110
109
  }
111
110
  finally {
112
111
  // Release all references.
113
112
  this.records.clear();
114
- this.onDestroy.clear();
113
+ this._ngOnDestroyHooks.clear();
115
114
  this.injectorDefTypes.clear();
115
+ this._onDestroyHooks.length = 0;
116
+ }
117
+ }
118
+ onDestroy(callback) {
119
+ this._onDestroyHooks.push(callback);
120
+ }
121
+ runInContext(fn) {
122
+ this.assertNotDestroyed();
123
+ const previousInjector = setCurrentInjector(this);
124
+ const previousInjectImplementation = setInjectImplementation(undefined);
125
+ try {
126
+ return fn();
127
+ }
128
+ finally {
129
+ setCurrentInjector(previousInjector);
130
+ setInjectImplementation(previousInjectImplementation);
116
131
  }
117
132
  }
118
133
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
119
134
  this.assertNotDestroyed();
135
+ flags = convertToBitFlags(flags);
120
136
  // Set the injection context.
121
137
  const previousInjector = setCurrentInjector(this);
138
+ const previousInjectImplementation = setInjectImplementation(undefined);
122
139
  try {
123
140
  // Check for the SkipSelf flag.
124
141
  if (!(flags & InjectFlags.SkipSelf)) {
@@ -176,16 +193,31 @@ export class R3Injector {
176
193
  }
177
194
  finally {
178
195
  // Lastly, restore the previous injection context.
196
+ setInjectImplementation(previousInjectImplementation);
179
197
  setCurrentInjector(previousInjector);
180
198
  }
181
199
  }
182
200
  /** @internal */
183
- _resolveInjectorDefTypes() {
184
- this.injectorDefTypes.forEach((defType) => this.get(defType));
201
+ resolveInjectorInitializers() {
202
+ const previousInjector = setCurrentInjector(this);
203
+ const previousInjectImplementation = setInjectImplementation(undefined);
204
+ try {
205
+ const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
206
+ for (const initializer of initializers) {
207
+ initializer();
208
+ }
209
+ }
210
+ finally {
211
+ setCurrentInjector(previousInjector);
212
+ setInjectImplementation(previousInjectImplementation);
213
+ }
185
214
  }
186
215
  toString() {
187
- const tokens = [], records = this.records;
188
- records.forEach((v, token) => tokens.push(stringify(token)));
216
+ const tokens = [];
217
+ const records = this.records;
218
+ for (const token of records.keys()) {
219
+ tokens.push(stringify(token));
220
+ }
189
221
  return `R3Injector[${tokens.join(', ')}]`;
190
222
  }
191
223
  assertNotDestroyed() {
@@ -193,19 +225,10 @@ export class R3Injector {
193
225
  throw new Error('Injector has already been destroyed.');
194
226
  }
195
227
  }
196
- /**
197
- * Add an `InjectorType` or `InjectorTypeWithProviders` and all of its transitive providers
198
- * to this injector.
199
- *
200
- * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
201
- * the function will return "true" to indicate that the providers of the type definition need
202
- * to be processed. This allows us to process providers of injector types after all imports of
203
- * an injector definition are processed. (following View Engine semantics: see FW-1349)
204
- */
205
228
  /**
206
229
  * Process a `SingleProvider` and add it.
207
230
  */
208
- processProvider(provider, ngModuleType, providers) {
231
+ processProvider(provider) {
209
232
  // Determine the token from the provider. Either it's its own token, or has a {provide: ...}
210
233
  // property.
211
234
  provider = resolveForwardRef(provider);
@@ -213,16 +236,13 @@ export class R3Injector {
213
236
  ? provider
214
237
  : resolveForwardRef(provider && provider.provide);
215
238
  // Construct a `Record` for the provider.
216
- const record = providerToRecord(provider, ngModuleType, providers);
239
+ const record = providerToRecord(provider);
217
240
  if (!isTypeProvider(provider) && provider.multi === true) {
218
241
  // If the provider indicates that it's a multi-provider, process it specially.
219
242
  // First check whether it's been defined already.
220
243
  let multiRecord = this.records.get(token);
221
244
  if (multiRecord) {
222
245
  // It has. Throw a nice error if
223
- // if (ngDevMode && multiRecord.multi === undefined) {
224
- // throwMixedMultiProviderError();
225
- // }
226
246
  }
227
247
  else {
228
248
  multiRecord = makeRecord(undefined, NOT_YET, true);
@@ -233,17 +253,11 @@ export class R3Injector {
233
253
  multiRecord.multi.push(provider);
234
254
  }
235
255
  else {
236
- // const existing = this.records.get(token);
237
- // if (ngDevMode && existing && existing.multi !== undefined) {
238
- // throwMixedMultiProviderError();
239
- // }
256
+ const existing = this.records.get(token);
240
257
  }
241
258
  this.records.set(token, record);
242
259
  }
243
260
  hydrate(token, record) {
244
- // if (ngDevMode && record.value === CIRCULAR) {
245
- // throwCyclicDependencyError(stringify(token));
246
- // } else
247
261
  if (record.value === NOT_YET) {
248
262
  record.value = CIRCULAR;
249
263
  record.value = record.factory();
@@ -251,7 +265,7 @@ export class R3Injector {
251
265
  if (typeof record.value === 'object' &&
252
266
  record.value &&
253
267
  hasOnDestroy(record.value)) {
254
- this.onDestroy.add(record.value);
268
+ this._ngOnDestroyHooks.add(record.value);
255
269
  }
256
270
  return record.value;
257
271
  }
@@ -261,7 +275,7 @@ export class R3Injector {
261
275
  }
262
276
  const providedIn = resolveForwardRef(def.providedIn);
263
277
  if (typeof providedIn === 'string') {
264
- return providedIn === 'any' || providedIn === this.scope;
278
+ return providedIn === 'any' || this.scopes.has(providedIn);
265
279
  }
266
280
  else {
267
281
  return this.injectorDefTypes.has(providedIn);
@@ -299,14 +313,20 @@ function getUndecoratedInjectableFactory(token) {
299
313
  // def from an ancestor if there is one.
300
314
  // Otherwise this really is a simple class with no dependencies, so return a factory that
301
315
  // just instantiates the zero-arg constructor.
302
- return () => new token();
316
+ const inheritedInjectableDef = getInheritedInjectableDef(token);
317
+ if (inheritedInjectableDef !== null) {
318
+ return () => inheritedInjectableDef.factory(token);
319
+ }
320
+ else {
321
+ return () => new token();
322
+ }
303
323
  }
304
- function providerToRecord(provider, ngModuleType, providers) {
324
+ function providerToRecord(provider) {
305
325
  if (isValueProvider(provider)) {
306
326
  return makeRecord(undefined, provider.useValue);
307
327
  }
308
328
  else {
309
- const factory = providerToFactory(provider, ngModuleType, providers);
329
+ const factory = providerToFactory(provider);
310
330
  return makeRecord(factory, NOT_YET);
311
331
  }
312
332
  }
@@ -380,3 +400,13 @@ function couldBeInjectableType(value) {
380
400
  return (typeof value === 'function' ||
381
401
  (typeof value === 'object' && value instanceof InjectionToken));
382
402
  }
403
+ function forEachSingleProvider(providers, fn) {
404
+ for (const provider of providers) {
405
+ if (Array.isArray(provider)) {
406
+ forEachSingleProvider(provider, fn);
407
+ }
408
+ else {
409
+ fn(provider);
410
+ }
411
+ }
412
+ }
@@ -5,10 +5,10 @@
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 { InjectionToken } from "./injection_token";
8
+ import { InjectionToken } from './injection_token';
9
9
  /**
10
10
  * An internal token whose presence in an injector indicates that the injector should treat itself
11
11
  * as a root scoped injector when processing requests for unknown tokens which may indicate
12
12
  * they are provided in the root scope.
13
13
  */
14
- export const INJECTOR_SCOPE = new InjectionToken("Set Injector scope.");
14
+ export const INJECTOR_SCOPE = new InjectionToken('Set Injector scope.');
@@ -1,4 +1,4 @@
1
- export * from './decorator/injectable';
1
+ export * from './di/injectable';
2
2
  export * from './di/metadata';
3
3
  export * from './di/r3_injector';
4
4
  export * from './di/interface/defs';
@@ -10,5 +10,5 @@ import { stringifyForError } from './util/stringify_utils';
10
10
  /** Throws an error when a token is not found in DI. */
11
11
  export function throwProviderNotFoundError(token, injectorName) {
12
12
  const injectorDetails = injectorName ? ` in ${injectorName}` : '';
13
- throw new RuntimeError("201" /* PROVIDER_NOT_FOUND */, `No provider for ${stringifyForError(token)} found${injectorDetails}`);
13
+ throw new RuntimeError("201" /* RuntimeErrorCode.PROVIDER_NOT_FOUND */, `No provider for ${stringifyForError(token)} found${injectorDetails}`);
14
14
  }