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
@@ -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 "../render3/errors_di";
9
- import { stringify } from "../util/stringify";
10
- import { getInjectableDef } from "./interface/defs";
11
- import { InjectFlags } from "./interface/injector";
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 == "root") {
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), "Injector");
51
+ throwProviderNotFoundError(stringify(token), 'Injector');
31
52
  }
@@ -65,6 +65,12 @@ export class InjectionToken {
65
65
  });
66
66
  }
67
67
  }
68
+ /**
69
+ * @internal
70
+ */
71
+ get multi() {
72
+ return this;
73
+ }
68
74
  toString() {
69
75
  return `InjectionToken ${this._desc}`;
70
76
  }
@@ -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 INJECTOR_IMPL(options, parent, '');
41
+ return createInjector({ name: '' }, parent, options, '');
45
42
  }
46
43
  else {
47
- return INJECTOR_IMPL(options.providers, options.parent, options.name || '');
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 "../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";
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 = "__NG_DI_FLAG__";
21
- export const NG_TEMP_TOKEN_PATH = "ngTempTokenPath";
22
- const NG_TOKEN_PATH = "ngTokenPath";
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 = "__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
- * Must be used in the context of a factory function such as one defined for an
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 injection is successful, `null` otherwise.
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
- * ### Example
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
- * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
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 const inject = ɵɵinject;
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("Arguments array must have arguments.");
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 === "number") {
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("\n" + e.message, tokenPath, injectorErrorName, source);
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) === "\n" && text.charAt(1) == NO_NEW_LINE
151
- ? text.substr(2)
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 === "object") {
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 === "string"
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 ? "(" + source + ")" : ""}[${context}]: ${text.replace(NEW_LINE, "\n ")}`;
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
+ }
@@ -9,6 +9,7 @@
9
9
  * Injection flags for DI.
10
10
  *
11
11
  * @publicApi
12
+ * @deprecated use an options object for `inject` instead.
12
13
  */
13
14
  export var InjectFlags;
14
15
  (function (InjectFlags) {
@@ -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
+ }