@angular/core 19.0.0-rc.1 → 19.0.0-rc.3
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.
- package/fesm2022/core.mjs +13164 -13060
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +2 -2
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +4 -4
- package/index.d.ts +74 -13
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/bundles/{checker-9ca42e51.js → checker-e3da3b0a.js} +95 -54
- package/schematics/bundles/{combine_units-a16385aa.js → combine_units-2adebceb.js} +97 -28
- package/schematics/bundles/{compiler_host-31afa4ed.js → compiler_host-d642e87e.js} +2 -2
- package/schematics/bundles/control-flow-migration.js +3 -3
- package/schematics/bundles/explicit-standalone-flag.js +3 -3
- package/schematics/bundles/imports-4ac08251.js +1 -1
- package/schematics/bundles/inject-migration.js +3 -3
- package/schematics/bundles/leading_space-d190b83b.js +1 -1
- package/schematics/bundles/{migrate_ts_type_references-b2a28742.js → migrate_ts_type_references-ed2c0669.js} +527 -31
- package/schematics/bundles/nodes-0e7d45ca.js +1 -1
- package/schematics/bundles/output-migration.js +17 -14
- package/schematics/bundles/pending-tasks.js +3 -3
- package/schematics/bundles/{program-71beec0b.js → program-f984ab63.js} +45 -52
- package/schematics/bundles/project_tsconfig_paths-e9ccccbf.js +1 -1
- package/schematics/bundles/provide-initializer.js +3 -3
- package/schematics/bundles/route-lazy-loading.js +3 -3
- package/schematics/bundles/signal-input-migration.js +48 -35
- package/schematics/bundles/signal-queries-migration.js +21 -14
- package/schematics/bundles/signals.js +5 -5
- package/schematics/bundles/standalone-migration.js +159 -75
- package/schematics/ng-generate/signals/schema.json +1 -0
- package/testing/index.d.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-rc.
|
|
3
|
+
* @license Angular v19.0.0-rc.3
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -14,18 +14,18 @@ var signalInputMigration = require('./signal-input-migration.js');
|
|
|
14
14
|
var outputMigration = require('./output-migration.js');
|
|
15
15
|
require('./project_tsconfig_paths-e9ccccbf.js');
|
|
16
16
|
require('@angular-devkit/core');
|
|
17
|
-
require('./combine_units-
|
|
17
|
+
require('./combine_units-2adebceb.js');
|
|
18
18
|
require('node:path/posix');
|
|
19
19
|
require('os');
|
|
20
20
|
require('typescript');
|
|
21
|
-
require('./checker-
|
|
21
|
+
require('./checker-e3da3b0a.js');
|
|
22
22
|
require('fs');
|
|
23
23
|
require('module');
|
|
24
24
|
require('path');
|
|
25
25
|
require('url');
|
|
26
|
-
require('./program-
|
|
26
|
+
require('./program-f984ab63.js');
|
|
27
|
+
require('./migrate_ts_type_references-ed2c0669.js');
|
|
27
28
|
require('assert');
|
|
28
|
-
require('./migrate_ts_type_references-b2a28742.js');
|
|
29
29
|
require('./leading_space-d190b83b.js');
|
|
30
30
|
|
|
31
31
|
function migrate(options) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-rc.
|
|
3
|
+
* @license Angular v19.0.0-rc.3
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -11,11 +11,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
require('os');
|
|
13
13
|
var ts = require('typescript');
|
|
14
|
-
var checker = require('./checker-
|
|
15
|
-
var program = require('./program-
|
|
14
|
+
var checker = require('./checker-e3da3b0a.js');
|
|
15
|
+
var program = require('./program-f984ab63.js');
|
|
16
16
|
var p = require('path');
|
|
17
17
|
var fs = require('fs');
|
|
18
|
-
var compiler_host = require('./compiler_host-
|
|
18
|
+
var compiler_host = require('./compiler_host-d642e87e.js');
|
|
19
19
|
var project_tsconfig_paths = require('./project_tsconfig_paths-e9ccccbf.js');
|
|
20
20
|
var nodes = require('./nodes-0e7d45ca.js');
|
|
21
21
|
var imports = require('./imports-4ac08251.js');
|
|
@@ -32,7 +32,7 @@ var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
|
32
32
|
* @description
|
|
33
33
|
* Entry point for all public APIs of the compiler-cli package.
|
|
34
34
|
*/
|
|
35
|
-
new checker.Version('19.0.0-rc.
|
|
35
|
+
new checker.Version('19.0.0-rc.3');
|
|
36
36
|
|
|
37
37
|
function createProgram({ rootNames, options, host, oldProgram, }) {
|
|
38
38
|
return new program.NgtscProgram(rootNames, options, host, oldProgram);
|
|
@@ -48,6 +48,20 @@ var LogLevel;
|
|
|
48
48
|
|
|
49
49
|
checker.setFileSystem(new checker.NodeJSFileSystem());
|
|
50
50
|
|
|
51
|
+
/** Checks whether a node is referring to a specific import specifier. */
|
|
52
|
+
function isReferenceToImport(typeChecker, node, importSpecifier) {
|
|
53
|
+
// If this function is called on an identifier (should be most cases), we can quickly rule out
|
|
54
|
+
// non-matches by comparing the identifier's string and the local name of the import specifier
|
|
55
|
+
// which saves us some calls to the type checker.
|
|
56
|
+
if (ts__default["default"].isIdentifier(node) && node.text !== importSpecifier.name.text) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
const nodeSymbol = typeChecker.getTypeAtLocation(node).getSymbol();
|
|
60
|
+
const importSymbol = typeChecker.getTypeAtLocation(importSpecifier).getSymbol();
|
|
61
|
+
return (!!(nodeSymbol?.declarations?.[0] && importSymbol?.declarations?.[0]) &&
|
|
62
|
+
nodeSymbol.declarations[0] === importSymbol.declarations[0]);
|
|
63
|
+
}
|
|
64
|
+
|
|
51
65
|
/*!
|
|
52
66
|
* @license
|
|
53
67
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -73,6 +87,9 @@ class UniqueItemTracker {
|
|
|
73
87
|
getEntries() {
|
|
74
88
|
return this._nodes.entries();
|
|
75
89
|
}
|
|
90
|
+
isEmpty() {
|
|
91
|
+
return this._nodes.size === 0;
|
|
92
|
+
}
|
|
76
93
|
}
|
|
77
94
|
/** Resolves references to nodes. */
|
|
78
95
|
class ReferenceResolver {
|
|
@@ -294,19 +311,37 @@ function isClassReferenceInAngularModule(node, className, moduleName, typeChecke
|
|
|
294
311
|
: className.test(closestClass.name.text);
|
|
295
312
|
});
|
|
296
313
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
314
|
+
/**
|
|
315
|
+
* Finds the imports of testing libraries in a file.
|
|
316
|
+
*/
|
|
317
|
+
function getTestingImports(sourceFile) {
|
|
318
|
+
return {
|
|
319
|
+
testBed: imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'TestBed'),
|
|
320
|
+
catalyst: imports.getImportSpecifier(sourceFile, /testing\/catalyst(\/(fake_)?async)?$/, 'setupModule'),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Determines if a node is a call to a testing API.
|
|
325
|
+
* @param typeChecker Type checker to use when resolving references.
|
|
326
|
+
* @param node Node to check.
|
|
327
|
+
* @param testBedImport Import of TestBed within the file.
|
|
328
|
+
* @param catalystImport Import of Catalyst within the file.
|
|
329
|
+
*/
|
|
330
|
+
function isTestCall(typeChecker, node, testBedImport, catalystImport) {
|
|
331
|
+
const isObjectLiteralCall = ts__default["default"].isCallExpression(node) &&
|
|
332
|
+
node.arguments.length > 0 &&
|
|
333
|
+
// `arguments[0]` is the testing module config.
|
|
334
|
+
ts__default["default"].isObjectLiteralExpression(node.arguments[0]);
|
|
335
|
+
const isTestBedCall = isObjectLiteralCall &&
|
|
336
|
+
testBedImport &&
|
|
337
|
+
ts__default["default"].isPropertyAccessExpression(node.expression) &&
|
|
338
|
+
node.expression.name.text === 'configureTestingModule' &&
|
|
339
|
+
isReferenceToImport(typeChecker, node.expression.expression, testBedImport);
|
|
340
|
+
const isCatalystCall = isObjectLiteralCall &&
|
|
341
|
+
catalystImport &&
|
|
342
|
+
ts__default["default"].isIdentifier(node.expression) &&
|
|
343
|
+
isReferenceToImport(typeChecker, node.expression, catalystImport);
|
|
344
|
+
return !!(isTestBedCall || isCatalystCall);
|
|
310
345
|
}
|
|
311
346
|
|
|
312
347
|
/*!
|
|
@@ -322,10 +357,10 @@ function isReferenceToImport(typeChecker, node, importSpecifier) {
|
|
|
322
357
|
* @param program
|
|
323
358
|
* @param printer
|
|
324
359
|
* @param fileImportRemapper Optional function that can be used to remap file-level imports.
|
|
325
|
-
* @param
|
|
360
|
+
* @param declarationImportRemapper Optional function that can be used to remap declaration-level
|
|
326
361
|
* imports.
|
|
327
362
|
*/
|
|
328
|
-
function toStandalone(sourceFiles, program, printer, fileImportRemapper,
|
|
363
|
+
function toStandalone(sourceFiles, program, printer, fileImportRemapper, declarationImportRemapper) {
|
|
329
364
|
const templateTypeChecker = program.compiler.getTemplateTypeChecker();
|
|
330
365
|
const typeChecker = program.getTsProgram().getTypeChecker();
|
|
331
366
|
const modulesToMigrate = new Set();
|
|
@@ -346,7 +381,7 @@ function toStandalone(sourceFiles, program, printer, fileImportRemapper, compone
|
|
|
346
381
|
testObjects.forEach((obj) => testObjectsToMigrate.add(obj));
|
|
347
382
|
}
|
|
348
383
|
for (const declaration of declarations) {
|
|
349
|
-
convertNgModuleDeclarationToStandalone(declaration, declarations, tracker, templateTypeChecker,
|
|
384
|
+
convertNgModuleDeclarationToStandalone(declaration, declarations, tracker, templateTypeChecker, declarationImportRemapper);
|
|
350
385
|
}
|
|
351
386
|
for (const node of modulesToMigrate) {
|
|
352
387
|
migrateNgModuleClass(node, declarations, tracker, typeChecker, templateTypeChecker);
|
|
@@ -408,7 +443,7 @@ function getComponentImportExpressions(decl, allDeclarations, tracker, typeCheck
|
|
|
408
443
|
resolvedDependencies.push(importLocation);
|
|
409
444
|
}
|
|
410
445
|
}
|
|
411
|
-
return potentialImportsToExpressions(resolvedDependencies, decl, tracker, importRemapper);
|
|
446
|
+
return potentialImportsToExpressions(resolvedDependencies, decl.getSourceFile(), tracker, importRemapper);
|
|
412
447
|
}
|
|
413
448
|
/**
|
|
414
449
|
* Converts an array of potential imports to an array of expressions that can be
|
|
@@ -418,19 +453,19 @@ function getComponentImportExpressions(decl, allDeclarations, tracker, typeCheck
|
|
|
418
453
|
* @param tracker
|
|
419
454
|
* @param importRemapper
|
|
420
455
|
*/
|
|
421
|
-
function potentialImportsToExpressions(potentialImports,
|
|
456
|
+
function potentialImportsToExpressions(potentialImports, toFile, tracker, importRemapper) {
|
|
422
457
|
const processedDependencies = importRemapper
|
|
423
|
-
? importRemapper(potentialImports
|
|
458
|
+
? importRemapper(potentialImports)
|
|
424
459
|
: potentialImports;
|
|
425
460
|
return processedDependencies.map((importLocation) => {
|
|
426
461
|
if (importLocation.moduleSpecifier) {
|
|
427
|
-
return tracker.addImport(
|
|
462
|
+
return tracker.addImport(toFile, importLocation.symbolName, importLocation.moduleSpecifier);
|
|
428
463
|
}
|
|
429
464
|
const identifier = ts__default["default"].factory.createIdentifier(importLocation.symbolName);
|
|
430
465
|
if (!importLocation.isForwardReference) {
|
|
431
466
|
return identifier;
|
|
432
467
|
}
|
|
433
|
-
const forwardRefExpression = tracker.addImport(
|
|
468
|
+
const forwardRefExpression = tracker.addImport(toFile, 'forwardRef', '@angular/core');
|
|
434
469
|
const arrowFunction = ts__default["default"].factory.createArrowFunction(undefined, undefined, [], undefined, undefined, identifier);
|
|
435
470
|
return ts__default["default"].factory.createCallExpression(forwardRefExpression, undefined, [arrowFunction]);
|
|
436
471
|
});
|
|
@@ -611,12 +646,12 @@ function isNamedPropertyAssignment(node) {
|
|
|
611
646
|
/**
|
|
612
647
|
* Finds the import from which to bring in a template dependency of a component.
|
|
613
648
|
* @param target Dependency that we're searching for.
|
|
614
|
-
* @param
|
|
649
|
+
* @param inContext Component in which the dependency is used.
|
|
615
650
|
* @param importMode Mode in which to resolve the import target.
|
|
616
651
|
* @param typeChecker
|
|
617
652
|
*/
|
|
618
|
-
function findImportLocation(target,
|
|
619
|
-
const importLocations = typeChecker.getPotentialImportsFor(target,
|
|
653
|
+
function findImportLocation(target, inContext, importMode, typeChecker) {
|
|
654
|
+
const importLocations = typeChecker.getPotentialImportsFor(target, inContext, importMode);
|
|
620
655
|
let firstSameFileImport = null;
|
|
621
656
|
let firstModuleImport = null;
|
|
622
657
|
for (const location of importLocations) {
|
|
@@ -669,25 +704,11 @@ function findNgModuleClassesToMigrate(sourceFile, typeChecker) {
|
|
|
669
704
|
/** Finds all testing object literals that need to be migrated. */
|
|
670
705
|
function findTestObjectsToMigrate(sourceFile, typeChecker) {
|
|
671
706
|
const testObjects = [];
|
|
672
|
-
const
|
|
673
|
-
|
|
674
|
-
if (testBedImport || catalystImport) {
|
|
707
|
+
const { testBed, catalyst } = getTestingImports(sourceFile);
|
|
708
|
+
if (testBed || catalyst) {
|
|
675
709
|
sourceFile.forEachChild(function walk(node) {
|
|
676
|
-
|
|
677
|
-
node.arguments
|
|
678
|
-
// `arguments[0]` is the testing module config.
|
|
679
|
-
ts__default["default"].isObjectLiteralExpression(node.arguments[0]);
|
|
680
|
-
const config = isObjectLiteralCall ? node.arguments[0] : null;
|
|
681
|
-
const isTestBedCall = isObjectLiteralCall &&
|
|
682
|
-
testBedImport &&
|
|
683
|
-
ts__default["default"].isPropertyAccessExpression(node.expression) &&
|
|
684
|
-
node.expression.name.text === 'configureTestingModule' &&
|
|
685
|
-
isReferenceToImport(typeChecker, node.expression.expression, testBedImport);
|
|
686
|
-
const isCatalystCall = isObjectLiteralCall &&
|
|
687
|
-
catalystImport &&
|
|
688
|
-
ts__default["default"].isIdentifier(node.expression) &&
|
|
689
|
-
isReferenceToImport(typeChecker, node.expression, catalystImport);
|
|
690
|
-
if ((isTestBedCall || isCatalystCall) && config) {
|
|
710
|
+
if (isTestCall(typeChecker, node, testBed, catalyst)) {
|
|
711
|
+
const config = node.arguments[0];
|
|
691
712
|
const declarations = findLiteralProperty(config, 'declarations');
|
|
692
713
|
if (declarations &&
|
|
693
714
|
ts__default["default"].isPropertyAssignment(declarations) &&
|
|
@@ -922,7 +943,7 @@ function isStandaloneDeclaration(node, declarationsInMigration, templateTypeChec
|
|
|
922
943
|
* Use of this source code is governed by an MIT-style license that can be
|
|
923
944
|
* found in the LICENSE file at https://angular.dev/license
|
|
924
945
|
*/
|
|
925
|
-
function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles,
|
|
946
|
+
function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles, declarationImportRemapper) {
|
|
926
947
|
const filesToRemove = new Set();
|
|
927
948
|
const tracker = new compiler_host.ChangeTracker(printer, importRemapper);
|
|
928
949
|
const tsProgram = program.getTsProgram();
|
|
@@ -938,10 +959,11 @@ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, pri
|
|
|
938
959
|
const classesToRemove = new Set();
|
|
939
960
|
const barrelExports = new UniqueItemTracker();
|
|
940
961
|
const componentImportArrays = new UniqueItemTracker();
|
|
962
|
+
const testArrays = new UniqueItemTracker();
|
|
941
963
|
const nodesToRemove = new Set();
|
|
942
964
|
sourceFiles.forEach(function walk(node) {
|
|
943
965
|
if (ts__default["default"].isClassDeclaration(node) && canRemoveClass(node, typeChecker)) {
|
|
944
|
-
collectChangeLocations(node, removalLocations, componentImportArrays, templateTypeChecker, referenceResolver, program);
|
|
966
|
+
collectChangeLocations(node, removalLocations, componentImportArrays, testArrays, templateTypeChecker, referenceResolver, program);
|
|
945
967
|
classesToRemove.add(node);
|
|
946
968
|
}
|
|
947
969
|
else if (ts__default["default"].isExportDeclaration(node) &&
|
|
@@ -958,7 +980,8 @@ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, pri
|
|
|
958
980
|
}
|
|
959
981
|
node.forEachChild(walk);
|
|
960
982
|
});
|
|
961
|
-
|
|
983
|
+
replaceInComponentImportsArray(componentImportArrays, classesToRemove, tracker, typeChecker, templateTypeChecker, declarationImportRemapper);
|
|
984
|
+
replaceInTestImportsArray(testArrays, removalLocations, classesToRemove, tracker, typeChecker, templateTypeChecker, declarationImportRemapper);
|
|
962
985
|
// We collect all the places where we need to remove references first before generating the
|
|
963
986
|
// removal instructions since we may have to remove multiple references from one node.
|
|
964
987
|
removeArrayReferences(removalLocations.arrays, tracker);
|
|
@@ -997,12 +1020,14 @@ function pruneNgModules(program, host, basePath, rootFileNames, sourceFiles, pri
|
|
|
997
1020
|
* @param ngModule Module being removed.
|
|
998
1021
|
* @param removalLocations Tracks the different places from which the class should be removed.
|
|
999
1022
|
* @param componentImportArrays Set of `imports` arrays of components that need to be adjusted.
|
|
1023
|
+
* @param testImportArrays Set of `imports` arrays of tests that need to be adjusted.
|
|
1000
1024
|
* @param referenceResolver
|
|
1001
1025
|
* @param program
|
|
1002
1026
|
*/
|
|
1003
|
-
function collectChangeLocations(ngModule, removalLocations, componentImportArrays, templateTypeChecker, referenceResolver, program) {
|
|
1027
|
+
function collectChangeLocations(ngModule, removalLocations, componentImportArrays, testImportArrays, templateTypeChecker, referenceResolver, program) {
|
|
1004
1028
|
const refsByFile = referenceResolver.findReferencesInProject(ngModule.name);
|
|
1005
1029
|
const tsProgram = program.getTsProgram();
|
|
1030
|
+
const typeChecker = tsProgram.getTypeChecker();
|
|
1006
1031
|
const nodes$1 = new Set();
|
|
1007
1032
|
for (const [fileName, refs] of refsByFile) {
|
|
1008
1033
|
const sourceFile = tsProgram.getSourceFile(fileName);
|
|
@@ -1014,20 +1039,31 @@ function collectChangeLocations(ngModule, removalLocations, componentImportArray
|
|
|
1014
1039
|
const closestArray = nodes.closestNode(node, ts__default["default"].isArrayLiteralExpression);
|
|
1015
1040
|
if (closestArray) {
|
|
1016
1041
|
const closestAssignment = nodes.closestNode(closestArray, ts__default["default"].isPropertyAssignment);
|
|
1017
|
-
// If the module was flagged as being removable, but it's still being used in a standalone
|
|
1018
|
-
// component's `imports` array, it means that it was likely changed outside of the migration
|
|
1019
|
-
// and deleting it now will be breaking. Track it separately so it can be handled properly.
|
|
1020
1042
|
if (closestAssignment && isInImportsArray(closestAssignment, closestArray)) {
|
|
1021
|
-
const
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1043
|
+
const closestCall = nodes.closestNode(closestAssignment, ts__default["default"].isCallExpression);
|
|
1044
|
+
if (closestCall) {
|
|
1045
|
+
const closestDecorator = nodes.closestNode(closestCall, ts__default["default"].isDecorator);
|
|
1046
|
+
const closestClass = closestDecorator
|
|
1047
|
+
? nodes.closestNode(closestDecorator, ts__default["default"].isClassDeclaration)
|
|
1048
|
+
: null;
|
|
1049
|
+
const directiveMeta = closestClass
|
|
1050
|
+
? templateTypeChecker.getDirectiveMetadata(closestClass)
|
|
1051
|
+
: null;
|
|
1052
|
+
// If the module was flagged as being removable, but it's still being used in a
|
|
1053
|
+
// standalone component's `imports` array, it means that it was likely changed
|
|
1054
|
+
// outside of the migration and deleting it now will be breaking. Track it
|
|
1055
|
+
// separately so it can be handled properly.
|
|
1056
|
+
if (directiveMeta && directiveMeta.isComponent && directiveMeta.isStandalone) {
|
|
1057
|
+
componentImportArrays.track(closestArray, node);
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
// If the module is removable and used inside a test's `imports`,
|
|
1061
|
+
// we track it separately so it can be replaced with its `exports`.
|
|
1062
|
+
const { testBed, catalyst } = getTestingImports(node.getSourceFile());
|
|
1063
|
+
if (isTestCall(typeChecker, closestCall, testBed, catalyst)) {
|
|
1064
|
+
testImportArrays.track(closestArray, node);
|
|
1065
|
+
continue;
|
|
1066
|
+
}
|
|
1031
1067
|
}
|
|
1032
1068
|
}
|
|
1033
1069
|
removalLocations.arrays.track(closestArray, node);
|
|
@@ -1047,7 +1083,7 @@ function collectChangeLocations(ngModule, removalLocations, componentImportArray
|
|
|
1047
1083
|
}
|
|
1048
1084
|
}
|
|
1049
1085
|
/**
|
|
1050
|
-
* Replaces all the leftover modules in imports arrays with their exports.
|
|
1086
|
+
* Replaces all the leftover modules in component `imports` arrays with their exports.
|
|
1051
1087
|
* @param componentImportArrays All the imports arrays and their nodes that represent NgModules.
|
|
1052
1088
|
* @param classesToRemove Set of classes that were marked for removal.
|
|
1053
1089
|
* @param tracker
|
|
@@ -1055,7 +1091,7 @@ function collectChangeLocations(ngModule, removalLocations, componentImportArray
|
|
|
1055
1091
|
* @param templateTypeChecker
|
|
1056
1092
|
* @param importRemapper
|
|
1057
1093
|
*/
|
|
1058
|
-
function
|
|
1094
|
+
function replaceInComponentImportsArray(componentImportArrays, classesToRemove, tracker, typeChecker, templateTypeChecker, importRemapper) {
|
|
1059
1095
|
for (const [array, toReplace] of componentImportArrays.getEntries()) {
|
|
1060
1096
|
const closestClass = nodes.closestNode(array, ts__default["default"].isClassDeclaration);
|
|
1061
1097
|
if (!closestClass) {
|
|
@@ -1081,21 +1117,65 @@ function replaceInImportsArray(componentImportArrays, classesToRemove, tracker,
|
|
|
1081
1117
|
}
|
|
1082
1118
|
}
|
|
1083
1119
|
}
|
|
1084
|
-
replaceModulesInImportsArray(array,
|
|
1120
|
+
replaceModulesInImportsArray(array, replacements, tracker, templateTypeChecker, importRemapper);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Replaces all the leftover modules in testing `imports` arrays with their exports.
|
|
1125
|
+
* @param testImportArrays All test `imports` arrays and their nodes that represent modules.
|
|
1126
|
+
* @param classesToRemove Classes marked for removal by the migration.
|
|
1127
|
+
* @param tracker
|
|
1128
|
+
* @param typeChecker
|
|
1129
|
+
* @param templateTypeChecker
|
|
1130
|
+
* @param importRemapper
|
|
1131
|
+
*/
|
|
1132
|
+
function replaceInTestImportsArray(testImportArrays, removalLocations, classesToRemove, tracker, typeChecker, templateTypeChecker, importRemapper) {
|
|
1133
|
+
for (const [array, toReplace] of testImportArrays.getEntries()) {
|
|
1134
|
+
const replacements = new UniqueItemTracker();
|
|
1135
|
+
for (const node of toReplace) {
|
|
1136
|
+
const moduleDecl = findClassDeclaration(node, typeChecker);
|
|
1137
|
+
if (moduleDecl) {
|
|
1138
|
+
const moduleMeta = templateTypeChecker.getNgModuleMetadata(moduleDecl);
|
|
1139
|
+
if (moduleMeta) {
|
|
1140
|
+
// Since we don't have access to the template type checker in tests,
|
|
1141
|
+
// we copy over all the `exports` that aren't flagged for removal.
|
|
1142
|
+
const exports = moduleMeta.exports.filter((exp) => !classesToRemove.has(exp.node));
|
|
1143
|
+
if (exports.length > 0) {
|
|
1144
|
+
exports.forEach((exp) => replacements.track(node, exp));
|
|
1145
|
+
}
|
|
1146
|
+
else {
|
|
1147
|
+
removalLocations.arrays.track(array, node);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
else {
|
|
1151
|
+
// It's unlikely not to have module metadata at this point, but just in
|
|
1152
|
+
// case unmark the class for removal to reduce the chance of breakages.
|
|
1153
|
+
classesToRemove.delete(moduleDecl);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
replaceModulesInImportsArray(array, replacements, tracker, templateTypeChecker, importRemapper);
|
|
1085
1158
|
}
|
|
1086
1159
|
}
|
|
1087
1160
|
/**
|
|
1088
|
-
* Replaces any leftover modules in `imports` arrays with
|
|
1089
|
-
* component.
|
|
1161
|
+
* Replaces any leftover modules in an `imports` arrays with a set of specified exports
|
|
1090
1162
|
* @param array Imports array which is being migrated.
|
|
1091
|
-
* @param componentClass Class that the imports array belongs to.
|
|
1092
1163
|
* @param replacements Map of NgModule references to their exports.
|
|
1093
1164
|
* @param tracker
|
|
1094
1165
|
* @param templateTypeChecker
|
|
1095
1166
|
* @param importRemapper
|
|
1096
1167
|
*/
|
|
1097
|
-
function replaceModulesInImportsArray(array,
|
|
1168
|
+
function replaceModulesInImportsArray(array, replacements, tracker, templateTypeChecker, importRemapper) {
|
|
1169
|
+
if (replacements.isEmpty()) {
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1098
1172
|
const newElements = [];
|
|
1173
|
+
const identifiers = new Set();
|
|
1174
|
+
for (const element of array.elements) {
|
|
1175
|
+
if (ts__default["default"].isIdentifier(element)) {
|
|
1176
|
+
identifiers.add(element.text);
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1099
1179
|
for (const element of array.elements) {
|
|
1100
1180
|
const replacementRefs = replacements.get(element);
|
|
1101
1181
|
if (!replacementRefs) {
|
|
@@ -1104,12 +1184,16 @@ function replaceModulesInImportsArray(array, componentClass, replacements, track
|
|
|
1104
1184
|
}
|
|
1105
1185
|
const potentialImports = [];
|
|
1106
1186
|
for (const ref of replacementRefs) {
|
|
1107
|
-
const importLocation = findImportLocation(ref,
|
|
1187
|
+
const importLocation = findImportLocation(ref, array, checker.PotentialImportMode.Normal, templateTypeChecker);
|
|
1108
1188
|
if (importLocation) {
|
|
1109
1189
|
potentialImports.push(importLocation);
|
|
1110
1190
|
}
|
|
1111
1191
|
}
|
|
1112
|
-
|
|
1192
|
+
potentialImportsToExpressions(potentialImports, array.getSourceFile(), tracker, importRemapper).forEach((expr) => {
|
|
1193
|
+
if (!ts__default["default"].isIdentifier(expr) || !identifiers.has(expr.text)) {
|
|
1194
|
+
newElements.push(expr);
|
|
1195
|
+
}
|
|
1196
|
+
});
|
|
1113
1197
|
}
|
|
1114
1198
|
tracker.replaceNode(array, ts__default["default"].factory.updateArrayLiteralExpression(array, newElements));
|
|
1115
1199
|
}
|
|
@@ -1344,7 +1428,7 @@ function isInImportsArray(closestAssignment, closestArray) {
|
|
|
1344
1428
|
* Use of this source code is governed by an MIT-style license that can be
|
|
1345
1429
|
* found in the LICENSE file at https://angular.dev/license
|
|
1346
1430
|
*/
|
|
1347
|
-
function toStandaloneBootstrap(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles,
|
|
1431
|
+
function toStandaloneBootstrap(program, host, basePath, rootFileNames, sourceFiles, printer, importRemapper, referenceLookupExcludedFiles, declarationImportRemapper) {
|
|
1348
1432
|
const tracker = new compiler_host.ChangeTracker(printer, importRemapper);
|
|
1349
1433
|
const typeChecker = program.getTsProgram().getTypeChecker();
|
|
1350
1434
|
const templateTypeChecker = program.compiler.getTemplateTypeChecker();
|
|
@@ -1379,7 +1463,7 @@ function toStandaloneBootstrap(program, host, basePath, rootFileNames, sourceFil
|
|
|
1379
1463
|
// The previous migrations explicitly skip over bootstrapped
|
|
1380
1464
|
// declarations so we have to migrate them now.
|
|
1381
1465
|
for (const declaration of allDeclarations) {
|
|
1382
|
-
convertNgModuleDeclarationToStandalone(declaration, allDeclarations, tracker, templateTypeChecker,
|
|
1466
|
+
convertNgModuleDeclarationToStandalone(declaration, allDeclarations, tracker, templateTypeChecker, declarationImportRemapper);
|
|
1383
1467
|
}
|
|
1384
1468
|
migrateTestDeclarations(testObjects, allDeclarations, tracker, templateTypeChecker, typeChecker);
|
|
1385
1469
|
return tracker.recordChanges();
|
package/testing/index.d.ts
CHANGED