static-injector 2.2.1 → 4.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 (93) hide show
  1. package/import/commonjs/index.js +94 -50
  2. package/import/es2022/di/index.js +1 -0
  3. package/import/es2022/di/initializer_token.js +1 -1
  4. package/import/es2022/di/inject_switch.js +1 -2
  5. package/import/es2022/di/injection_token.js +13 -6
  6. package/import/es2022/di/injector.js +3 -3
  7. package/import/es2022/di/injector_compatibility.js +23 -0
  8. package/import/es2022/di/injector_token.js +2 -3
  9. package/import/es2022/di/internal_tokens.js +1 -1
  10. package/import/es2022/di/r3_injector.js +19 -16
  11. package/import/es2022/di/scope.js +1 -1
  12. package/import/es2022/di.js +24 -0
  13. package/import/es2022/render3/errors_di.js +2 -2
  14. package/import/es2022/render3/instructions/di.js +7 -0
  15. package/import/es2022/render3/util/stringify_utils.js +1 -0
  16. package/import/es2022/util/array_utils.js +7 -0
  17. package/import/es2022/util/stringify.js +15 -0
  18. package/import/fesm2022/index.js +88 -44
  19. package/import/typings/di/create_injector.d.ts +2 -2
  20. package/import/typings/di/forward_ref.d.ts +1 -1
  21. package/import/typings/di/index.d.ts +1 -0
  22. package/import/typings/di/initializer_token.d.ts +1 -1
  23. package/import/typings/di/injection_token.d.ts +11 -6
  24. package/import/typings/di/injector.d.ts +3 -3
  25. package/import/typings/di/injector_compatibility.d.ts +2 -1
  26. package/import/typings/di/injector_token.d.ts +1 -1
  27. package/import/typings/di/interface/provider.d.ts +12 -12
  28. package/import/typings/di/internal_tokens.d.ts +1 -1
  29. package/import/typings/di/metadata.d.ts +2 -2
  30. package/import/typings/di/null_injector.d.ts +1 -1
  31. package/import/typings/di/r3_injector.d.ts +1 -1
  32. package/import/typings/di.d.ts +24 -0
  33. package/import/typings/errors.d.ts +11 -3
  34. package/import/typings/render3/errors_di.d.ts +2 -1
  35. package/import/typings/render3/instructions/di.d.ts +7 -0
  36. package/import/typings/render3/util/stringify_utils.d.ts +1 -0
  37. package/import/typings/util/array_utils.d.ts +7 -0
  38. package/import/typings/util/empty.d.ts +1 -1
  39. package/import/typings/util/stringify.d.ts +8 -0
  40. package/package.json +7 -5
  41. package/readme.md +2 -2
  42. package/transform/compiler/src/compiler.d.ts +0 -22
  43. package/transform/compiler/src/compiler.js +0 -26
  44. package/transform/compiler/src/core.d.ts +6 -0
  45. package/transform/compiler/src/core.js +13 -0
  46. package/transform/compiler/src/injectable_compiler_2.js +2 -2
  47. package/transform/compiler/src/output/output_ast.d.ts +21 -7
  48. package/transform/compiler/src/output/output_ast.js +55 -9
  49. package/transform/compiler/src/render3/partial/api.d.ts +5 -0
  50. package/transform/compiler/src/render3/r3_factory.js +1 -1
  51. package/transform/compiler/src/render3/r3_identifiers.js +4 -0
  52. package/transform/compiler/src/render3/util.js +1 -3
  53. package/transform/compiler/src/render3/view/util.d.ts +2 -0
  54. package/transform/compiler/src/render3/view/util.js +10 -2
  55. package/transform/compiler-cli/src/ngtsc/annotations/common/index.d.ts +0 -7
  56. package/transform/compiler-cli/src/ngtsc/annotations/common/index.js +0 -7
  57. package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.d.ts +3 -0
  58. package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +14 -2
  59. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +3 -2
  60. package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +3 -1
  61. package/transform/compiler-cli/src/ngtsc/diagnostics/error.d.ts +2 -2
  62. package/transform/compiler-cli/src/ngtsc/diagnostics/error_code.js +2 -2
  63. package/transform/compiler-cli/src/ngtsc/diagnostics/index.d.ts +0 -7
  64. package/transform/compiler-cli/src/ngtsc/diagnostics/index.js +0 -7
  65. package/transform/compiler-cli/src/ngtsc/imports/index.d.ts +0 -7
  66. package/transform/compiler-cli/src/ngtsc/imports/index.js +0 -7
  67. package/transform/compiler-cli/src/ngtsc/reflection/index.d.ts +0 -7
  68. package/transform/compiler-cli/src/ngtsc/reflection/index.js +0 -7
  69. package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +7 -2
  70. package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +3 -1
  71. package/transform/compiler-cli/src/ngtsc/reflection/src/type_to_value.d.ts +2 -1
  72. package/transform/compiler-cli/src/ngtsc/reflection/src/type_to_value.js +16 -5
  73. package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +4 -3
  74. package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +25 -9
  75. package/transform/compiler-cli/src/ngtsc/transform/index.d.ts +0 -7
  76. package/transform/compiler-cli/src/ngtsc/transform/index.js +0 -7
  77. package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +18 -0
  78. package/transform/compiler-cli/src/ngtsc/transform/src/api.js +20 -0
  79. package/transform/compiler-cli/src/ngtsc/transform/src/utils.d.ts +1 -1
  80. package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +35 -24
  81. package/transform/compiler-cli/src/ngtsc/translator/index.d.ts +0 -7
  82. package/transform/compiler-cli/src/ngtsc/translator/index.js +0 -7
  83. package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +9 -1
  84. package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.d.ts +21 -3
  85. package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +13 -3
  86. package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +1 -0
  87. package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +6 -0
  88. package/transform/compiler-cli/src/ngtsc/translator/src/ts_util.d.ts +12 -0
  89. package/transform/compiler-cli/src/ngtsc/translator/src/ts_util.js +27 -0
  90. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +1 -0
  91. package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +9 -1
  92. package/transform/index.d.ts +1 -1
  93. package/transform/injectable-transform.js +2 -2
@@ -1,11 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
3
  if (k2 === undefined) k2 = k;
11
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -209,7 +209,7 @@ export interface ImportedTypeValueReference {
209
209
  * When `null` or empty, the `importedName` itself is the symbol being referenced.
210
210
  */
211
211
  nestedPath: string[] | null;
212
- valueDeclaration: DeclarationNode;
212
+ valueDeclaration: DeclarationNode | null;
213
213
  }
214
214
  /**
215
215
  * A representation for a type value reference that is used when no value is available. This can
@@ -410,6 +410,11 @@ export interface Import {
410
410
  * A type that is used to identify a declaration.
411
411
  */
412
412
  export type DeclarationNode = ts.Declaration;
413
+ export type AmbientImport = {
414
+ __brand: 'AmbientImport';
415
+ };
416
+ /** Indicates that a declaration is referenced through an ambient type. */
417
+ export declare const AmbientImport: AmbientImport;
413
418
  /**
414
419
  * The declaration of a symbol, along with information about how it was imported into the
415
420
  * application.
@@ -420,7 +425,7 @@ export interface Declaration<T extends ts.Declaration = ts.Declaration> {
420
425
  * was imported via an absolute module (even through a chain of re-exports). If the symbol is part
421
426
  * of the application and was not imported from an absolute path, this will be `null`.
422
427
  */
423
- viaModule: string | null;
428
+ viaModule: string | AmbientImport | null;
424
429
  /**
425
430
  * TypeScript reference to the declaration itself, if one exists.
426
431
  */
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.ClassMemberKind = exports.isDecoratorIdentifier = void 0;
13
+ exports.AmbientImport = exports.ClassMemberKind = exports.isDecoratorIdentifier = void 0;
14
14
  const typescript_1 = __importDefault(require("typescript"));
15
15
  function isDecoratorIdentifier(exp) {
16
16
  return (typescript_1.default.isIdentifier(exp) ||
@@ -30,3 +30,5 @@ var ClassMemberKind;
30
30
  ClassMemberKind[ClassMemberKind["Property"] = 3] = "Property";
31
31
  ClassMemberKind[ClassMemberKind["Method"] = 4] = "Method";
32
32
  })(ClassMemberKind || (exports.ClassMemberKind = ClassMemberKind = {}));
33
+ /** Indicates that a declaration is referenced through an ambient type. */
34
+ exports.AmbientImport = {};
@@ -14,7 +14,7 @@ import { TypeValueReference } from './host';
14
14
  * This can return `null` if the `typeNode` is `null`, if it does not refer to a symbol with a value
15
15
  * declaration, or if it is not possible to statically understand.
16
16
  */
17
- export declare function typeToValue(typeNode: ts.TypeNode | null, checker: ts.TypeChecker): TypeValueReference;
17
+ export declare function typeToValue(typeNode: ts.TypeNode | null, checker: ts.TypeChecker, isLocalCompilation: boolean): TypeValueReference;
18
18
  /**
19
19
  * Attempt to extract a `ts.Expression` that's equivalent to a `ts.TypeNode`, as the two have
20
20
  * different AST shapes but can reference the same symbols.
@@ -22,3 +22,4 @@ export declare function typeToValue(typeNode: ts.TypeNode | null, checker: ts.Ty
22
22
  * This will return `null` if an equivalent expression cannot be constructed.
23
23
  */
24
24
  export declare function typeNodeToValueExpr(node: ts.TypeNode): ts.Expression | null;
25
+ export declare function entityNameToValue(node: ts.EntityName): ts.Expression | null;
@@ -10,7 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  return (mod && mod.__esModule) ? mod : { "default": mod };
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.typeNodeToValueExpr = exports.typeToValue = void 0;
13
+ exports.entityNameToValue = exports.typeNodeToValueExpr = exports.typeToValue = void 0;
14
14
  const typescript_1 = __importDefault(require("typescript"));
15
15
  /**
16
16
  * Potentially convert a `ts.TypeNode` to a `TypeValueReference`, which indicates how to use the
@@ -19,7 +19,7 @@ const typescript_1 = __importDefault(require("typescript"));
19
19
  * This can return `null` if the `typeNode` is `null`, if it does not refer to a symbol with a value
20
20
  * declaration, or if it is not possible to statically understand.
21
21
  */
22
- function typeToValue(typeNode, checker) {
22
+ function typeToValue(typeNode, checker, isLocalCompilation) {
23
23
  // It's not possible to get a value expression if the parameter doesn't even have a type.
24
24
  if (typeNode === null) {
25
25
  return missingType();
@@ -41,7 +41,17 @@ function typeToValue(typeNode, checker) {
41
41
  if (decl.declarations !== undefined && decl.declarations.length > 0) {
42
42
  typeOnlyDecl = decl.declarations[0];
43
43
  }
44
- return noValueDeclaration(typeNode, typeOnlyDecl);
44
+ // In local compilation mode a declaration is considered invalid only if it is a type related
45
+ // declaration.
46
+ if (!isLocalCompilation ||
47
+ (typeOnlyDecl &&
48
+ [
49
+ typescript_1.default.SyntaxKind.TypeParameter,
50
+ typescript_1.default.SyntaxKind.TypeAliasDeclaration,
51
+ typescript_1.default.SyntaxKind.InterfaceDeclaration,
52
+ ].includes(typeOnlyDecl.kind))) {
53
+ return noValueDeclaration(typeNode, typeOnlyDecl);
54
+ }
45
55
  }
46
56
  // The type points to a valid value declaration. Rewrite the TypeReference into an
47
57
  // Expression which references the value pointed to by the TypeReference, if possible.
@@ -85,7 +95,7 @@ function typeToValue(typeNode, checker) {
85
95
  const moduleName = extractModuleName(firstDecl.parent.parent.parent);
86
96
  return {
87
97
  kind: 1 /* TypeValueReferenceKind.IMPORTED */,
88
- valueDeclaration: decl.valueDeclaration,
98
+ valueDeclaration: decl.valueDeclaration ?? null,
89
99
  moduleName,
90
100
  importedName,
91
101
  nestedPath,
@@ -109,7 +119,7 @@ function typeToValue(typeNode, checker) {
109
119
  const moduleName = extractModuleName(firstDecl.parent.parent);
110
120
  return {
111
121
  kind: 1 /* TypeValueReferenceKind.IMPORTED */,
112
- valueDeclaration: decl.valueDeclaration,
122
+ valueDeclaration: decl.valueDeclaration ?? null,
113
123
  moduleName,
114
124
  importedName,
115
125
  nestedPath,
@@ -252,6 +262,7 @@ function entityNameToValue(node) {
252
262
  return null;
253
263
  }
254
264
  }
265
+ exports.entityNameToValue = entityNameToValue;
255
266
  function extractModuleName(node) {
256
267
  if (!typescript_1.default.isStringLiteral(node.moduleSpecifier)) {
257
268
  throw new Error('not a module specifier');
@@ -12,7 +12,8 @@ import { ClassDeclaration, ClassMember, CtorParameter, DeclarationNode, Decorato
12
12
  */
13
13
  export declare class TypeScriptReflectionHost implements ReflectionHost {
14
14
  protected checker: ts.TypeChecker;
15
- constructor(checker: ts.TypeChecker);
15
+ private readonly isLocalCompilation;
16
+ constructor(checker: ts.TypeChecker, isLocalCompilation?: boolean);
16
17
  getDecoratorsOfDeclaration(declaration: DeclarationNode): Decorator[] | null;
17
18
  getMembersOfClass(clazz: ClassDeclaration): ClassMember[];
18
19
  getConstructorParameters(clazz: ClassDeclaration): CtorParameter[] | null;
@@ -43,10 +44,10 @@ export declare class TypeScriptReflectionHost implements ReflectionHost {
43
44
  protected getImportOfNamespacedIdentifier(id: ts.Identifier, namespaceIdentifier: ts.Identifier | null): Import | null;
44
45
  private _reflectDecorator;
45
46
  private _reflectMember;
47
+ private _viaModule;
46
48
  }
47
49
  export declare function reflectObjectLiteral(node: ts.ObjectLiteralExpression): Map<string, ts.Expression>;
48
50
  /**
49
- * Return the ImportDeclaration for the given `node` if it is either an `ImportSpecifier` or a
50
- * `NamespaceImport`. If not return `null`.
51
+ * Gets the closest ancestor `ImportDeclaration` to a node.
51
52
  */
52
53
  export declare function getContainingImportDeclaration(node: ts.Node): ts.ImportDeclaration | null;
@@ -20,8 +20,10 @@ const util_1 = require("./util");
20
20
  */
21
21
  class TypeScriptReflectionHost {
22
22
  checker;
23
- constructor(checker) {
23
+ isLocalCompilation;
24
+ constructor(checker, isLocalCompilation = false) {
24
25
  this.checker = checker;
26
+ this.isLocalCompilation = isLocalCompilation;
25
27
  }
26
28
  getDecoratorsOfDeclaration(declaration) {
27
29
  const decorators = typescript_1.default.canHaveDecorators(declaration)
@@ -70,7 +72,7 @@ class TypeScriptReflectionHost {
70
72
  typeNode = childTypeNodes[0];
71
73
  }
72
74
  }
73
- const typeValueReference = (0, type_to_value_1.typeToValue)(typeNode, this.checker);
75
+ const typeValueReference = (0, type_to_value_1.typeToValue)(typeNode, this.checker, this.isLocalCompilation);
74
76
  return {
75
77
  name,
76
78
  nameNode: node.name,
@@ -280,6 +282,18 @@ class TypeScriptReflectionHost {
280
282
  isStatic,
281
283
  };
282
284
  }
285
+ _viaModule(declaration, originalId, importInfo) {
286
+ if (importInfo === null &&
287
+ originalId !== null &&
288
+ declaration.getSourceFile() !== originalId.getSourceFile()) {
289
+ return host_1.AmbientImport;
290
+ }
291
+ return importInfo !== null &&
292
+ importInfo.from !== null &&
293
+ !importInfo.from.startsWith('.')
294
+ ? importInfo.from
295
+ : null;
296
+ }
283
297
  }
284
298
  exports.TypeScriptReflectionHost = TypeScriptReflectionHost;
285
299
  function reflectObjectLiteral(node) {
@@ -353,15 +367,17 @@ function getFarLeftIdentifier(propertyAccess) {
353
367
  : null;
354
368
  }
355
369
  /**
356
- * Return the ImportDeclaration for the given `node` if it is either an `ImportSpecifier` or a
357
- * `NamespaceImport`. If not return `null`.
370
+ * Gets the closest ancestor `ImportDeclaration` to a node.
358
371
  */
359
372
  function getContainingImportDeclaration(node) {
360
- return typescript_1.default.isImportSpecifier(node)
361
- ? node.parent.parent.parent
362
- : typescript_1.default.isNamespaceImport(node)
363
- ? node.parent.parent
364
- : null;
373
+ let parent = node.parent;
374
+ while (parent && !typescript_1.default.isSourceFile(parent)) {
375
+ if (typescript_1.default.isImportDeclaration(parent)) {
376
+ return parent;
377
+ }
378
+ parent = parent.parent;
379
+ }
380
+ return null;
365
381
  }
366
382
  exports.getContainingImportDeclaration = getContainingImportDeclaration;
367
383
  /**
@@ -1,9 +1,2 @@
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
1
  export * from './src/api';
9
2
  export * from './src/utils';
@@ -1,11 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
3
  if (k2 === undefined) k2 = k;
11
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -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 = {}));
@@ -12,4 +12,4 @@ import { ImportManager } from '../../translator';
12
12
  * and before the module body.
13
13
  * Can optionally add extra statements (e.g. new constants) before the body as well.
14
14
  */
15
- export declare function addImports(importManager: ImportManager, sf: ts.SourceFile, extraStatements?: ts.Statement[]): ts.SourceFile;
15
+ export declare function addImports(factory: ts.NodeFactory | undefined, importManager: ImportManager, sf: ts.SourceFile, extraStatements?: ts.Statement[]): ts.SourceFile;
@@ -17,29 +17,13 @@ const typescript_1 = __importDefault(require("typescript"));
17
17
  * and before the module body.
18
18
  * Can optionally add extra statements (e.g. new constants) before the body as well.
19
19
  */
20
- function addImports(importManager, sf, extraStatements = []) {
20
+ function addImports(factory = typescript_1.default.factory, importManager, sf, extraStatements = []) {
21
21
  // Generate the import statements to prepend.
22
- const addedImports = importManager.getAllImports(sf.fileName).map((i) => {
23
- const qualifier = typescript_1.default.factory.createIdentifier(i.qualifier.text);
24
- const importClause = typescript_1.default.factory.createImportClause(
25
- /* isTypeOnly */ false,
26
- /* name */ undefined,
27
- /* namedBindings */ typescript_1.default.factory.createNamespaceImport(qualifier));
28
- const decl = typescript_1.default.factory.createImportDeclaration(
29
- /* modifiers */ undefined,
30
- /* importClause */ importClause,
31
- /* moduleSpecifier */ typescript_1.default.factory.createStringLiteral(i.specifier));
32
- // Set the qualifier's original TS node to the `ts.ImportDeclaration`. This allows downstream
33
- // transforms such as tsickle to properly process references to this import.
34
- //
35
- // This operation is load-bearing in g3 as some imported modules contain special metadata
36
- // generated by clutz, which tsickle uses to transform imports and references to those imports.
37
- //
38
- // TODO(alxhub): add a test for this when tsickle is updated externally to depend on this
39
- // behavior.
40
- typescript_1.default.setOriginalNode(i.qualifier, decl);
41
- return decl;
42
- });
22
+ const addedImports = importManager
23
+ .getAllImports(sf.fileName)
24
+ .map((i) => i.qualifier !== null
25
+ ? createNamespaceImportDecl(i, factory)
26
+ : createSideEffectImportDecl(i, factory));
43
27
  // Filter out the existing imports and the source file body. All new statements
44
28
  // will be inserted between them.
45
29
  const existingImports = sf.statements.filter((stmt) => isImportStatement(stmt));
@@ -49,8 +33,8 @@ function addImports(importManager, sf, extraStatements = []) {
49
33
  // If we prepend imports, we also prepend NotEmittedStatement to use it as an anchor
50
34
  // for @fileoverview Closure annotation. If there is no @fileoverview annotations, this
51
35
  // statement would be a noop.
52
- const fileoverviewAnchorStmt = typescript_1.default.factory.createNotEmittedStatement(sf);
53
- return typescript_1.default.factory.updateSourceFile(sf, typescript_1.default.factory.createNodeArray([
36
+ const fileoverviewAnchorStmt = factory.createNotEmittedStatement(sf);
37
+ return factory.updateSourceFile(sf, factory.createNodeArray([
54
38
  fileoverviewAnchorStmt,
55
39
  ...existingImports,
56
40
  ...addedImports,
@@ -61,6 +45,33 @@ function addImports(importManager, sf, extraStatements = []) {
61
45
  return sf;
62
46
  }
63
47
  exports.addImports = addImports;
48
+ function createNamespaceImportDecl(i, factory) {
49
+ const qualifier = factory.createIdentifier(i.qualifier.text);
50
+ const importClause = factory.createImportClause(
51
+ /* isTypeOnly */ false,
52
+ /* name */ undefined,
53
+ /* namedBindings */ factory.createNamespaceImport(qualifier));
54
+ const decl = factory.createImportDeclaration(
55
+ /* modifiers */ undefined,
56
+ /* importClause */ importClause,
57
+ /* moduleSpecifier */ factory.createStringLiteral(i.specifier));
58
+ // Set the qualifier's original TS node to the `ts.ImportDeclaration`. This allows downstream
59
+ // transforms such as tsickle to properly process references to this import.
60
+ //
61
+ // This operation is load-bearing in g3 as some imported modules contain special metadata
62
+ // generated by clutz, which tsickle uses to transform imports and references to those imports.
63
+ //
64
+ // TODO(alxhub): add a test for this when tsickle is updated externally to depend on this
65
+ // behavior.
66
+ typescript_1.default.setOriginalNode(i.qualifier, decl);
67
+ return decl;
68
+ }
69
+ function createSideEffectImportDecl(i, factory) {
70
+ return factory.createImportDeclaration(
71
+ /* modifiers */ undefined,
72
+ /* importClause */ undefined,
73
+ /* moduleSpecifier */ typescript_1.default.factory.createStringLiteral(i.specifier));
74
+ }
64
75
  function isImportStatement(stmt) {
65
76
  return (typescript_1.default.isImportDeclaration(stmt) ||
66
77
  typescript_1.default.isImportEqualsDeclaration(stmt) ||
@@ -1,10 +1,3 @@
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
1
  export * from './src/context';
9
2
  export * from './src/translator';
10
3
  export * from './src/typescript_ast_factory';
@@ -1,11 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * @license
4
- * Copyright Google LLC All Rights Reserved.
5
- *
6
- * Use of this source code is governed by an MIT-style license that can be
7
- * found in the LICENSE file at https://angular.io/license
8
- */
9
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
3
  if (k2 === undefined) k2 = k;
11
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -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')`)
@@ -213,7 +221,7 @@ export type UnaryOperator = '+' | '-' | '!';
213
221
  /**
214
222
  * The binary operators supported by the `AstFactory`.
215
223
  */
216
- export type BinaryOperator = '&&' | '>' | '>=' | '&' | '/' | '==' | '===' | '<' | '<=' | '-' | '%' | '*' | '!=' | '!==' | '||' | '+' | '??';
224
+ export type BinaryOperator = '&&' | '>' | '>=' | '&' | '|' | '/' | '==' | '===' | '<' | '<=' | '-' | '%' | '*' | '!=' | '!==' | '||' | '+' | '??';
217
225
  /**
218
226
  * The original location of the start or end of a node created by the `AstFactory`.
219
227
  */
@@ -9,21 +9,39 @@ import ts from 'typescript';
9
9
  import { ImportRewriter } from '../../imports';
10
10
  import { ImportGenerator, NamedImport } from './api/import_generator';
11
11
  /**
12
- * Information about an import that has been added to a module.
12
+ * Information about a namespace import that has been added to a module.
13
13
  */
14
- export interface Import {
14
+ export interface NamespaceImport {
15
15
  /** The name of the module that has been imported. */
16
16
  specifier: string;
17
17
  /** The `ts.Identifier` by which the imported module is known. */
18
18
  qualifier: ts.Identifier;
19
19
  }
20
+ /**
21
+ * Information about a side effect import that has been added to a module.
22
+ */
23
+ export interface SideEffectImport {
24
+ /** The name of the module that has been imported. */
25
+ specifier: string;
26
+ /**
27
+ * The qualifier of a side effect import is always non-existent, and that can be used to check
28
+ * whether the import is side effect or not.
29
+ */
30
+ qualifier: null;
31
+ }
32
+ /**
33
+ * Information about an import that has been added to a module.
34
+ */
35
+ export type Import = NamespaceImport | SideEffectImport;
20
36
  export declare class ImportManager implements ImportGenerator<ts.Identifier> {
21
37
  protected rewriter: ImportRewriter;
22
38
  private prefix;
39
+ private factory;
23
40
  private specifierToIdentifier;
24
41
  private nextIndex;
25
- constructor(rewriter?: ImportRewriter, prefix?: string);
42
+ constructor(rewriter?: ImportRewriter, prefix?: string, factory?: ts.NodeFactory);
26
43
  generateNamespaceImport(moduleName: string): ts.Identifier;
27
44
  generateNamedImport(moduleName: string, originalSymbol: string): NamedImport<ts.Identifier>;
45
+ generateSideEffectImport(moduleName: string): void;
28
46
  getAllImports(contextPath: string): Import[];
29
47
  }
@@ -16,15 +16,20 @@ const imports_1 = require("../../imports");
16
16
  class ImportManager {
17
17
  rewriter;
18
18
  prefix;
19
+ factory;
19
20
  specifierToIdentifier = new Map();
20
21
  nextIndex = 0;
21
- constructor(rewriter = new imports_1.NoopImportRewriter(), prefix = 'i') {
22
+ constructor(rewriter = new imports_1.NoopImportRewriter(), prefix = 'i', factory = typescript_1.default.factory) {
22
23
  this.rewriter = rewriter;
23
24
  this.prefix = prefix;
25
+ this.factory = factory;
24
26
  }
25
27
  generateNamespaceImport(moduleName) {
26
- if (!this.specifierToIdentifier.has(moduleName)) {
27
- this.specifierToIdentifier.set(moduleName, typescript_1.default.factory.createIdentifier(`${this.prefix}${this.nextIndex++}`));
28
+ // The case `specifierToIdentifier.get(moduleName) === null` is also considered to overwrite the
29
+ // side effect import since namedspace import is enough.
30
+ if (!this.specifierToIdentifier.has(moduleName) ||
31
+ this.specifierToIdentifier.get(moduleName) === null) {
32
+ this.specifierToIdentifier.set(moduleName, this.factory.createIdentifier(`${this.prefix}${this.nextIndex++}`));
28
33
  }
29
34
  return this.specifierToIdentifier.get(moduleName);
30
35
  }
@@ -41,6 +46,11 @@ class ImportManager {
41
46
  const moduleImport = this.generateNamespaceImport(moduleName);
42
47
  return { moduleImport, symbol };
43
48
  }
49
+ generateSideEffectImport(moduleName) {
50
+ if (!this.specifierToIdentifier.has(moduleName)) {
51
+ this.specifierToIdentifier.set(moduleName, null);
52
+ }
53
+ }
44
54
  getAllImports(contextPath) {
45
55
  const imports = [];
46
56
  for (const [originalSpecifier, qualifier] of this.specifierToIdentifier) {
@@ -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;
@@ -41,6 +41,7 @@ const BINARY_OPERATORS = new Map([
41
41
  [o.BinaryOperator.Bigger, '>'],
42
42
  [o.BinaryOperator.BiggerEquals, '>='],
43
43
  [o.BinaryOperator.BitwiseAnd, '&'],
44
+ [o.BinaryOperator.BitwiseOr, '|'],
44
45
  [o.BinaryOperator.Divide, '/'],
45
46
  [o.BinaryOperator.Equals, '=='],
46
47
  [o.BinaryOperator.Identical, '==='],
@@ -186,6 +187,11 @@ class ExpressionTranslatorVisitor {
186
187
  visitFunctionExpr(ast, context) {
187
188
  return this.factory.createFunctionExpression(ast.name ?? null, ast.params.map((param) => param.name), this.factory.createBlock(this.visitStatements(ast.statements, context)));
188
189
  }
190
+ visitArrowFunctionExpr(ast, context) {
191
+ return this.factory.createArrowFunctionExpression(ast.params.map((param) => param.name), Array.isArray(ast.body)
192
+ ? this.factory.createBlock(this.visitStatements(ast.body, context))
193
+ : ast.body.visitExpression(this, context));
194
+ }
189
195
  visitBinaryOperatorExpr(ast, context) {
190
196
  if (!BINARY_OPERATORS.has(ast.operator)) {
191
197
  throw new Error(`Unknown binary operator: ${o.BinaryOperator[ast.operator]}`);
@@ -0,0 +1,12 @@
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 ts from 'typescript';
9
+ /**
10
+ * Creates a TypeScript node representing a numeric value.
11
+ */
12
+ export declare function tsNumericExpression(value: number): ts.NumericLiteral | ts.PrefixUnaryExpression;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /*!
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.io/license
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.tsNumericExpression = void 0;
14
+ const typescript_1 = __importDefault(require("typescript"));
15
+ /**
16
+ * Creates a TypeScript node representing a numeric value.
17
+ */
18
+ function tsNumericExpression(value) {
19
+ // As of TypeScript 5.3 negative numbers are represented as `prefixUnaryOperator` and passing a
20
+ // negative number (even as a string) into `createNumericLiteral` will result in an error.
21
+ if (value < 0) {
22
+ const operand = typescript_1.default.factory.createNumericLiteral(Math.abs(value));
23
+ return typescript_1.default.factory.createPrefixUnaryExpression(typescript_1.default.SyntaxKind.MinusToken, operand);
24
+ }
25
+ return typescript_1.default.factory.createNumericLiteral(value);
26
+ }
27
+ exports.tsNumericExpression = tsNumericExpression;
@@ -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;
@@ -12,6 +12,7 @@ exports.attachComments = exports.createTemplateTail = exports.createTemplateMidd
12
12
  * found in the LICENSE file at https://angular.io/license
13
13
  */
14
14
  const typescript_1 = __importDefault(require("typescript"));
15
+ const ts_util_1 = require("./ts_util");
15
16
  /**
16
17
  * Different optimizers use different annotations on a function or method call to indicate its pure
17
18
  * status.
@@ -36,6 +37,7 @@ const BINARY_OPERATORS = {
36
37
  '>': typescript_1.default.SyntaxKind.GreaterThanToken,
37
38
  '>=': typescript_1.default.SyntaxKind.GreaterThanEqualsToken,
38
39
  '&': typescript_1.default.SyntaxKind.AmpersandToken,
40
+ '|': typescript_1.default.SyntaxKind.BarToken,
39
41
  '/': typescript_1.default.SyntaxKind.SlashToken,
40
42
  '==': typescript_1.default.SyntaxKind.EqualsEqualsToken,
41
43
  '===': typescript_1.default.SyntaxKind.EqualsEqualsEqualsToken,
@@ -106,6 +108,12 @@ class TypeScriptAstFactory {
106
108
  }
107
109
  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
110
  }
111
+ createArrowFunctionExpression(parameters, body) {
112
+ if (typescript_1.default.isStatement(body) && !typescript_1.default.isBlock(body)) {
113
+ throw new Error(`Invalid syntax, expected a block, but got ${typescript_1.default.SyntaxKind[body.kind]}.`);
114
+ }
115
+ return typescript_1.default.factory.createArrowFunction(undefined, undefined, parameters.map((param) => typescript_1.default.factory.createParameterDeclaration(undefined, undefined, param)), undefined, undefined, body);
116
+ }
109
117
  createIdentifier = typescript_1.default.factory.createIdentifier;
110
118
  createIfStatement(condition, thenStatement, elseStatement) {
111
119
  return typescript_1.default.factory.createIfStatement(condition, thenStatement, elseStatement ?? undefined);
@@ -121,7 +129,7 @@ class TypeScriptAstFactory {
121
129
  return value ? typescript_1.default.factory.createTrue() : typescript_1.default.factory.createFalse();
122
130
  }
123
131
  else if (typeof value === 'number') {
124
- return typescript_1.default.factory.createNumericLiteral(value);
132
+ return (0, ts_util_1.tsNumericExpression)(value);
125
133
  }
126
134
  else {
127
135
  return typescript_1.default.factory.createStringLiteral(value);
@@ -1 +1 @@
1
- export * from "./injectable-transform";
1
+ export * from './injectable-transform';