pending-tasks.cjs 3.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. 'use strict';
  2. /**
  3. * @license Angular v19.2.13
  4. * (c) 2010-2025 Google LLC. https://angular.io/
  5. * License: MIT
  6. */
  7. 'use strict';
  8. var schematics = require('@angular-devkit/schematics');
  9. var p = require('path');
  10. var project_tsconfig_paths = require('./project_tsconfig_paths-CDVxT6Ov.cjs');
  11. var compiler_host = require('./compiler_host-B1Gyeytz.cjs');
  12. var ts = require('typescript');
  13. var imports = require('./imports-CIX-JgAN.cjs');
  14. require('@angular-devkit/core');
  15. require('./checker-5pyJrZ9G.cjs');
  16. require('os');
  17. require('fs');
  18. require('module');
  19. require('url');
  20. const CORE = '@angular/core';
  21. const EXPERIMENTAL_PENDING_TASKS = 'ExperimentalPendingTasks';
  22. function migrateFile(sourceFile, typeChecker, rewriteFn) {
  23. const changeTracker = new compiler_host.ChangeTracker(ts.createPrinter());
  24. // Check if there are any imports of the `AfterRenderPhase` enum.
  25. const coreImports = imports.getNamedImports(sourceFile, CORE);
  26. if (!coreImports) {
  27. return;
  28. }
  29. const importSpecifier = imports.getImportSpecifier(sourceFile, CORE, EXPERIMENTAL_PENDING_TASKS);
  30. if (!importSpecifier) {
  31. return;
  32. }
  33. const nodeToReplace = importSpecifier.propertyName ?? importSpecifier.name;
  34. if (!ts.isIdentifier(nodeToReplace)) {
  35. return;
  36. }
  37. changeTracker.replaceNode(nodeToReplace, ts.factory.createIdentifier('PendingTasks'));
  38. ts.forEachChild(sourceFile, function visit(node) {
  39. // import handled above
  40. if (ts.isImportDeclaration(node)) {
  41. return;
  42. }
  43. if (ts.isIdentifier(node) &&
  44. node.text === EXPERIMENTAL_PENDING_TASKS &&
  45. imports.getImportOfIdentifier(typeChecker, node)?.name === EXPERIMENTAL_PENDING_TASKS) {
  46. changeTracker.replaceNode(node, ts.factory.createIdentifier('PendingTasks'));
  47. }
  48. ts.forEachChild(node, visit);
  49. });
  50. // Write the changes.
  51. for (const changesInFile of changeTracker.recordChanges().values()) {
  52. for (const change of changesInFile) {
  53. rewriteFn(change.start, change.removeLength ?? 0, change.text);
  54. }
  55. }
  56. }
  57. function migrate() {
  58. return async (tree) => {
  59. const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
  60. const basePath = process.cwd();
  61. const allPaths = [...buildPaths, ...testPaths];
  62. if (!allPaths.length) {
  63. throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the afterRender phase migration.');
  64. }
  65. for (const tsconfigPath of allPaths) {
  66. runMigration(tree, tsconfigPath, basePath);
  67. }
  68. };
  69. }
  70. function runMigration(tree, tsconfigPath, basePath) {
  71. const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
  72. const sourceFiles = program
  73. .getSourceFiles()
  74. .filter((sourceFile) => compiler_host.canMigrateFile(basePath, sourceFile, program));
  75. for (const sourceFile of sourceFiles) {
  76. let update = null;
  77. const rewriter = (startPos, width, text) => {
  78. if (update === null) {
  79. // Lazily initialize update, because most files will not require migration.
  80. update = tree.beginUpdate(p.relative(basePath, sourceFile.fileName));
  81. }
  82. update.remove(startPos, width);
  83. if (text !== null) {
  84. update.insertLeft(startPos, text);
  85. }
  86. };
  87. migrateFile(sourceFile, program.getTypeChecker(), rewriter);
  88. if (update !== null) {
  89. tree.commitUpdate(update);
  90. }
  91. }
  92. }
  93. exports.migrate = migrate;