static-injector 2.2.0 → 3.0.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 (36) hide show
  1. package/import/commonjs/index.js +30 -8
  2. package/import/es2022/di/injection_token.js +11 -6
  3. package/import/es2022/di/r3_injector.js +4 -2
  4. package/import/es2022/render3/util/stringify_utils.js +1 -0
  5. package/import/es2022/util/stringify.js +15 -0
  6. package/import/fesm2022/index.js +30 -8
  7. package/import/typings/di/initializer_token.d.ts +1 -1
  8. package/import/typings/di/injection_token.d.ts +11 -6
  9. package/import/typings/di/internal_tokens.d.ts +1 -1
  10. package/import/typings/errors.d.ts +7 -2
  11. package/import/typings/render3/util/stringify_utils.d.ts +1 -0
  12. package/import/typings/util/stringify.d.ts +8 -0
  13. package/package.json +4 -3
  14. package/readme.md +2 -2
  15. package/transform/compiler/src/injectable_compiler_2.js +2 -2
  16. package/transform/compiler/src/output/output_ast.d.ts +13 -1
  17. package/transform/compiler/src/output/output_ast.js +45 -3
  18. package/transform/compiler/src/render3/r3_factory.js +1 -1
  19. package/transform/compiler/src/render3/util.js +1 -3
  20. package/transform/compiler/src/render3/view/util.d.ts +2 -0
  21. package/transform/compiler/src/render3/view/util.js +10 -2
  22. package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.d.ts +3 -2
  23. package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +31 -4
  24. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +3 -2
  25. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +8 -6
  26. package/transform/compiler-cli/src/ngtsc/diagnostics/error.d.ts +2 -2
  27. package/transform/compiler-cli/src/ngtsc/diagnostics/error_code.js +2 -2
  28. package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +18 -0
  29. package/transform/compiler-cli/src/ngtsc/transform/src/api.js +20 -0
  30. package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +8 -0
  31. package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +1 -0
  32. package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +5 -0
  33. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +1 -0
  34. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +6 -0
  35. package/transform/index.d.ts +1 -1
  36. package/transform/injectable-transform.js +1 -1
@@ -163,6 +163,21 @@ function stringify(token) {
163
163
  const newLineIndex = res.indexOf('\n');
164
164
  return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
165
165
  }
166
+ /**
167
+ * Ellipses the string in the middle when longer than the max length
168
+ *
169
+ * @param string
170
+ * @param maxLength of the output string
171
+ * @returns elispsed string with ... in the middle
172
+ */
173
+ function truncateMiddle(str, maxLength = 100) {
174
+ if (!str || maxLength < 1 || str.length <= maxLength)
175
+ return str;
176
+ if (maxLength == 1)
177
+ return str.substring(0, 1) + '...';
178
+ const halfLimit = Math.round(maxLength / 2);
179
+ return (str.substring(0, halfLimit) + '...' + str.substring(str.length - halfLimit));
180
+ }
166
181
 
167
182
  /**
168
183
  * @license
@@ -823,11 +838,17 @@ if (false) {
823
838
  * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
824
839
  * the `Injector`. This provides an additional level of type safety.
825
840
  *
826
- * ```
827
- * interface MyInterface {...}
828
- * const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
829
- * // myInterface is inferred to be MyInterface.
830
- * ```
841
+ * <div class="alert is-helpful">
842
+ *
843
+ * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the
844
+ * provider and the injection call. Creating a new instance of `InjectionToken` in different places,
845
+ * even with the same description, will be treated as different tokens by Angular's DI system,
846
+ * leading to a `NullInjectorError`.
847
+ *
848
+ * </div>
849
+ *
850
+ * <code-example format="typescript" language="typescript" path="injection-token/src/main.ts"
851
+ * region="InjectionToken"></code-example>
831
852
  *
832
853
  * When creating an `InjectionToken`, you can optionally specify a factory function which returns
833
854
  * (possibly by creating) a default value of the parameterized type `T`. This sets up the
@@ -854,7 +875,6 @@ if (false) {
854
875
  *
855
876
  * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
856
877
  *
857
- *
858
878
  * @publicApi
859
879
  */
860
880
  class InjectionToken {
@@ -1161,7 +1181,7 @@ class R3Injector extends EnvironmentInjector {
1161
1181
  if (record != null && typeof record.value === 'string') {
1162
1182
  this.scopes.add(record.value);
1163
1183
  }
1164
- this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES.multi, EMPTY_ARRAY, exports.InjectFlags.Self));
1184
+ this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES, EMPTY_ARRAY, exports.InjectFlags.Self));
1165
1185
  }
1166
1186
  /**
1167
1187
  * Destroy the injector and release references to every instance or provider associated with it.
@@ -1235,6 +1255,8 @@ class R3Injector extends EnvironmentInjector {
1235
1255
  if (def && this.injectableDefInScope(def)) {
1236
1256
  // Found an injectable def and it's scoped to this injector. Pretend as if it was here
1237
1257
  // all along.
1258
+ if (false) {
1259
+ }
1238
1260
  record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
1239
1261
  }
1240
1262
  else {
@@ -1291,7 +1313,7 @@ class R3Injector extends EnvironmentInjector {
1291
1313
  if (false) {
1292
1314
  }
1293
1315
  try {
1294
- const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, exports.InjectFlags.Self);
1316
+ const initializers = this.get(ENVIRONMENT_INITIALIZER, EMPTY_ARRAY, exports.InjectFlags.Self);
1295
1317
  if (false) {
1296
1318
  }
1297
1319
  for (const initializer of initializers) {
@@ -16,11 +16,17 @@ import { ɵɵdefineInjectable } from './interface/defs';
16
16
  * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
17
17
  * the `Injector`. This provides an additional level of type safety.
18
18
  *
19
- * ```
20
- * interface MyInterface {...}
21
- * const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
22
- * // myInterface is inferred to be MyInterface.
23
- * ```
19
+ * <div class="alert is-helpful">
20
+ *
21
+ * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the
22
+ * provider and the injection call. Creating a new instance of `InjectionToken` in different places,
23
+ * even with the same description, will be treated as different tokens by Angular's DI system,
24
+ * leading to a `NullInjectorError`.
25
+ *
26
+ * </div>
27
+ *
28
+ * <code-example format="typescript" language="typescript" path="injection-token/src/main.ts"
29
+ * region="InjectionToken"></code-example>
24
30
  *
25
31
  * When creating an `InjectionToken`, you can optionally specify a factory function which returns
26
32
  * (possibly by creating) a default value of the parameterized type `T`. This sets up the
@@ -47,7 +53,6 @@ import { ɵɵdefineInjectable } from './interface/defs';
47
53
  *
48
54
  * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
49
55
  *
50
- *
51
56
  * @publicApi
52
57
  */
53
58
  export class InjectionToken {
@@ -94,7 +94,7 @@ export class R3Injector extends EnvironmentInjector {
94
94
  if (record != null && typeof record.value === 'string') {
95
95
  this.scopes.add(record.value);
96
96
  }
97
- this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES.multi, EMPTY_ARRAY, InjectFlags.Self));
97
+ this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES, EMPTY_ARRAY, InjectFlags.Self));
98
98
  }
99
99
  /**
100
100
  * Destroy the injector and release references to every instance or provider associated with it.
@@ -168,6 +168,8 @@ export class R3Injector extends EnvironmentInjector {
168
168
  if (def && this.injectableDefInScope(def)) {
169
169
  // Found an injectable def and it's scoped to this injector. Pretend as if it was here
170
170
  // all along.
171
+ if (false) {
172
+ }
171
173
  record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
172
174
  }
173
175
  else {
@@ -224,7 +226,7 @@ export class R3Injector extends EnvironmentInjector {
224
226
  if (false) {
225
227
  }
226
228
  try {
227
- const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
229
+ const initializers = this.get(ENVIRONMENT_INITIALIZER, EMPTY_ARRAY, InjectFlags.Self);
228
230
  if (false) {
229
231
  }
230
232
  for (const initializer of initializers) {
@@ -22,6 +22,7 @@ export function renderStringify(value) {
22
22
  }
23
23
  /**
24
24
  * Used to stringify a value so that it can be displayed in an error message.
25
+ *
25
26
  * Important! This function contains a megamorphic read and should only be
26
27
  * used for error messages.
27
28
  */
@@ -28,3 +28,18 @@ export function stringify(token) {
28
28
  const newLineIndex = res.indexOf('\n');
29
29
  return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
30
30
  }
31
+ /**
32
+ * Ellipses the string in the middle when longer than the max length
33
+ *
34
+ * @param string
35
+ * @param maxLength of the output string
36
+ * @returns elispsed string with ... in the middle
37
+ */
38
+ export function truncateMiddle(str, maxLength = 100) {
39
+ if (!str || maxLength < 1 || str.length <= maxLength)
40
+ return str;
41
+ if (maxLength == 1)
42
+ return str.substring(0, 1) + '...';
43
+ const halfLimit = Math.round(maxLength / 2);
44
+ return (str.substring(0, halfLimit) + '...' + str.substring(str.length - halfLimit));
45
+ }
@@ -161,6 +161,21 @@ function stringify(token) {
161
161
  const newLineIndex = res.indexOf('\n');
162
162
  return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
163
163
  }
164
+ /**
165
+ * Ellipses the string in the middle when longer than the max length
166
+ *
167
+ * @param string
168
+ * @param maxLength of the output string
169
+ * @returns elispsed string with ... in the middle
170
+ */
171
+ function truncateMiddle(str, maxLength = 100) {
172
+ if (!str || maxLength < 1 || str.length <= maxLength)
173
+ return str;
174
+ if (maxLength == 1)
175
+ return str.substring(0, 1) + '...';
176
+ const halfLimit = Math.round(maxLength / 2);
177
+ return (str.substring(0, halfLimit) + '...' + str.substring(str.length - halfLimit));
178
+ }
164
179
 
165
180
  /**
166
181
  * @license
@@ -821,11 +836,17 @@ if (false) {
821
836
  * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
822
837
  * the `Injector`. This provides an additional level of type safety.
823
838
  *
824
- * ```
825
- * interface MyInterface {...}
826
- * const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
827
- * // myInterface is inferred to be MyInterface.
828
- * ```
839
+ * <div class="alert is-helpful">
840
+ *
841
+ * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the
842
+ * provider and the injection call. Creating a new instance of `InjectionToken` in different places,
843
+ * even with the same description, will be treated as different tokens by Angular's DI system,
844
+ * leading to a `NullInjectorError`.
845
+ *
846
+ * </div>
847
+ *
848
+ * <code-example format="typescript" language="typescript" path="injection-token/src/main.ts"
849
+ * region="InjectionToken"></code-example>
829
850
  *
830
851
  * When creating an `InjectionToken`, you can optionally specify a factory function which returns
831
852
  * (possibly by creating) a default value of the parameterized type `T`. This sets up the
@@ -852,7 +873,6 @@ if (false) {
852
873
  *
853
874
  * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
854
875
  *
855
- *
856
876
  * @publicApi
857
877
  */
858
878
  class InjectionToken {
@@ -1159,7 +1179,7 @@ class R3Injector extends EnvironmentInjector {
1159
1179
  if (record != null && typeof record.value === 'string') {
1160
1180
  this.scopes.add(record.value);
1161
1181
  }
1162
- this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES.multi, EMPTY_ARRAY, InjectFlags.Self));
1182
+ this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES, EMPTY_ARRAY, InjectFlags.Self));
1163
1183
  }
1164
1184
  /**
1165
1185
  * Destroy the injector and release references to every instance or provider associated with it.
@@ -1233,6 +1253,8 @@ class R3Injector extends EnvironmentInjector {
1233
1253
  if (def && this.injectableDefInScope(def)) {
1234
1254
  // Found an injectable def and it's scoped to this injector. Pretend as if it was here
1235
1255
  // all along.
1256
+ if (false) {
1257
+ }
1236
1258
  record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
1237
1259
  }
1238
1260
  else {
@@ -1289,7 +1311,7 @@ class R3Injector extends EnvironmentInjector {
1289
1311
  if (false) {
1290
1312
  }
1291
1313
  try {
1292
- const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, InjectFlags.Self);
1314
+ const initializers = this.get(ENVIRONMENT_INITIALIZER, EMPTY_ARRAY, InjectFlags.Self);
1293
1315
  if (false) {
1294
1316
  }
1295
1317
  for (const initializer of initializers) {
@@ -12,4 +12,4 @@ import { InjectionToken } from './injection_token';
12
12
  *
13
13
  * @publicApi
14
14
  */
15
- export declare const ENVIRONMENT_INITIALIZER: InjectionToken<() => void>;
15
+ export declare const ENVIRONMENT_INITIALIZER: InjectionToken<readonly (() => void)[]>;
@@ -16,11 +16,17 @@ import { Type } from '../interface/type';
16
16
  * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
17
17
  * the `Injector`. This provides an additional level of type safety.
18
18
  *
19
- * ```
20
- * interface MyInterface {...}
21
- * const myInterface = injector.get(new InjectionToken<MyInterface>('SomeToken'));
22
- * // myInterface is inferred to be MyInterface.
23
- * ```
19
+ * <div class="alert is-helpful">
20
+ *
21
+ * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the
22
+ * provider and the injection call. Creating a new instance of `InjectionToken` in different places,
23
+ * even with the same description, will be treated as different tokens by Angular's DI system,
24
+ * leading to a `NullInjectorError`.
25
+ *
26
+ * </div>
27
+ *
28
+ * <code-example format="typescript" language="typescript" path="injection-token/src/main.ts"
29
+ * region="InjectionToken"></code-example>
24
30
  *
25
31
  * When creating an `InjectionToken`, you can optionally specify a factory function which returns
26
32
  * (possibly by creating) a default value of the parameterized type `T`. This sets up the
@@ -47,7 +53,6 @@ import { Type } from '../interface/type';
47
53
  *
48
54
  * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
49
55
  *
50
- *
51
56
  * @publicApi
52
57
  */
53
58
  export declare class InjectionToken<T> {
@@ -7,4 +7,4 @@
7
7
  */
8
8
  import { Type } from '../interface/type';
9
9
  import { InjectionToken } from './injection_token';
10
- export declare const INJECTOR_DEF_TYPES: InjectionToken<Type<unknown>>;
10
+ export declare const INJECTOR_DEF_TYPES: InjectionToken<readonly Type<unknown>[]>;
@@ -27,6 +27,7 @@ export declare const enum RuntimeErrorCode {
27
27
  EXPRESSION_CHANGED_AFTER_CHECKED = -100,
28
28
  RECURSIVE_APPLICATION_REF_TICK = 101,
29
29
  RECURSIVE_APPLICATION_RENDER = 102,
30
+ INFINITE_CHANGE_DETECTION = 103,
30
31
  CYCLIC_DI_DEPENDENCY = -200,
31
32
  PROVIDER_NOT_FOUND = -201,
32
33
  INVALID_FACTORY_DEPENDENCY = 202,
@@ -46,7 +47,7 @@ export declare const enum RuntimeErrorCode {
46
47
  INVALID_EVENT_BINDING = 306,
47
48
  HOST_DIRECTIVE_UNRESOLVABLE = 307,
48
49
  HOST_DIRECTIVE_NOT_STANDALONE = 308,
49
- DUPLICATE_DIRECTITVE = 309,
50
+ DUPLICATE_DIRECTIVE = 309,
50
51
  HOST_DIRECTIVE_COMPONENT = 310,
51
52
  HOST_DIRECTIVE_UNDEFINED_BINDING = 311,
52
53
  HOST_DIRECTIVE_CONFLICTING_ALIAS = 312,
@@ -69,8 +70,10 @@ export declare const enum RuntimeErrorCode {
69
70
  MISSING_SSR_CONTENT_INTEGRITY_MARKER = -507,
70
71
  SIGNAL_WRITE_FROM_ILLEGAL_CONTEXT = 600,
71
72
  REQUIRE_SYNC_WITHOUT_SYNC_EMIT = 601,
73
+ ASSERTION_NOT_INSIDE_REACTIVE_CONTEXT = -602,
72
74
  INVALID_I18N_STRUCTURE = 700,
73
75
  MISSING_LOCALE_DATA = 701,
76
+ DEFER_LOADING_FAILED = 750,
74
77
  IMPORT_PROVIDERS_FROM_STANDALONE = 800,
75
78
  INVALID_DIFFER_INPUT = 900,
76
79
  NO_SUPPORTING_DIFFER_FACTORY = 901,
@@ -85,7 +88,9 @@ export declare const enum RuntimeErrorCode {
85
88
  UNSAFE_IFRAME_ATTRS = -910,
86
89
  VIEW_ALREADY_DESTROYED = 911,
87
90
  COMPONENT_ID_COLLISION = -912,
88
- RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000
91
+ IMAGE_PERFORMANCE_WARNING = -913,
92
+ RUNTIME_DEPS_INVALID_IMPORTED_TYPE = 1000,
93
+ RUNTIME_DEPS_ORPHAN_COMPONENT = 1001
89
94
  }
90
95
  /**
91
96
  * Class that represents a runtime error.
@@ -14,6 +14,7 @@
14
14
  export declare function renderStringify(value: any): string;
15
15
  /**
16
16
  * Used to stringify a value so that it can be displayed in an error message.
17
+ *
17
18
  * Important! This function contains a megamorphic read and should only be
18
19
  * used for error messages.
19
20
  */
@@ -6,3 +6,11 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  export declare function stringify(token: any): string;
9
+ /**
10
+ * Ellipses the string in the middle when longer than the max length
11
+ *
12
+ * @param string
13
+ * @param maxLength of the output string
14
+ * @returns elispsed string with ... in the middle
15
+ */
16
+ export declare function truncateMiddle(str: string, maxLength?: number): string;
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "static-injector",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "description": "Angular的静态注入器独立使用版本",
5
5
  "keywords": [
6
6
  "angular",
7
+ "angular 17.0.4",
7
8
  "injector",
8
9
  "typescript",
9
- "typescript 5.1.6",
10
+ "typescript 5.2.2",
10
11
  "injectable",
11
12
  "static-inject"
12
13
  ],
@@ -29,7 +30,7 @@
29
30
  "author": "wszgrcy",
30
31
  "license": "MIT",
31
32
  "peerDependencies": {
32
- "typescript": "~5.1.6"
33
+ "typescript": ">=5.0.0"
33
34
  },
34
35
  "devDependencies": {},
35
36
  "sideEffects": false
package/readme.md CHANGED
@@ -3,9 +3,9 @@
3
3
  - 这是 Angualr 依赖注入的独立版本,初始版本逻辑为从 Angular 源码中提取出来,并修复了一些已知 bug
4
4
  - 使用方法与 Angular 的依赖注入完全一致
5
5
  # 来源
6
- - Angular 16.2.2
6
+ - Angular 17.0.4
7
7
  # 兼容
8
- - ts 5.1.6
8
+ - ts 5.2.2
9
9
  # 使用方法
10
10
 
11
11
  - 以`Injector.create`创建第一级依赖注入器
@@ -88,7 +88,7 @@ function compileInjectable(meta, resolveForwardRefs) {
88
88
  else {
89
89
  result = {
90
90
  statements: [],
91
- expression: o.fn([], [new o.ReturnStatement(meta.useFactory.callFn([]))]),
91
+ expression: o.arrowFn([], meta.useFactory.callFn([])),
92
92
  };
93
93
  }
94
94
  }
@@ -167,5 +167,5 @@ function delegateToFactory(type, useType, unwrapForwardRefs) {
167
167
  return createFactoryFunction(unwrappedType);
168
168
  }
169
169
  function createFactoryFunction(type) {
170
- return o.fn([new o.FnParam('t', o.DYNAMIC_TYPE)], [new o.ReturnStatement(type.prop('ɵfac').callFn([o.variable('t')]))]);
170
+ return o.arrowFn([new o.FnParam('t', o.DYNAMIC_TYPE)], type.prop('ɵfac').callFn([o.variable('t')]));
171
171
  }
@@ -280,12 +280,22 @@ export declare class FunctionExpr extends Expression {
280
280
  statements: Statement[];
281
281
  name?: string | null | undefined;
282
282
  constructor(params: FnParam[], statements: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, name?: string | null | undefined);
283
- isEquivalent(e: Expression): boolean;
283
+ isEquivalent(e: Expression | Statement): boolean;
284
284
  isConstant(): boolean;
285
285
  visitExpression(visitor: ExpressionVisitor, context: any): any;
286
286
  toDeclStmt(name: string, modifiers?: StmtModifier): DeclareFunctionStmt;
287
287
  clone(): FunctionExpr;
288
288
  }
289
+ export declare class ArrowFunctionExpr extends Expression {
290
+ params: FnParam[];
291
+ body: Expression | Statement[];
292
+ constructor(params: FnParam[], body: Expression | Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null);
293
+ isEquivalent(e: Expression): boolean;
294
+ isConstant(): boolean;
295
+ visitExpression(visitor: ExpressionVisitor, context: any): any;
296
+ clone(): Expression;
297
+ toDeclStmt(name: string, modifiers?: StmtModifier): DeclareVarStmt;
298
+ }
289
299
  export declare class UnaryOperatorExpr extends Expression {
290
300
  operator: UnaryOperator;
291
301
  expr: Expression;
@@ -383,6 +393,7 @@ export interface ExpressionVisitor {
383
393
  visitCommaExpr(ast: CommaExpr, context: any): any;
384
394
  visitWrappedNodeExpr(ast: WrappedNodeExpr<any>, context: any): any;
385
395
  visitTypeofExpr(ast: TypeofExpr, context: any): any;
396
+ visitArrowFunctionExpr(ast: ArrowFunctionExpr, context: any): any;
386
397
  }
387
398
  export declare const NULL_EXPR: LiteralExpr;
388
399
  export declare const TYPED_NULL_EXPR: LiteralExpr;
@@ -480,6 +491,7 @@ export declare function literalMap(values: {
480
491
  export declare function unary(operator: UnaryOperator, expr: Expression, type?: Type, sourceSpan?: ParseSourceSpan | null): UnaryOperatorExpr;
481
492
  export declare function not(expr: Expression, sourceSpan?: ParseSourceSpan | null): NotExpr;
482
493
  export declare function fn(params: FnParam[], body: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, name?: string | null): FunctionExpr;
494
+ export declare function arrowFn(params: FnParam[], body: Expression | Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null): ArrowFunctionExpr;
483
495
  export declare function ifStmt(condition: Expression, thenClause: Statement[], elseClause?: Statement[], sourceSpan?: ParseSourceSpan, leadingComments?: LeadingComment[]): IfStmt;
484
496
  export declare function literal(value: any, type?: Type | null, sourceSpan?: ParseSourceSpan | null): LiteralExpr;
485
497
  export declare function isNull(exp: Expression): boolean;
@@ -7,8 +7,8 @@
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.TYPED_NULL_EXPR = exports.NULL_EXPR = exports.CommaExpr = exports.LiteralMapExpr = exports.LiteralMapEntry = exports.LiteralArrayExpr = exports.ReadKeyExpr = exports.ReadPropExpr = exports.BinaryOperatorExpr = exports.UnaryOperatorExpr = exports.FunctionExpr = exports.FnParam = exports.NotExpr = exports.DynamicImportExpr = exports.ConditionalExpr = exports.ExternalReference = exports.ExternalExpr = exports.LiteralPiece = exports.TemplateLiteralElement = exports.TemplateLiteral = exports.LiteralExpr = exports.InstantiateExpr = exports.InvokeFunctionExpr = exports.WritePropExpr = exports.WriteKeyExpr = exports.WriteVarExpr = exports.WrappedNodeExpr = exports.TypeofExpr = exports.ReadVarExpr = exports.Expression = exports.areAllEquivalent = exports.nullSafeIsEquivalent = exports.BinaryOperator = exports.UnaryOperator = exports.NONE_TYPE = exports.FUNCTION_TYPE = exports.STRING_TYPE = exports.NUMBER_TYPE = exports.INT_TYPE = exports.BOOL_TYPE = exports.INFERRED_TYPE = exports.DYNAMIC_TYPE = exports.TransplantedType = exports.MapType = exports.ArrayType = exports.ExpressionType = exports.BuiltinType = exports.BuiltinTypeName = exports.Type = exports.TypeModifier = void 0;
11
- exports.isNull = exports.literal = exports.ifStmt = exports.fn = exports.not = exports.unary = exports.literalMap = exports.literalArr = exports.typeofExpr = exports.transplantedType = exports.expressionType = exports.importType = exports.importExpr = exports.variable = exports.jsDocComment = exports.leadingComment = exports.IfStmt = exports.ReturnStatement = exports.ExpressionStatement = exports.DeclareFunctionStmt = exports.DeclareVarStmt = exports.Statement = exports.JSDocComment = exports.LeadingComment = exports.StmtModifier = void 0;
10
+ exports.NULL_EXPR = exports.CommaExpr = exports.LiteralMapExpr = exports.LiteralMapEntry = exports.LiteralArrayExpr = exports.ReadKeyExpr = exports.ReadPropExpr = exports.BinaryOperatorExpr = exports.UnaryOperatorExpr = exports.ArrowFunctionExpr = exports.FunctionExpr = exports.FnParam = exports.NotExpr = exports.DynamicImportExpr = exports.ConditionalExpr = exports.ExternalReference = exports.ExternalExpr = exports.LiteralPiece = exports.TemplateLiteralElement = exports.TemplateLiteral = exports.LiteralExpr = exports.InstantiateExpr = exports.InvokeFunctionExpr = exports.WritePropExpr = exports.WriteKeyExpr = exports.WriteVarExpr = exports.WrappedNodeExpr = exports.TypeofExpr = exports.ReadVarExpr = exports.Expression = exports.areAllEquivalent = exports.nullSafeIsEquivalent = exports.BinaryOperator = exports.UnaryOperator = exports.NONE_TYPE = exports.FUNCTION_TYPE = exports.STRING_TYPE = exports.NUMBER_TYPE = exports.INT_TYPE = exports.BOOL_TYPE = exports.INFERRED_TYPE = exports.DYNAMIC_TYPE = exports.TransplantedType = exports.MapType = exports.ArrayType = exports.ExpressionType = exports.BuiltinType = exports.BuiltinTypeName = exports.Type = exports.TypeModifier = void 0;
11
+ exports.isNull = exports.literal = exports.ifStmt = exports.arrowFn = exports.fn = exports.not = exports.unary = exports.literalMap = exports.literalArr = exports.typeofExpr = exports.transplantedType = exports.expressionType = exports.importType = exports.importExpr = exports.variable = exports.jsDocComment = exports.leadingComment = exports.IfStmt = exports.ReturnStatement = exports.ExpressionStatement = exports.DeclareFunctionStmt = exports.DeclareVarStmt = exports.Statement = exports.JSDocComment = exports.LeadingComment = exports.StmtModifier = exports.TYPED_NULL_EXPR = void 0;
12
12
  //// Types
13
13
  var TypeModifier;
14
14
  (function (TypeModifier) {
@@ -600,7 +600,7 @@ class FunctionExpr extends Expression {
600
600
  this.name = name;
601
601
  }
602
602
  isEquivalent(e) {
603
- return (e instanceof FunctionExpr &&
603
+ return ((e instanceof FunctionExpr || e instanceof DeclareFunctionStmt) &&
604
604
  areAllEquivalent(this.params, e.params) &&
605
605
  areAllEquivalent(this.statements, e.statements));
606
606
  }
@@ -619,6 +619,44 @@ class FunctionExpr extends Expression {
619
619
  }
620
620
  }
621
621
  exports.FunctionExpr = FunctionExpr;
622
+ class ArrowFunctionExpr extends Expression {
623
+ params;
624
+ body;
625
+ // Note that `body: Expression` represents `() => expr` whereas
626
+ // `body: Statement[]` represents `() => { expr }`.
627
+ constructor(params, body, type, sourceSpan) {
628
+ super(type, sourceSpan);
629
+ this.params = params;
630
+ this.body = body;
631
+ }
632
+ isEquivalent(e) {
633
+ if (!(e instanceof ArrowFunctionExpr) ||
634
+ !areAllEquivalent(this.params, e.params)) {
635
+ return false;
636
+ }
637
+ if (this.body instanceof Expression && e.body instanceof Expression) {
638
+ return this.body.isEquivalent(e.body);
639
+ }
640
+ if (Array.isArray(this.body) && Array.isArray(e.body)) {
641
+ return areAllEquivalent(this.body, e.body);
642
+ }
643
+ return false;
644
+ }
645
+ isConstant() {
646
+ return false;
647
+ }
648
+ visitExpression(visitor, context) {
649
+ return visitor.visitArrowFunctionExpr(this, context);
650
+ }
651
+ clone() {
652
+ // TODO: Should we deep clone statements?
653
+ return new ArrowFunctionExpr(this.params.map((p) => p.clone()), Array.isArray(this.body) ? this.body : this.body.clone(), this.type, this.sourceSpan);
654
+ }
655
+ toDeclStmt(name, modifiers) {
656
+ return new DeclareVarStmt(name, this, exports.INFERRED_TYPE, modifiers, this.sourceSpan);
657
+ }
658
+ }
659
+ exports.ArrowFunctionExpr = ArrowFunctionExpr;
622
660
  class UnaryOperatorExpr extends Expression {
623
661
  operator;
624
662
  expr;
@@ -1015,6 +1053,10 @@ function fn(params, body, type, sourceSpan, name) {
1015
1053
  return new FunctionExpr(params, body, type, sourceSpan, name);
1016
1054
  }
1017
1055
  exports.fn = fn;
1056
+ function arrowFn(params, body, type, sourceSpan) {
1057
+ return new ArrowFunctionExpr(params, body, type, sourceSpan);
1058
+ }
1059
+ exports.arrowFn = arrowFn;
1018
1060
  function ifStmt(condition, thenClause, elseClause, sourceSpan, leadingComments) {
1019
1061
  return new IfStmt(condition, thenClause, elseClause, sourceSpan, leadingComments);
1020
1062
  }
@@ -116,7 +116,7 @@ function compileFactoryFunction(meta) {
116
116
  // There is a base factory variable so wrap its declaration along with the factory function into
117
117
  // an IIFE.
118
118
  factoryFn = o
119
- .fn([], [
119
+ .arrowFn([], [
120
120
  new o.DeclareVarStmt(baseFactoryVar.name),
121
121
  new o.ReturnStatement(factoryFn),
122
122
  ])
@@ -77,8 +77,6 @@ exports.convertFromMaybeForwardRefExpression = convertFromMaybeForwardRefExpress
77
77
  * ```
78
78
  */
79
79
  function generateForwardRef(expr) {
80
- return o
81
- .importExpr(r3_identifiers_1.Identifiers.forwardRef)
82
- .callFn([o.fn([], [new o.ReturnStatement(expr)])]);
80
+ return o.importExpr(r3_identifiers_1.Identifiers.forwardRef).callFn([o.arrowFn([], expr)]);
83
81
  }
84
82
  exports.generateForwardRef = generateForwardRef;
@@ -6,6 +6,8 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import * as o from '../../output/output_ast';
9
+ /** Special value representing a direct access to a template's context. */
10
+ export declare const DIRECT_CONTEXT_REFERENCE = "#context";
9
11
  /**
10
12
  * A representation for an object literal used during codegen of definition objects. The generic
11
13
  * type `T` allows to reference a documented type of the generated structure, such that the
@@ -30,8 +30,10 @@ var __importStar = (this && this.__importStar) || function (mod) {
30
30
  return result;
31
31
  };
32
32
  Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.DefinitionMap = void 0;
33
+ exports.DefinitionMap = exports.DIRECT_CONTEXT_REFERENCE = void 0;
34
34
  const o = __importStar(require("../../output/output_ast"));
35
+ /** Special value representing a direct access to a template's context. */
36
+ exports.DIRECT_CONTEXT_REFERENCE = '#context';
35
37
  /**
36
38
  * A representation for an object literal used during codegen of definition objects. The generic
37
39
  * type `T` allows to reference a documented type of the generated structure, such that the
@@ -41,7 +43,13 @@ class DefinitionMap {
41
43
  values = [];
42
44
  set(key, value) {
43
45
  if (value) {
44
- this.values.push({ key: key, value, quoted: false });
46
+ const existing = this.values.find((value) => value.key === key);
47
+ if (existing) {
48
+ existing.value = value;
49
+ }
50
+ else {
51
+ this.values.push({ key: key, value, quoted: false });
52
+ }
45
53
  }
46
54
  }
47
55
  toLiteralMap() {
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { R3DependencyMetadata } from 'static-injector/transform/compiler';
9
9
  import { ClassDeclaration, CtorParameter, ReflectionHost, UnavailableValue } from '../../../reflection';
10
+ import { CompilationMode } from '../../../transform';
10
11
  export type ConstructorDeps = {
11
12
  deps: R3DependencyMetadata[];
12
13
  } | {
@@ -18,7 +19,7 @@ export interface ConstructorDepError {
18
19
  param: CtorParameter;
19
20
  reason: UnavailableValue;
20
21
  }
21
- export declare function getConstructorDependencies(clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean): ConstructorDeps | null;
22
+ export declare function getConstructorDependencies(clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean, compilationMode: CompilationMode): ConstructorDeps | null;
22
23
  /**
23
24
  * Convert `ConstructorDeps` into the `R3DependencyMetadata` array for those deps if they're valid,
24
25
  * or into an `'invalid'` signal if they're not.
@@ -26,7 +27,7 @@ export declare function getConstructorDependencies(clazz: ClassDeclaration, refl
26
27
  * This is a companion function to `validateConstructorDependencies` which accepts invalid deps.
27
28
  */
28
29
  export declare function unwrapConstructorDependencies(deps: ConstructorDeps | null): R3DependencyMetadata[] | 'invalid' | null;
29
- export declare function getValidConstructorDependencies(clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean): R3DependencyMetadata[] | null;
30
+ export declare function getValidConstructorDependencies(clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean, compilationMode: CompilationMode): R3DependencyMetadata[] | null;
30
31
  /**
31
32
  * Validate that `ConstructorDeps` does not have any invalid dependencies and convert them into the
32
33
  * `R3DependencyMetadata` array if so, or raise a diagnostic if some deps are invalid.
@@ -14,8 +14,9 @@ exports.validateConstructorDependencies = exports.getValidConstructorDependencie
14
14
  const compiler_1 = require("static-injector/transform/compiler");
15
15
  const typescript_1 = __importDefault(require("typescript"));
16
16
  const diagnostics_1 = require("../../../diagnostics");
17
+ const transform_1 = require("../../../transform");
17
18
  const util_1 = require("./util");
18
- function getConstructorDependencies(clazz, reflector, isCore) {
19
+ function getConstructorDependencies(clazz, reflector, isCore, compilationMode) {
19
20
  const deps = [];
20
21
  const errors = [];
21
22
  let ctorParams = reflector.getConstructorParameters(clazz);
@@ -28,7 +29,26 @@ function getConstructorDependencies(clazz, reflector, isCore) {
28
29
  }
29
30
  }
30
31
  ctorParams.forEach((param, idx) => {
31
- let token = (0, util_1.valueReferenceToExpression)(param.typeValueReference);
32
+ let token = null;
33
+ if (compilationMode === transform_1.CompilationMode.LOCAL &&
34
+ param.typeValueReference.kind === 2 /* TypeValueReferenceKind.UNAVAILABLE */ &&
35
+ param.typeValueReference.reason.kind !== 0 /* ValueUnavailableKind.MISSING_TYPE */) {
36
+ // The case of local compilation where injection token cannot be resolved because it is
37
+ // "probably" imported from another file
38
+ const typeNode = param.typeValueReference.reason.typeNode;
39
+ if (typescript_1.default.isTypeReferenceNode(typeNode)) {
40
+ // Here we manually create the token out of the typeName without caring about its
41
+ // references for better TS tracking. This is because in this code path the typeNode is
42
+ // imported from another file and since we are in local compilation mode (=single file
43
+ // mode) the reference of this node (or its typeName node) cannot be resolved. So all we
44
+ // can do is just to create a new expression.
45
+ token = toQualifiedExpression(typeNode.typeName);
46
+ }
47
+ }
48
+ else {
49
+ // In all other cases resolve the injection token
50
+ token = (0, util_1.valueReferenceToExpression)(param.typeValueReference);
51
+ }
32
52
  let attributeNameType = null;
33
53
  let optional = false, self = false, skipSelf = false, host = false;
34
54
  (param.decorators || [])
@@ -80,6 +100,13 @@ function getConstructorDependencies(clazz, reflector, isCore) {
80
100
  }
81
101
  }
82
102
  exports.getConstructorDependencies = getConstructorDependencies;
103
+ /** Converts a TS qualified name to output expression. */
104
+ function toQualifiedExpression(entity) {
105
+ if (typescript_1.default.isIdentifier(entity)) {
106
+ return new compiler_1.WrappedNodeExpr(entity);
107
+ }
108
+ return new compiler_1.ReadPropExpr(toQualifiedExpression(entity.left), entity.right.text);
109
+ }
83
110
  /**
84
111
  * Convert `ConstructorDeps` into the `R3DependencyMetadata` array for those deps if they're valid,
85
112
  * or into an `'invalid'` signal if they're not.
@@ -100,8 +127,8 @@ function unwrapConstructorDependencies(deps) {
100
127
  }
101
128
  }
102
129
  exports.unwrapConstructorDependencies = unwrapConstructorDependencies;
103
- function getValidConstructorDependencies(clazz, reflector, isCore) {
104
- return validateConstructorDependencies(clazz, getConstructorDependencies(clazz, reflector, isCore));
130
+ function getValidConstructorDependencies(clazz, reflector, isCore, compilationMode) {
131
+ return validateConstructorDependencies(clazz, getConstructorDependencies(clazz, reflector, isCore, compilationMode));
105
132
  }
106
133
  exports.getValidConstructorDependencies = getValidConstructorDependencies;
107
134
  /**
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { R3DependencyMetadata, R3InjectableMetadata } from 'static-injector/transform/compiler';
9
9
  import { ClassDeclaration, Decorator, ReflectionHost } from '../../reflection';
10
- import { AnalysisOutput, CompileResult, DecoratorHandler, DetectResult } from '../../transform';
10
+ import { AnalysisOutput, CompilationMode, CompileResult, DecoratorHandler, DetectResult } from '../../transform';
11
11
  export interface InjectableHandlerData {
12
12
  meta: R3InjectableMetadata;
13
13
  ctorDeps: R3DependencyMetadata[] | 'invalid' | null;
@@ -20,6 +20,7 @@ export declare class InjectableDecoratorHandler implements DecoratorHandler<Deco
20
20
  private isCore;
21
21
  private strictCtorDeps;
22
22
  private includeClassMetadata;
23
+ private readonly compilationMode;
23
24
  /**
24
25
  * What to do if the injectable already contains a ɵprov property.
25
26
  *
@@ -27,7 +28,7 @@ export declare class InjectableDecoratorHandler implements DecoratorHandler<Deco
27
28
  * If false then there is no error and a new ɵprov property is not added.
28
29
  */
29
30
  private errorOnDuplicateProv;
30
- constructor(reflector: ReflectionHost, isCore: boolean, strictCtorDeps: boolean, includeClassMetadata: boolean,
31
+ constructor(reflector: ReflectionHost, isCore: boolean, strictCtorDeps: boolean, includeClassMetadata: boolean, compilationMode: CompilationMode,
31
32
  /**
32
33
  * What to do if the injectable already contains a ɵprov property.
33
34
  *
@@ -25,8 +25,9 @@ class InjectableDecoratorHandler {
25
25
  isCore;
26
26
  strictCtorDeps;
27
27
  includeClassMetadata;
28
+ compilationMode;
28
29
  errorOnDuplicateProv;
29
- constructor(reflector, isCore, strictCtorDeps, includeClassMetadata,
30
+ constructor(reflector, isCore, strictCtorDeps, includeClassMetadata, compilationMode,
30
31
  /**
31
32
  * What to do if the injectable already contains a ɵprov property.
32
33
  *
@@ -38,6 +39,7 @@ class InjectableDecoratorHandler {
38
39
  this.isCore = isCore;
39
40
  this.strictCtorDeps = strictCtorDeps;
40
41
  this.includeClassMetadata = includeClassMetadata;
42
+ this.compilationMode = compilationMode;
41
43
  this.errorOnDuplicateProv = errorOnDuplicateProv;
42
44
  }
43
45
  detect(node, decorators) {
@@ -61,7 +63,7 @@ class InjectableDecoratorHandler {
61
63
  return {
62
64
  analysis: {
63
65
  meta,
64
- ctorDeps: extractInjectableCtorDeps(node, meta, decorator, this.reflector, this.isCore, this.strictCtorDeps),
66
+ ctorDeps: extractInjectableCtorDeps(node, meta, decorator, this.reflector, this.isCore, this.strictCtorDeps, this.compilationMode),
65
67
  // Avoid generating multiple factories if a class has
66
68
  // more Angular decorators, apart from Injectable.
67
69
  },
@@ -179,7 +181,7 @@ function getProviderExpression(expression, reflector) {
179
181
  ? 2 /* ForwardRefHandling.Unwrapped */
180
182
  : 0 /* ForwardRefHandling.None */);
181
183
  }
182
- function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, strictCtorDeps) {
184
+ function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, strictCtorDeps, compilationMode) {
183
185
  if (decorator.args === null) {
184
186
  throw new diagnostics_1.FatalDiagnosticError(diagnostics_1.ErrorCode.DECORATOR_NOT_CALLED, decorator.node, '@Injectable must be called');
185
187
  }
@@ -194,15 +196,15 @@ function extractInjectableCtorDeps(clazz, meta, decorator, reflector, isCore, st
194
196
  // constructor signature does not work for DI then a factory definition (ɵfac) that throws is
195
197
  // generated.
196
198
  if (strictCtorDeps && !(0, common_1.isAbstractClassDeclaration)(clazz)) {
197
- ctorDeps = (0, common_2.getValidConstructorDependencies)(clazz, reflector, isCore);
199
+ ctorDeps = (0, common_2.getValidConstructorDependencies)(clazz, reflector, isCore, compilationMode);
198
200
  }
199
201
  else {
200
- ctorDeps = (0, common_2.unwrapConstructorDependencies)((0, common_2.getConstructorDependencies)(clazz, reflector, isCore));
202
+ ctorDeps = (0, common_2.unwrapConstructorDependencies)((0, common_2.getConstructorDependencies)(clazz, reflector, isCore, compilationMode));
201
203
  }
202
204
  return ctorDeps;
203
205
  }
204
206
  else if (decorator.args.length === 1) {
205
- const rawCtorDeps = (0, common_2.getConstructorDependencies)(clazz, reflector, isCore);
207
+ const rawCtorDeps = (0, common_2.getConstructorDependencies)(clazz, reflector, isCore, compilationMode);
206
208
  if (strictCtorDeps &&
207
209
  !(0, common_1.isAbstractClassDeclaration)(clazz) &&
208
210
  requiresValidCtor(meta)) {
@@ -5,8 +5,8 @@
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 * as ts from "typescript";
9
- import { ErrorCode } from "./error_code";
8
+ import * as ts from 'typescript';
9
+ import { ErrorCode } from './error_code';
10
10
  export declare class FatalDiagnosticError {
11
11
  readonly code: ErrorCode;
12
12
  readonly node: ts.Node;
@@ -182,7 +182,7 @@ var ErrorCode;
182
182
  * Keep this value in sync with a similar const in
183
183
  * `packages/core/src/render3/error_code.ts`.
184
184
  */
185
- exports.ERROR_DETAILS_PAGE_BASE_URL = "https://angular.io/errors";
185
+ exports.ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
186
186
  /**
187
187
  * @internal
188
188
  * Contains a set of error messages that have detailed guides at angular.io.
@@ -201,6 +201,6 @@ exports.COMPILER_ERRORS_WITH_GUIDES = new Set([
201
201
  * @internal
202
202
  */
203
203
  function ngErrorCode(code) {
204
- return parseInt("-99" + code);
204
+ return parseInt('-99' + code);
205
205
  }
206
206
  exports.ngErrorCode = ngErrorCode;
@@ -8,6 +8,24 @@
8
8
  import { Expression, Statement, Type } from 'static-injector/transform/compiler';
9
9
  import ts from 'typescript';
10
10
  import { ClassDeclaration, Decorator } from '../../reflection';
11
+ /**
12
+ * Specifies the compilation mode that is used for the compilation.
13
+ */
14
+ export declare enum CompilationMode {
15
+ /**
16
+ * Generates fully AOT compiled code using Ivy instructions.
17
+ */
18
+ FULL = 0,
19
+ /**
20
+ * Generates code using a stable, but intermediate format suitable to be published to NPM.
21
+ */
22
+ PARTIAL = 1,
23
+ /**
24
+ * Generates code based on each individual source file without using its
25
+ * dependencies (suitable for local dev edit/refresh workflow).
26
+ */
27
+ LOCAL = 2
28
+ }
11
29
  /**
12
30
  * Provides the interface between a decorator compiler from @angular/compiler and the Typescript
13
31
  * compiler/transform.
@@ -7,3 +7,23 @@
7
7
  * found in the LICENSE file at https://angular.io/license
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.CompilationMode = void 0;
11
+ /**
12
+ * Specifies the compilation mode that is used for the compilation.
13
+ */
14
+ var CompilationMode;
15
+ (function (CompilationMode) {
16
+ /**
17
+ * Generates fully AOT compiled code using Ivy instructions.
18
+ */
19
+ CompilationMode[CompilationMode["FULL"] = 0] = "FULL";
20
+ /**
21
+ * Generates code using a stable, but intermediate format suitable to be published to NPM.
22
+ */
23
+ CompilationMode[CompilationMode["PARTIAL"] = 1] = "PARTIAL";
24
+ /**
25
+ * Generates code based on each individual source file without using its
26
+ * dependencies (suitable for local dev edit/refresh workflow).
27
+ */
28
+ CompilationMode[CompilationMode["LOCAL"] = 2] = "LOCAL";
29
+ })(CompilationMode || (exports.CompilationMode = CompilationMode = {}));
@@ -93,6 +93,14 @@ export interface AstFactory<TStatement, TExpression> {
93
93
  * @param body a statement (or a block of statements) that are the body of the function.
94
94
  */
95
95
  createFunctionExpression(functionName: string | null, parameters: string[], body: TStatement): TExpression;
96
+ /**
97
+ * Create an expression that represents an arrow function
98
+ * (e.g. `(param1, param2) => body`).
99
+ *
100
+ * @param parameters the names of the function's parameters.
101
+ * @param body an expression or block of statements that are the body of the function.
102
+ */
103
+ createArrowFunctionExpression(parameters: string[], body: TExpression | TStatement): TExpression;
96
104
  /**
97
105
  * Creates an expression that represents a dynamic import
98
106
  * (e.g. `import('./some/path')`)
@@ -40,6 +40,7 @@ export declare class ExpressionTranslatorVisitor<TStatement, TExpression> implem
40
40
  visitDynamicImportExpr(ast: o.DynamicImportExpr, context: any): TExpression;
41
41
  visitNotExpr(ast: o.NotExpr, context: Context): TExpression;
42
42
  visitFunctionExpr(ast: o.FunctionExpr, context: Context): TExpression;
43
+ visitArrowFunctionExpr(ast: o.ArrowFunctionExpr, context: any): TExpression;
43
44
  visitBinaryOperatorExpr(ast: o.BinaryOperatorExpr, context: Context): TExpression;
44
45
  visitReadPropExpr(ast: o.ReadPropExpr, context: Context): TExpression;
45
46
  visitReadKeyExpr(ast: o.ReadKeyExpr, context: Context): TExpression;
@@ -186,6 +186,11 @@ class ExpressionTranslatorVisitor {
186
186
  visitFunctionExpr(ast, context) {
187
187
  return this.factory.createFunctionExpression(ast.name ?? null, ast.params.map((param) => param.name), this.factory.createBlock(this.visitStatements(ast.statements, context)));
188
188
  }
189
+ visitArrowFunctionExpr(ast, context) {
190
+ return this.factory.createArrowFunctionExpression(ast.params.map((param) => param.name), Array.isArray(ast.body)
191
+ ? this.factory.createBlock(this.visitStatements(ast.body, context))
192
+ : ast.body.visitExpression(this, context));
193
+ }
189
194
  visitBinaryOperatorExpr(ast, context) {
190
195
  if (!BINARY_OPERATORS.has(ast.operator)) {
191
196
  throw new Error(`Unknown binary operator: ${o.BinaryOperator[ast.operator]}`);
@@ -26,6 +26,7 @@ export declare class TypeScriptAstFactory implements AstFactory<ts.Statement, ts
26
26
  createDynamicImport(url: string): ts.CallExpression;
27
27
  createFunctionDeclaration(functionName: string, parameters: string[], body: ts.Statement): ts.Statement;
28
28
  createFunctionExpression(functionName: string | null, parameters: string[], body: ts.Statement): ts.Expression;
29
+ createArrowFunctionExpression(parameters: string[], body: ts.Statement | ts.Expression): ts.Expression;
29
30
  createIdentifier: (text: string) => ts.Identifier;
30
31
  createIfStatement(condition: ts.Expression, thenStatement: ts.Statement, elseStatement: ts.Statement | null): ts.Statement;
31
32
  createLiteral(value: string | number | boolean | null | undefined): ts.Expression;
@@ -106,6 +106,12 @@ class TypeScriptAstFactory {
106
106
  }
107
107
  return typescript_1.default.factory.createFunctionExpression(undefined, undefined, functionName ?? undefined, undefined, parameters.map((param) => typescript_1.default.factory.createParameterDeclaration(undefined, undefined, param)), undefined, body);
108
108
  }
109
+ createArrowFunctionExpression(parameters, body) {
110
+ if (typescript_1.default.isStatement(body) && !typescript_1.default.isBlock(body)) {
111
+ throw new Error(`Invalid syntax, expected a block, but got ${typescript_1.default.SyntaxKind[body.kind]}.`);
112
+ }
113
+ return typescript_1.default.factory.createArrowFunction(undefined, undefined, parameters.map((param) => typescript_1.default.factory.createParameterDeclaration(undefined, undefined, param)), undefined, undefined, body);
114
+ }
109
115
  createIdentifier = typescript_1.default.factory.createIdentifier;
110
116
  createIfStatement(condition, thenStatement, elseStatement) {
111
117
  return typescript_1.default.factory.createIfStatement(condition, thenStatement, elseStatement ?? undefined);
@@ -1 +1 @@
1
- export * from "./injectable-transform";
1
+ export * from './injectable-transform';
@@ -28,7 +28,7 @@ class InjectableTransformerFactory {
28
28
  this.options = options;
29
29
  this.typeChecker = this.program.getTypeChecker();
30
30
  this.reflectionHost = new reflection_1.TypeScriptReflectionHost(this.typeChecker);
31
- this.handler = new injectable_1.InjectableDecoratorHandler(this.reflectionHost, false, !!this.options.strictCtorDeps, false);
31
+ this.handler = new injectable_1.InjectableDecoratorHandler(this.reflectionHost, false, !!this.options.strictCtorDeps, false, transform_1.CompilationMode.FULL);
32
32
  }
33
33
  getTransform() {
34
34
  return (context) => this.transform(context);