@angular/core 21.0.0-next.0 → 21.0.0-next.10
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/_attribute-chunk.mjs +12 -0
- package/fesm2022/_attribute-chunk.mjs.map +1 -0
- package/fesm2022/_debug_node-chunk.mjs +18469 -0
- package/fesm2022/_debug_node-chunk.mjs.map +1 -0
- package/fesm2022/_effect-chunk.mjs +423 -0
- package/fesm2022/_effect-chunk.mjs.map +1 -0
- package/fesm2022/_effect-chunk2.mjs +2951 -0
- package/fesm2022/_effect-chunk2.mjs.map +1 -0
- package/fesm2022/_not_found-chunk.mjs +39 -0
- package/fesm2022/_not_found-chunk.mjs.map +1 -0
- package/fesm2022/_resource-chunk.mjs +378 -0
- package/fesm2022/_resource-chunk.mjs.map +1 -0
- package/fesm2022/_untracked-chunk.mjs +96 -0
- package/fesm2022/_untracked-chunk.mjs.map +1 -0
- package/fesm2022/_weak_ref-chunk.mjs +10 -0
- package/fesm2022/_weak_ref-chunk.mjs.map +1 -0
- package/fesm2022/core.mjs +2499 -4185
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives-di.mjs +23 -0
- package/fesm2022/primitives-di.mjs.map +1 -0
- package/fesm2022/primitives-event-dispatch.mjs +788 -0
- package/fesm2022/primitives-event-dispatch.mjs.map +1 -0
- package/fesm2022/primitives-signals.mjs +187 -0
- package/fesm2022/primitives-signals.mjs.map +1 -0
- package/fesm2022/rxjs-interop.mjs +210 -308
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +2309 -3170
- package/fesm2022/testing.mjs.map +1 -1
- package/package.json +18 -12
- package/resources/best-practices.md +56 -0
- package/schematics/bundles/add-bootstrap-context-to-server-main.cjs +117 -0
- package/schematics/bundles/application-config-core.cjs +84 -0
- package/schematics/bundles/{apply_import_manager-DR9xXCle.cjs → apply_import_manager-1Zs_gpB6.cjs} +4 -5
- package/schematics/bundles/bootstrap-options-migration.cjs +598 -0
- package/schematics/bundles/cleanup-unused-imports.cjs +9 -13
- package/schematics/bundles/common-to-standalone-migration.cjs +381 -0
- package/schematics/bundles/{compiler_host-BXBP7CE2.cjs → compiler_host-DBwYMlTo.cjs} +10 -11
- package/schematics/bundles/control-flow-migration.cjs +122 -119
- package/schematics/bundles/{imports-CIX-JgAN.cjs → imports-DP72APSx.cjs} +6 -1
- package/schematics/bundles/{index-CfTQUOiz.cjs → index-B7I9sIUx.cjs} +36 -39
- package/schematics/bundles/inject-migration.cjs +148 -70
- package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
- package/schematics/bundles/{migrate_ts_type_references-6NtAj-Wk.cjs → migrate_ts_type_references-UGIUl7En.cjs} +500 -24
- package/schematics/bundles/ng_component_template-Dsuq1Lw7.cjs +185 -0
- package/schematics/bundles/{ng_decorators-B5HCqr20.cjs → ng_decorators-DSFlWYQY.cjs} +2 -2
- package/schematics/bundles/ngclass-to-class-migration.cjs +542 -0
- package/schematics/bundles/ngstyle-to-style-migration.cjs +487 -0
- package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
- package/schematics/bundles/output-migration.cjs +16 -19
- package/schematics/bundles/parse_html-8VLCL37B.cjs +132 -0
- package/schematics/bundles/{project_paths-DcaODbky.cjs → project_paths-DvD50ouC.cjs} +14 -247
- package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +90 -0
- package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
- package/schematics/bundles/route-lazy-loading.cjs +54 -26
- package/schematics/bundles/router-current-navigation.cjs +7 -18
- package/schematics/bundles/router-last-successful-navigation.cjs +7 -18
- package/schematics/bundles/router-testing-module-migration.cjs +502 -0
- package/schematics/bundles/self-closing-tags-migration.cjs +17 -216
- package/schematics/bundles/signal-input-migration.cjs +93 -29
- package/schematics/bundles/signal-queries-migration.cjs +22 -25
- package/schematics/bundles/signals.cjs +10 -13
- package/schematics/bundles/standalone-migration.cjs +135 -102
- package/schematics/bundles/{symbol-VPWguRxr.cjs → symbol-BObKoqes.cjs} +3 -2
- package/schematics/collection.json +23 -0
- package/schematics/migrations/common-to-standalone-migration/schema.json +14 -0
- package/schematics/migrations/ngclass-to-class-migration/schema.json +20 -0
- package/schematics/migrations/ngstyle-to-style-migration/schema.json +20 -0
- package/schematics/migrations/router-testing-module-migration/schema.json +14 -0
- package/schematics/migrations.json +16 -2
- package/{api.d.d.ts → types/_api-chunk.d.ts} +9 -6
- package/{chrome_dev_tools_performance.d.d.ts → types/_chrome_dev_tools_performance-chunk.d.ts} +26 -31
- package/{discovery.d.d.ts → types/_discovery-chunk.d.ts} +135 -98
- package/{signal.d.d.ts → types/_effect-chunk.d.ts} +14 -5
- package/{event_dispatcher.d.d.ts → types/_event_dispatcher-chunk.d.ts} +2 -2
- package/{graph.d.d.ts → types/_formatter-chunk.d.ts} +40 -7
- package/{weak_ref.d.d.ts → types/_weak_ref-chunk.d.ts} +2 -2
- package/{index.d.ts → types/core.d.ts} +233 -305
- package/{primitives/di/index.d.ts → types/primitives-di.d.ts} +2 -2
- package/{primitives/event-dispatch/index.d.ts → types/primitives-event-dispatch.d.ts} +4 -4
- package/{primitives/signals/index.d.ts → types/primitives-signals.d.ts} +7 -8
- package/{rxjs-interop/index.d.ts → types/rxjs-interop.d.ts} +8 -6
- package/{testing/index.d.ts → types/testing.d.ts} +7 -7
- package/fesm2022/attribute.mjs +0 -24
- package/fesm2022/attribute.mjs.map +0 -1
- package/fesm2022/debug_node.mjs +0 -31833
- package/fesm2022/debug_node.mjs.map +0 -1
- package/fesm2022/not_found.mjs +0 -56
- package/fesm2022/not_found.mjs.map +0 -1
- package/fesm2022/primitives/di.mjs +0 -23
- package/fesm2022/primitives/di.mjs.map +0 -1
- package/fesm2022/primitives/event-dispatch.mjs +0 -1622
- package/fesm2022/primitives/event-dispatch.mjs.map +0 -1
- package/fesm2022/primitives/signals.mjs +0 -89
- package/fesm2022/primitives/signals.mjs.map +0 -1
- package/fesm2022/resource.mjs +0 -633
- package/fesm2022/resource.mjs.map +0 -1
- package/fesm2022/root_effect_scheduler.mjs +0 -4007
- package/fesm2022/root_effect_scheduler.mjs.map +0 -1
- package/fesm2022/signal.mjs +0 -560
- package/fesm2022/signal.mjs.map +0 -1
- package/fesm2022/untracked.mjs +0 -117
- package/fesm2022/untracked.mjs.map +0 -1
- package/fesm2022/weak_ref.mjs +0 -12
- package/fesm2022/weak_ref.mjs.map +0 -1
- package/schematics/bundles/index-esqfDjNB.cjs +0 -22074
- package/schematics/bundles/project_tsconfig_paths-CS-eSeHC.cjs +0 -51062
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @license Angular v21.0.0-next.10
|
|
4
|
+
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
require('@angular-devkit/core');
|
|
10
|
+
require('node:path/posix');
|
|
11
|
+
var project_paths = require('./project_paths-DvD50ouC.cjs');
|
|
12
|
+
require('@angular/compiler-cli');
|
|
13
|
+
var migrations = require('@angular/compiler-cli/private/migrations');
|
|
14
|
+
var ts = require('typescript');
|
|
15
|
+
require('node:path');
|
|
16
|
+
var apply_import_manager = require('./apply_import_manager-1Zs_gpB6.cjs');
|
|
17
|
+
var property_name = require('./property_name-BBwFuqMe.cjs');
|
|
18
|
+
var imports = require('./imports-DP72APSx.cjs');
|
|
19
|
+
var symbol = require('./symbol-BObKoqes.cjs');
|
|
20
|
+
require('@angular-devkit/schematics');
|
|
21
|
+
require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
22
|
+
|
|
23
|
+
const CORE_PACKAGE = '@angular/core';
|
|
24
|
+
const PROVIDE_ZONE_CHANGE_DETECTION = 'provideZoneChangeDetection';
|
|
25
|
+
const ZONE_CD_PROVIDER = `${PROVIDE_ZONE_CHANGE_DETECTION}()`;
|
|
26
|
+
const SAFE_TO_REMOVE_OPTIONS = [
|
|
27
|
+
'ignoreChangesOutsideZone',
|
|
28
|
+
'ngZoneRunCoalescing',
|
|
29
|
+
'ngZoneEventCoalescing',
|
|
30
|
+
];
|
|
31
|
+
const BOOTSTRAP_OPTIONS = ['ngZone', ...SAFE_TO_REMOVE_OPTIONS];
|
|
32
|
+
class BootstrapOptionsMigration extends project_paths.TsurgeFunnelMigration {
|
|
33
|
+
async analyze(info) {
|
|
34
|
+
let replacements = [];
|
|
35
|
+
const importManager = new migrations.ImportManager();
|
|
36
|
+
for (const sourceFile of info.sourceFiles) {
|
|
37
|
+
// We need to migration either
|
|
38
|
+
// * `bootstrapApplication(App)
|
|
39
|
+
// * `platformBrowser().bootstrapModule(AppModule)`
|
|
40
|
+
// * `platformBrowserDynamic().bootstrapModule(AppModule)`
|
|
41
|
+
// * `TestBed.initTestEnvironment([AppModule], platformBrowserTesting())`
|
|
42
|
+
// * `getTestBed.initTestEnvironment([AppModule], platformBrowserTesting())`
|
|
43
|
+
const specifiers = getSpecifiers(sourceFile);
|
|
44
|
+
// If none of the imports related to bootstraping are present, we can skip the file.
|
|
45
|
+
if (specifiers === null)
|
|
46
|
+
continue;
|
|
47
|
+
const { bootstrapAppSpecifier, testBedSpecifier, createApplicationSpecifier, getTestBedSpecifier, } = specifiers;
|
|
48
|
+
const typeChecker = info.program.getTypeChecker();
|
|
49
|
+
const isCreateApplicationNode = (node) => {
|
|
50
|
+
return (ts.isCallExpression(node) &&
|
|
51
|
+
createApplicationSpecifier !== null &&
|
|
52
|
+
symbol.isReferenceToImport(typeChecker, node.expression, createApplicationSpecifier));
|
|
53
|
+
};
|
|
54
|
+
const isBootstrapAppNode = (node) => {
|
|
55
|
+
return (ts.isCallExpression(node) &&
|
|
56
|
+
bootstrapAppSpecifier !== null &&
|
|
57
|
+
symbol.isReferenceToImport(typeChecker, node.expression, bootstrapAppSpecifier));
|
|
58
|
+
};
|
|
59
|
+
const isBootstrapModuleNode = (node) => {
|
|
60
|
+
return (ts.isCallExpression(node) &&
|
|
61
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
62
|
+
node.expression.name.text === 'bootstrapModule' &&
|
|
63
|
+
node.arguments.length > 0);
|
|
64
|
+
};
|
|
65
|
+
const isTestBedInitEnvironmentNode = (node) => {
|
|
66
|
+
return (ts.isCallExpression(node) &&
|
|
67
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
68
|
+
node.expression.name.text === 'initTestEnvironment' &&
|
|
69
|
+
(symbol.isReferenceToImport(typeChecker, node.expression.expression, testBedSpecifier) ||
|
|
70
|
+
symbol.isReferenceToImport(typeChecker, node.expression.expression, getTestBedSpecifier)));
|
|
71
|
+
};
|
|
72
|
+
const reflector = new migrations.TypeScriptReflectionHost(typeChecker);
|
|
73
|
+
const evaluator = new migrations.PartialEvaluator(reflector, typeChecker, null);
|
|
74
|
+
const walk = (node) => {
|
|
75
|
+
if (isBootstrapAppNode(node)) {
|
|
76
|
+
this.analyzeBootstrapApplication(node, sourceFile, info, typeChecker, importManager, replacements);
|
|
77
|
+
}
|
|
78
|
+
else if (isCreateApplicationNode(node)) {
|
|
79
|
+
this.analyzeCreateApplication(node, sourceFile, info, typeChecker, importManager, replacements);
|
|
80
|
+
}
|
|
81
|
+
else if (isBootstrapModuleNode(node)) {
|
|
82
|
+
this.analyzeBootstrapModule(node, sourceFile, reflector, evaluator, info, typeChecker, importManager, replacements);
|
|
83
|
+
}
|
|
84
|
+
else if (isTestBedInitEnvironmentNode(node)) {
|
|
85
|
+
this.analyzeTestBedInitEnvironment(node, sourceFile, info, typeChecker, importManager, replacements);
|
|
86
|
+
}
|
|
87
|
+
node.forEachChild(walk);
|
|
88
|
+
};
|
|
89
|
+
sourceFile.forEachChild(walk);
|
|
90
|
+
}
|
|
91
|
+
apply_import_manager.applyImportManagerChanges(importManager, replacements, info.sourceFiles, info);
|
|
92
|
+
return project_paths.confirmAsSerializable({ replacements });
|
|
93
|
+
}
|
|
94
|
+
async combine(unitA, unitB) {
|
|
95
|
+
const combined = [...unitA.replacements, ...unitB.replacements];
|
|
96
|
+
return project_paths.confirmAsSerializable({ replacements: combined });
|
|
97
|
+
}
|
|
98
|
+
async globalMeta(data) {
|
|
99
|
+
return project_paths.confirmAsSerializable(data);
|
|
100
|
+
}
|
|
101
|
+
async stats(data) {
|
|
102
|
+
return project_paths.confirmAsSerializable({});
|
|
103
|
+
}
|
|
104
|
+
async migrate(data) {
|
|
105
|
+
return { replacements: data.replacements };
|
|
106
|
+
}
|
|
107
|
+
analyzeBootstrapApplication(node, sourceFile, info, typeChecker, importManager, replacements) {
|
|
108
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(node, typeChecker);
|
|
109
|
+
if (hasExistingChangeDetectionProvider)
|
|
110
|
+
return;
|
|
111
|
+
const providerFn = 'provideZoneChangeDetection()';
|
|
112
|
+
const optionsNode = node.arguments[1];
|
|
113
|
+
const currentProjectFile = project_paths.projectFile(sourceFile, info);
|
|
114
|
+
if (optionsNode) {
|
|
115
|
+
let optionProjectFile = currentProjectFile;
|
|
116
|
+
let optionLiteral;
|
|
117
|
+
if (ts.isObjectLiteralExpression(optionsNode)) {
|
|
118
|
+
optionLiteral = optionsNode;
|
|
119
|
+
addProvidersToBootstrapOption(optionProjectFile, optionLiteral, providerFn, replacements);
|
|
120
|
+
}
|
|
121
|
+
else if (ts.isIdentifier(optionsNode)) {
|
|
122
|
+
// This case handled both `bootstrapApplication(App, appConfig)` and the server () => bootstrapApplication(App, appConfig)
|
|
123
|
+
// where appConfig is the result of a `mergeApplicationConfig` call.
|
|
124
|
+
// This is tricky case to handle, in G3 we're might not be able to resolve the identifier's value
|
|
125
|
+
// Our best alternative is to assume there is not CD providers set and add the ZoneChangeDetection provider
|
|
126
|
+
// In the cases where it is, we'll just override the zone provider we just set by re-used inthe appConfig providers
|
|
127
|
+
// TODO: Should we insert a TODO to clean this up ?
|
|
128
|
+
const text = `{...${optionsNode.getText()}, providers: [${providerFn}, ...${optionsNode.getText()}.providers]}`;
|
|
129
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({
|
|
130
|
+
position: optionsNode.getStart(),
|
|
131
|
+
end: optionsNode.getEnd(),
|
|
132
|
+
toInsert: text,
|
|
133
|
+
})));
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
throw new Error('unsupported optionsNode: ' + optionsNode.getText());
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
// No options object, add it.
|
|
141
|
+
const text = `, {providers: [${providerFn}]}`;
|
|
142
|
+
const component = node.arguments[0];
|
|
143
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({ position: component.getEnd(), end: component.getEnd(), toInsert: text })));
|
|
144
|
+
}
|
|
145
|
+
importManager.addImport({
|
|
146
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
147
|
+
exportSymbolName: 'provideZoneChangeDetection',
|
|
148
|
+
requestedFile: sourceFile,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
analyzeCreateApplication(node, sourceFile, info, typeChecker, importManager, replacements) {
|
|
152
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(node, typeChecker);
|
|
153
|
+
if (hasExistingChangeDetectionProvider)
|
|
154
|
+
return;
|
|
155
|
+
const providerFn = 'provideZoneChangeDetection()';
|
|
156
|
+
const optionsNode = node.arguments[0];
|
|
157
|
+
const currentProjectFile = project_paths.projectFile(sourceFile, info);
|
|
158
|
+
if (optionsNode) {
|
|
159
|
+
let optionProjectFile = currentProjectFile;
|
|
160
|
+
let optionLiteral;
|
|
161
|
+
if (ts.isObjectLiteralExpression(optionsNode)) {
|
|
162
|
+
optionLiteral = optionsNode;
|
|
163
|
+
addProvidersToBootstrapOption(optionProjectFile, optionLiteral, providerFn, replacements);
|
|
164
|
+
}
|
|
165
|
+
else if (ts.isIdentifier(optionsNode) ||
|
|
166
|
+
ts.isCallExpression(optionsNode) ||
|
|
167
|
+
ts.isPropertyAccessExpression(optionsNode)) {
|
|
168
|
+
// This is tricky case to handle, in G3 we're might not be able to resolve the identifier's value
|
|
169
|
+
// Our best alternative is to assume there is no CD providers set and add the ZoneChangeDetection provider
|
|
170
|
+
// In the cases where it is, we'll just override the zone provider we just set by re-used inthe appConfig providers
|
|
171
|
+
// TODO: Should we insert a TODO to clean this up ?
|
|
172
|
+
const text = `{...${optionsNode.getText()}, providers: [${providerFn}, ...${optionsNode.getText()}.providers]}`;
|
|
173
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({
|
|
174
|
+
position: optionsNode.getStart(),
|
|
175
|
+
end: optionsNode.getEnd(),
|
|
176
|
+
toInsert: text,
|
|
177
|
+
})));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
throw new Error('unsupported optionsNode: ' + optionsNode.getText());
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
// No options object, add it.
|
|
185
|
+
const text = `{providers: [${providerFn}]}`;
|
|
186
|
+
replacements.push(new project_paths.Replacement(currentProjectFile, new project_paths.TextUpdate({
|
|
187
|
+
position: node.expression.getEnd() + 1,
|
|
188
|
+
end: node.expression.getEnd() + 1,
|
|
189
|
+
toInsert: text,
|
|
190
|
+
})));
|
|
191
|
+
}
|
|
192
|
+
importManager.addImport({
|
|
193
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
194
|
+
exportSymbolName: 'provideZoneChangeDetection',
|
|
195
|
+
requestedFile: sourceFile,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
analyzeBootstrapModule(node, sourceFile, reflector, evaluator, info, typeChecker, importManager, replacements) {
|
|
199
|
+
const moduleIdentifier = node.arguments[0];
|
|
200
|
+
const moduleType = evaluator.evaluate(moduleIdentifier);
|
|
201
|
+
if (!(moduleType instanceof migrations.Reference) || !ts.isClassDeclaration(moduleType.node)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const moduleClass = moduleType.node;
|
|
205
|
+
const ngModule = findNgModule(moduleClass, reflector);
|
|
206
|
+
if (!ngModule) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const optionsNode = node.arguments[1];
|
|
210
|
+
const file = project_paths.projectFile(sourceFile, info);
|
|
211
|
+
replacements.push(new project_paths.Replacement(file, new project_paths.TextUpdate({
|
|
212
|
+
position: moduleIdentifier.getEnd(),
|
|
213
|
+
end: node.getEnd() - 1,
|
|
214
|
+
toInsert: '',
|
|
215
|
+
})));
|
|
216
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(ngModule, typeChecker);
|
|
217
|
+
if (hasExistingChangeDetectionProvider) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// Let's try to understand the bootstrap options.
|
|
221
|
+
let options = optionsNode ? evaluator.evaluate(optionsNode) : null;
|
|
222
|
+
let extraOptions = new Map();
|
|
223
|
+
let zoneCdProvider = ZONE_CD_PROVIDER;
|
|
224
|
+
let zoneInstanceProvider = null;
|
|
225
|
+
if (Array.isArray(options)) {
|
|
226
|
+
const mergedOptions = options.reduce((acc, item) => {
|
|
227
|
+
if (item instanceof Map) {
|
|
228
|
+
for (const [k, v] of item) {
|
|
229
|
+
acc.set(k, v);
|
|
230
|
+
if (!SAFE_TO_REMOVE_OPTIONS.includes(k)) {
|
|
231
|
+
extraOptions.set(k, v);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return acc;
|
|
236
|
+
}, new Map());
|
|
237
|
+
options = mergedOptions;
|
|
238
|
+
}
|
|
239
|
+
if (options instanceof Map) {
|
|
240
|
+
[...options.entries()].forEach(([k, v]) => {
|
|
241
|
+
if (!BOOTSTRAP_OPTIONS.includes(k) && typeof v !== 'string') {
|
|
242
|
+
extraOptions.set(k, v);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
if (options.has('ngZoneRunCoalescing') || options.has('ngZoneEventCoalescing')) {
|
|
246
|
+
const config = [];
|
|
247
|
+
if (options.get('ngZoneRunCoalescing')) {
|
|
248
|
+
config.push('runCoalescing: true');
|
|
249
|
+
}
|
|
250
|
+
if (options.get('ngZoneEventCoalescing')) {
|
|
251
|
+
config.push('eventCoalescing: true');
|
|
252
|
+
}
|
|
253
|
+
zoneCdProvider = `${PROVIDE_ZONE_CHANGE_DETECTION}(${config.length > 0 ? `{ ${config.join(', ')} }` : ''})`;
|
|
254
|
+
}
|
|
255
|
+
const ngZoneOption = options.get('ngZone');
|
|
256
|
+
if (ngZoneOption instanceof migrations.Reference) {
|
|
257
|
+
const clazz = ngZoneOption.node;
|
|
258
|
+
if (ts.isClassDeclaration(clazz) && clazz.name) {
|
|
259
|
+
zoneInstanceProvider = `{provide: NgZone, useClass: ${clazz.name.text}}`;
|
|
260
|
+
removePropertiesFromLiteral(file, optionsNode, ['ngZone'], replacements);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
else if (typeof ngZoneOption === 'string') {
|
|
264
|
+
if (ngZoneOption === 'noop') {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
else if (ngZoneOption && typeof ngZoneOption !== 'string') {
|
|
269
|
+
// This is a case where we're not able to migrate automatically
|
|
270
|
+
// The migration fails gracefully, keeps the ngZone option and adds a TODO.
|
|
271
|
+
let ngZoneValue;
|
|
272
|
+
optionsNode.properties.forEach((p) => {
|
|
273
|
+
if (ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === 'ngZone') {
|
|
274
|
+
ngZoneValue = p.initializer.getText();
|
|
275
|
+
}
|
|
276
|
+
else if (ts.isShorthandPropertyAssignment(p) && p.name.text === 'ngZone') {
|
|
277
|
+
ngZoneValue = p.name.text;
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
if (ngZoneValue) {
|
|
281
|
+
// We re-add the ngZone option
|
|
282
|
+
extraOptions.set('ngZone', ngZoneValue);
|
|
283
|
+
}
|
|
284
|
+
replacements.push(new project_paths.Replacement(project_paths.projectFile(sourceFile, info), new project_paths.TextUpdate({
|
|
285
|
+
position: node.getStart() - 1,
|
|
286
|
+
end: node.getStart() - 1,
|
|
287
|
+
toInsert: '// TODO: BootstrapOptions are deprecated & ignored. Configure NgZone in the providers array of the application module instead.',
|
|
288
|
+
})));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
const providers = [zoneCdProvider];
|
|
292
|
+
if (zoneInstanceProvider) {
|
|
293
|
+
providers.push(zoneInstanceProvider);
|
|
294
|
+
}
|
|
295
|
+
importManager.addImport({
|
|
296
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
297
|
+
exportSymbolName: PROVIDE_ZONE_CHANGE_DETECTION,
|
|
298
|
+
requestedFile: sourceFile,
|
|
299
|
+
});
|
|
300
|
+
// if we only use the key, we use the a shorthand asignment
|
|
301
|
+
const extraOptionsStr = [...extraOptions.entries()]
|
|
302
|
+
.map(([k, v]) => (k != v ? `${k}: ${v},` : `${k},`))
|
|
303
|
+
.join(', ');
|
|
304
|
+
replacements.push(new project_paths.Replacement(file, new project_paths.TextUpdate({
|
|
305
|
+
position: moduleIdentifier.end,
|
|
306
|
+
end: moduleIdentifier.end,
|
|
307
|
+
toInsert: `, { applicationProviders: [${providers.join(', ')}], ${extraOptionsStr}}`,
|
|
308
|
+
})));
|
|
309
|
+
}
|
|
310
|
+
analyzeTestBedInitEnvironment(callExpr, sourceFile, info, typeChecker, importManager, replacements) {
|
|
311
|
+
const hasExistingChangeDetectionProvider = hasChangeDetectionProvider(callExpr, typeChecker);
|
|
312
|
+
if (hasExistingChangeDetectionProvider)
|
|
313
|
+
return;
|
|
314
|
+
const ngModules = callExpr.arguments[0];
|
|
315
|
+
const moduleProjectFile = project_paths.projectFile(sourceFile, info);
|
|
316
|
+
importManager.addImport({
|
|
317
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
318
|
+
exportSymbolName: PROVIDE_ZONE_CHANGE_DETECTION,
|
|
319
|
+
requestedFile: sourceFile,
|
|
320
|
+
});
|
|
321
|
+
let tmpNode = callExpr;
|
|
322
|
+
let insertPosition = 0;
|
|
323
|
+
while (tmpNode.parent.kind !== ts.SyntaxKind.SourceFile) {
|
|
324
|
+
insertPosition = tmpNode.parent.getStart(sourceFile, true) - 1;
|
|
325
|
+
tmpNode = tmpNode.parent;
|
|
326
|
+
}
|
|
327
|
+
importManager.addImport({
|
|
328
|
+
exportModuleSpecifier: CORE_PACKAGE,
|
|
329
|
+
exportSymbolName: 'NgModule',
|
|
330
|
+
requestedFile: sourceFile,
|
|
331
|
+
});
|
|
332
|
+
addZoneCDModule(ZONE_CD_PROVIDER, moduleProjectFile, insertPosition, replacements);
|
|
333
|
+
insertZoneCDModule(ngModules, moduleProjectFile, replacements, 'ZoneChangeDetectionModule');
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function addZoneCDModule(providersText, projectFile, location, replacements) {
|
|
337
|
+
const newModuleText = `\n@NgModule({ providers: [ ${providersText} ] })
|
|
338
|
+
export class ZoneChangeDetectionModule {}\n\n`;
|
|
339
|
+
if (replacementsHaveZoneCdModule(projectFile.rootRelativePath, replacements, newModuleText)) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
343
|
+
position: location,
|
|
344
|
+
end: location,
|
|
345
|
+
toInsert: newModuleText,
|
|
346
|
+
})));
|
|
347
|
+
}
|
|
348
|
+
function insertZoneCDModule(node, projectFile, replacements, importedModule) {
|
|
349
|
+
if (ts.isArrayLiteralExpression(node)) {
|
|
350
|
+
const literal = node;
|
|
351
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
352
|
+
position: literal.elements[0]?.getStart() ?? literal.getEnd() - 1,
|
|
353
|
+
end: literal.elements[0]?.getStart() ?? literal.getEnd() - 1,
|
|
354
|
+
toInsert: importedModule + ',',
|
|
355
|
+
})));
|
|
356
|
+
}
|
|
357
|
+
else if (ts.isIdentifier(node)) {
|
|
358
|
+
// This should be a good enough heuristic to determine if the identifier is not array
|
|
359
|
+
let isArray = !node.text.endsWith('Module');
|
|
360
|
+
// Because if it's an array, we need to spread it
|
|
361
|
+
const newImports = `[${importedModule}, ${isArray ? '...' : ''}${node.text}]`;
|
|
362
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
363
|
+
position: node.getStart(),
|
|
364
|
+
end: node.getEnd(),
|
|
365
|
+
toInsert: newImports,
|
|
366
|
+
})));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
throw new Error('unsupported importsNode: ' + node.getText());
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function addProvidersToBootstrapOption(projectFile, optionsNode, providersText, replacements) {
|
|
373
|
+
const providersProp = property_name.findLiteralProperty(optionsNode, 'providers');
|
|
374
|
+
if (providersProp && ts.isPropertyAssignment(providersProp)) {
|
|
375
|
+
// Can be bootstrap(App, {providers: [...]}), bootstrap(App, {providers}), bootstrap(App, {...appConfig, providers}) etc.
|
|
376
|
+
if (ts.isArrayLiteralExpression(providersProp.initializer)) {
|
|
377
|
+
const initializer = providersProp.initializer;
|
|
378
|
+
const text = `${providersText},`;
|
|
379
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
380
|
+
position: initializer.elements[0]?.getStart() ?? initializer.getEnd() - 1,
|
|
381
|
+
end: initializer.elements[0]?.getStart() ?? initializer.getEnd() - 1,
|
|
382
|
+
toInsert: text,
|
|
383
|
+
})));
|
|
384
|
+
}
|
|
385
|
+
else if (ts.isIdentifier(providersProp.initializer)) {
|
|
386
|
+
const newProviders = `[${providersText}, ...${providersProp.initializer.text}]`;
|
|
387
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
388
|
+
position: providersProp.initializer.getStart(),
|
|
389
|
+
end: providersProp.initializer.getEnd(),
|
|
390
|
+
toInsert: newProviders,
|
|
391
|
+
})));
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
const newProviders = `[${providersText}, ...`;
|
|
395
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
396
|
+
position: providersProp.initializer.getStart(),
|
|
397
|
+
end: providersProp.initializer.getStart(),
|
|
398
|
+
toInsert: newProviders,
|
|
399
|
+
})));
|
|
400
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
401
|
+
position: providersProp.initializer.getEnd(),
|
|
402
|
+
end: providersProp.initializer.getEnd(),
|
|
403
|
+
toInsert: ']',
|
|
404
|
+
})));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
else if (providersProp && ts.isShorthandPropertyAssignment(providersProp)) {
|
|
408
|
+
const newProviders = `providers: [${providersText}, ...${providersProp.name.text}]`;
|
|
409
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
410
|
+
position: providersProp.getStart(),
|
|
411
|
+
end: providersProp.getEnd(),
|
|
412
|
+
toInsert: newProviders,
|
|
413
|
+
})));
|
|
414
|
+
}
|
|
415
|
+
else if (optionsNode.properties.length === 1 &&
|
|
416
|
+
ts.isSpreadAssignment(optionsNode.properties[0])) {
|
|
417
|
+
const spread = optionsNode.properties[0];
|
|
418
|
+
const newProviders = `, providers: [${providersText}, ...${spread.expression.getText()}.providers]`;
|
|
419
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
420
|
+
position: spread.getEnd(),
|
|
421
|
+
end: spread.getEnd(),
|
|
422
|
+
toInsert: newProviders,
|
|
423
|
+
})));
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
const text = `providers: [${providersText}]`;
|
|
427
|
+
let toInsert;
|
|
428
|
+
let position;
|
|
429
|
+
if (optionsNode.properties.length > 0) {
|
|
430
|
+
const lastProperty = optionsNode.properties[optionsNode.properties.length - 1];
|
|
431
|
+
toInsert = `,\n ${text}`;
|
|
432
|
+
position = lastProperty.getEnd();
|
|
433
|
+
}
|
|
434
|
+
else {
|
|
435
|
+
toInsert = `\n ${text}\n`;
|
|
436
|
+
position = optionsNode.getStart() + 1;
|
|
437
|
+
}
|
|
438
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({
|
|
439
|
+
position,
|
|
440
|
+
end: position,
|
|
441
|
+
toInsert,
|
|
442
|
+
})));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
function findNgModule(node, reflector) {
|
|
446
|
+
const decorators = reflector.getDecoratorsOfDeclaration(node);
|
|
447
|
+
if (decorators) {
|
|
448
|
+
const ngModuleDecorator = migrations.getAngularDecorators(decorators, ['NgModule'], true)[0];
|
|
449
|
+
if (ngModuleDecorator &&
|
|
450
|
+
ngModuleDecorator.args &&
|
|
451
|
+
ngModuleDecorator.args.length > 0 &&
|
|
452
|
+
ts.isObjectLiteralExpression(ngModuleDecorator.args[0])) {
|
|
453
|
+
return ngModuleDecorator.args[0];
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return null;
|
|
457
|
+
}
|
|
458
|
+
function hasChangeDetectionProvider(expression, // either the bootstrapApplication or platformBrowserDynamic().bootstrapModule()
|
|
459
|
+
typeChecker) {
|
|
460
|
+
let literal;
|
|
461
|
+
if (ts.isCallExpression(expression)) {
|
|
462
|
+
let optionsNode = expression.arguments[1];
|
|
463
|
+
if (!optionsNode &&
|
|
464
|
+
symbol.isReferenceToImport(typeChecker, expression.expression, imports.getImportSpecifier(expression.getSourceFile(), '@angular/core', 'createApplication'))) {
|
|
465
|
+
optionsNode = expression.arguments[0];
|
|
466
|
+
}
|
|
467
|
+
if (!optionsNode)
|
|
468
|
+
return false;
|
|
469
|
+
if (ts.isIdentifier(optionsNode)) {
|
|
470
|
+
literal = getObjectLiteralFromIdentifier(optionsNode, typeChecker);
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
literal = optionsNode;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
literal = expression;
|
|
478
|
+
}
|
|
479
|
+
if (!literal) {
|
|
480
|
+
return false;
|
|
481
|
+
}
|
|
482
|
+
const provideZoneCdSpecifier = imports.getImportSpecifier(literal.getSourceFile(), '@angular/core', 'provideZoneChangeDetection');
|
|
483
|
+
const provideZonelessCdSpecifier = imports.getImportSpecifier(literal.getSourceFile(), '@angular/core', 'provideZonelessChangeDetection');
|
|
484
|
+
if (provideZoneCdSpecifier === null && provideZonelessCdSpecifier === null) {
|
|
485
|
+
return false;
|
|
486
|
+
}
|
|
487
|
+
const found = ts.forEachChild(literal, function walk(node) {
|
|
488
|
+
if (ts.isCallExpression(node)) {
|
|
489
|
+
if (provideZonelessCdSpecifier &&
|
|
490
|
+
node.getText().includes(provideZonelessCdSpecifier.getText())) {
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
if (provideZoneCdSpecifier && node.getText().includes(provideZoneCdSpecifier.getText())) {
|
|
494
|
+
return true;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return ts.forEachChild(node, walk);
|
|
498
|
+
});
|
|
499
|
+
return !!found;
|
|
500
|
+
}
|
|
501
|
+
function getObjectLiteralFromIdentifier(identifier, typeChecker) {
|
|
502
|
+
let symbol = typeChecker.getSymbolAtLocation(identifier);
|
|
503
|
+
if (!symbol)
|
|
504
|
+
return;
|
|
505
|
+
// Follow aliases (for imported symbols)
|
|
506
|
+
if ((symbol.flags & ts.SymbolFlags.Alias) !== 0) {
|
|
507
|
+
symbol = typeChecker.getAliasedSymbol(symbol);
|
|
508
|
+
}
|
|
509
|
+
const declarations = symbol.getDeclarations();
|
|
510
|
+
if (!declarations)
|
|
511
|
+
return;
|
|
512
|
+
for (const decl of declarations) {
|
|
513
|
+
if (ts.isVariableDeclaration(decl) &&
|
|
514
|
+
decl.initializer &&
|
|
515
|
+
ts.isObjectLiteralExpression(decl.initializer)) {
|
|
516
|
+
return decl.initializer;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Extracts the import specifiers related to bootstraping from the source file.
|
|
523
|
+
* Returns null if no relevant specifiers are found.
|
|
524
|
+
*/
|
|
525
|
+
function getSpecifiers(sourceFile) {
|
|
526
|
+
const createApplicationSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core', 'createApplication');
|
|
527
|
+
const bootstrapAppSpecifier = imports.getImportSpecifier(sourceFile, '@angular/platform-browser', 'bootstrapApplication');
|
|
528
|
+
const platformBrowserDynamicSpecifier = imports.getImportSpecifier(sourceFile, '@angular/platform-browser-dynamic', 'platformBrowserDynamic');
|
|
529
|
+
const platformBrowserSpecifier = imports.getImportSpecifier(sourceFile, '@angular/platform-browser', 'platformBrowser');
|
|
530
|
+
const testBedSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'TestBed');
|
|
531
|
+
const getTestBedSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core/testing', 'getTestBed');
|
|
532
|
+
const ngModuleSpecifier = imports.getImportSpecifier(sourceFile, '@angular/core', 'NgModule');
|
|
533
|
+
if (!createApplicationSpecifier &&
|
|
534
|
+
!bootstrapAppSpecifier &&
|
|
535
|
+
!platformBrowserSpecifier &&
|
|
536
|
+
!testBedSpecifier &&
|
|
537
|
+
!ngModuleSpecifier &&
|
|
538
|
+
!getTestBedSpecifier) {
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
return {
|
|
542
|
+
createApplicationSpecifier,
|
|
543
|
+
bootstrapAppSpecifier,
|
|
544
|
+
platformBrowserDynamicSpecifier,
|
|
545
|
+
platformBrowserSpecifier,
|
|
546
|
+
testBedSpecifier,
|
|
547
|
+
ngModuleSpecifier,
|
|
548
|
+
getTestBedSpecifier,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* In the case we're looking to insert a new ZoneChangeDetectionModule, we need to check if we already inserted one.
|
|
553
|
+
*
|
|
554
|
+
* This function also checks if the existing one has fewer options (shorter text length), which means the previous migration strategy inserted one
|
|
555
|
+
* but the following one is more complete and we should still add it (the dedup function will take care of the cleanup).
|
|
556
|
+
*/
|
|
557
|
+
function replacementsHaveZoneCdModule(rootRelativePath, replacements, text) {
|
|
558
|
+
return replacements.some((replacement) => {
|
|
559
|
+
const exisitingText = replacement.update.data.toInsert;
|
|
560
|
+
const isSameFile = replacement.projectFile.rootRelativePath === rootRelativePath;
|
|
561
|
+
return (isSameFile &&
|
|
562
|
+
text.includes('ZoneChangeDetectionModule') &&
|
|
563
|
+
exisitingText.length >= text.length);
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
function removePropertiesFromLiteral(projectFile, literal, propertyNames, replacements) {
|
|
567
|
+
const syntaxList = literal.getChildren().find((ch) => ch.kind === ts.SyntaxKind.SyntaxList);
|
|
568
|
+
const optionsElements = syntaxList.getChildren();
|
|
569
|
+
const optionsToRemove = [];
|
|
570
|
+
optionsElements.forEach((node, i, children) => {
|
|
571
|
+
if (ts.isPropertyAssignment(node) &&
|
|
572
|
+
ts.isIdentifier(node.name) &&
|
|
573
|
+
propertyNames.includes(node.name.text)) {
|
|
574
|
+
// Look ahead for comma
|
|
575
|
+
const next = children[i + 1];
|
|
576
|
+
if (next && next.kind === ts.SyntaxKind.CommaToken) {
|
|
577
|
+
optionsToRemove.push({ start: node.getStart(), end: next.getEnd() });
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
optionsToRemove.push({ start: node.getStart(), end: node.getEnd() });
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
optionsToRemove.forEach((toRemove) => {
|
|
585
|
+
replacements.push(new project_paths.Replacement(projectFile, new project_paths.TextUpdate({ position: toRemove.start, end: toRemove.end, toInsert: '' })));
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
function migrate() {
|
|
590
|
+
return async (tree) => {
|
|
591
|
+
await project_paths.runMigrationInDevkit({
|
|
592
|
+
tree,
|
|
593
|
+
getMigration: () => new BootstrapOptionsMigration(),
|
|
594
|
+
});
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
exports.migrate = migrate;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v21.0.0-next.
|
|
3
|
+
* @license Angular v21.0.0-next.10
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,18 +8,14 @@
|
|
|
8
8
|
|
|
9
9
|
require('@angular-devkit/core');
|
|
10
10
|
require('node:path/posix');
|
|
11
|
-
var project_paths = require('./project_paths-
|
|
11
|
+
var project_paths = require('./project_paths-DvD50ouC.cjs');
|
|
12
12
|
var ts = require('typescript');
|
|
13
|
-
require('
|
|
14
|
-
var
|
|
15
|
-
var index = require('./index-esqfDjNB.cjs');
|
|
16
|
-
require('path');
|
|
13
|
+
var compilerCli = require('@angular/compiler-cli');
|
|
14
|
+
var migrations = require('@angular/compiler-cli/private/migrations');
|
|
17
15
|
require('node:path');
|
|
18
|
-
var apply_import_manager = require('./apply_import_manager-
|
|
16
|
+
var apply_import_manager = require('./apply_import_manager-1Zs_gpB6.cjs');
|
|
19
17
|
require('@angular-devkit/schematics');
|
|
20
|
-
require('
|
|
21
|
-
require('module');
|
|
22
|
-
require('url');
|
|
18
|
+
require('./project_tsconfig_paths-CDVxT6Ov.cjs');
|
|
23
19
|
|
|
24
20
|
/** Migration that cleans up unused imports from a project. */
|
|
25
21
|
class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
|
|
@@ -29,7 +25,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
29
25
|
extendedDiagnostics: {
|
|
30
26
|
checks: {
|
|
31
27
|
// Ensure that the diagnostic is enabled.
|
|
32
|
-
unusedStandaloneImports:
|
|
28
|
+
unusedStandaloneImports: migrations.DiagnosticCategoryLabel.Warning,
|
|
33
29
|
},
|
|
34
30
|
},
|
|
35
31
|
});
|
|
@@ -43,7 +39,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
43
39
|
if (diag.file !== undefined &&
|
|
44
40
|
diag.start !== undefined &&
|
|
45
41
|
diag.length !== undefined &&
|
|
46
|
-
diag.code ===
|
|
42
|
+
diag.code === compilerCli.ngErrorCode(compilerCli.ErrorCode.UNUSED_STANDALONE_IMPORTS)) {
|
|
47
43
|
// Skip files that aren't owned by this compilation unit.
|
|
48
44
|
if (!info.sourceFiles.includes(diag.file)) {
|
|
49
45
|
return;
|
|
@@ -193,7 +189,7 @@ class UnusedImportsMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
193
189
|
generateReplacements(sourceFile, removalLocations, usages, info, replacements) {
|
|
194
190
|
const { fullRemovals, partialRemovals, allRemovedIdentifiers } = removalLocations;
|
|
195
191
|
const { importedSymbols, identifierCounts } = usages;
|
|
196
|
-
const importManager = new
|
|
192
|
+
const importManager = new migrations.ImportManager();
|
|
197
193
|
const sourceText = sourceFile.getFullText();
|
|
198
194
|
// Replace full arrays with empty ones. This allows preserves more of the user's formatting.
|
|
199
195
|
fullRemovals.forEach((node) => {
|