@angular/core 20.0.0-next.1 → 20.0.0-next.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 +770 -2144
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/di.mjs +3 -2
- package/fesm2022/primitives/di.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +2 -589
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +44 -13
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +7 -39
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +116 -143
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/weak_ref-DrMdAIDh.mjs +12 -0
- package/fesm2022/weak_ref-DrMdAIDh.mjs.map +1 -0
- package/index.d.ts +14366 -15214
- package/navigation_types.d-u4EOrrdZ.d.ts +121 -0
- package/package.json +2 -2
- package/primitives/di/index.d.ts +66 -59
- package/primitives/event-dispatch/index.d.ts +205 -309
- package/primitives/signals/index.d.ts +161 -195
- package/rxjs-interop/index.d.ts +71 -100
- package/schematics/bundles/{apply_import_manager-e2a7fe5b.js → apply_import_manager-BXQEjo09.js} +15 -19
- package/schematics/bundles/{checker-af521da6.js → checker-BHb19MHt.js} +3695 -1175
- package/schematics/bundles/cleanup-unused-imports.js +56 -89
- package/schematics/bundles/{compiler_host-5a29293c.js → compiler_host-Bk3repE2.js} +19 -23
- package/schematics/bundles/control-flow-migration.js +81 -38
- package/schematics/bundles/{imports-047fbbc8.js → imports-CIX-JgAN.js} +9 -14
- package/schematics/bundles/{index-1bef3025.js → index-BL9kAIe5.js} +62 -66
- package/schematics/bundles/{program-a449f9bf.js → index-I8VbxQcO.js} +1508 -3178
- package/schematics/bundles/inject-flags.js +147 -0
- package/schematics/bundles/inject-migration.js +121 -127
- package/schematics/bundles/{leading_space-f8944434.js → leading_space-D9nQ8UQC.js} +1 -1
- package/schematics/bundles/{migrate_ts_type_references-2a3e9e6b.js → migrate_ts_type_references-KlOTWeDl.js} +121 -126
- package/schematics/bundles/{ng_decorators-b0d8b324.js → ng_decorators-DznZ5jMl.js} +4 -8
- package/schematics/bundles/{nodes-7758dbf6.js → nodes-B16H9JUd.js} +2 -6
- package/schematics/bundles/output-migration.js +94 -128
- package/schematics/bundles/{project_tsconfig_paths-b558633b.js → project_tsconfig_paths-CDVxT6Ov.js} +1 -1
- package/schematics/bundles/{property_name-ac18447e.js → property_name-BBwFuqMe.js} +3 -7
- package/schematics/bundles/route-lazy-loading.js +35 -41
- package/schematics/bundles/{project_paths-17dc204d.js → run_in_devkit-C0JPtK2u.js} +283 -216
- package/schematics/bundles/self-closing-tags-migration.js +55 -91
- package/schematics/bundles/signal-input-migration.js +121 -156
- package/schematics/bundles/signal-queries-migration.js +119 -154
- package/schematics/bundles/signals.js +12 -14
- package/schematics/bundles/standalone-migration.js +180 -200
- package/schematics/bundles/symbol-VPWguRxr.js +25 -0
- package/schematics/bundles/test-bed-get.js +98 -0
- package/schematics/migrations.json +8 -14
- package/testing/index.d.ts +289 -471
- package/weak_ref.d-ttyj86RV.d.ts +9 -0
- package/schematics/bundles/explicit-standalone-flag.js +0 -184
- package/schematics/bundles/index-ef1bffbb.js +0 -30
- package/schematics/bundles/pending-tasks.js +0 -103
- package/schematics/bundles/provide-initializer.js +0 -186
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.0-next.
|
|
3
|
+
* @license Angular v20.0.0-next.3
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,14 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
var ts = require('typescript');
|
|
10
10
|
|
|
11
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
|
-
|
|
13
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
14
|
-
|
|
15
11
|
/** Find the closest parent node of a particular kind. */
|
|
16
12
|
function closestNode(node, predicate) {
|
|
17
13
|
let current = node.parent;
|
|
18
|
-
while (current && !
|
|
14
|
+
while (current && !ts.isSourceFile(current)) {
|
|
19
15
|
if (predicate(current)) {
|
|
20
16
|
return current;
|
|
21
17
|
}
|
|
@@ -1,43 +1,37 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.0-next.
|
|
3
|
+
* @license Angular v20.0.0-next.3
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
-
|
|
11
|
-
var schematics = require('@angular-devkit/schematics');
|
|
12
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-b558633b.js');
|
|
13
|
-
var project_paths = require('./project_paths-17dc204d.js');
|
|
14
|
-
require('os');
|
|
15
9
|
var ts = require('typescript');
|
|
16
|
-
|
|
17
|
-
var
|
|
10
|
+
require('os');
|
|
11
|
+
var checker = require('./checker-BHb19MHt.js');
|
|
12
|
+
var index$1 = require('./index-I8VbxQcO.js');
|
|
18
13
|
require('path');
|
|
19
|
-
var
|
|
20
|
-
var
|
|
14
|
+
var run_in_devkit = require('./run_in_devkit-C0JPtK2u.js');
|
|
15
|
+
var apply_import_manager = require('./apply_import_manager-BXQEjo09.js');
|
|
16
|
+
var index = require('./index-BL9kAIe5.js');
|
|
21
17
|
require('@angular-devkit/core');
|
|
22
18
|
require('node:path/posix');
|
|
23
19
|
require('fs');
|
|
24
20
|
require('module');
|
|
25
21
|
require('url');
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
22
|
+
require('@angular-devkit/schematics');
|
|
23
|
+
require('./project_tsconfig_paths-CDVxT6Ov.js');
|
|
30
24
|
|
|
31
25
|
function isOutputDeclarationEligibleForMigration(node) {
|
|
32
26
|
return (node.initializer !== undefined &&
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
ts.isNewExpression(node.initializer) &&
|
|
28
|
+
ts.isIdentifier(node.initializer.expression) &&
|
|
35
29
|
node.initializer.expression.text === 'EventEmitter');
|
|
36
30
|
}
|
|
37
31
|
function isPotentialOutputCallUsage(node, name) {
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
if (ts.isCallExpression(node) &&
|
|
33
|
+
ts.isPropertyAccessExpression(node.expression) &&
|
|
34
|
+
ts.isIdentifier(node.expression.name)) {
|
|
41
35
|
return node.expression?.name.text === name;
|
|
42
36
|
}
|
|
43
37
|
else {
|
|
@@ -68,8 +62,8 @@ function isTargetOutputDeclaration(node, checker, reflector, dtsReader) {
|
|
|
68
62
|
function isOutputDeclaration(node, reflector, dtsReader) {
|
|
69
63
|
// `.d.ts` file, so we check the `static ecmp` metadata on the `declare class`.
|
|
70
64
|
if (node.getSourceFile().isDeclarationFile) {
|
|
71
|
-
if (!
|
|
72
|
-
!
|
|
65
|
+
if (!ts.isIdentifier(node.name) ||
|
|
66
|
+
!ts.isClassDeclaration(node.parent) ||
|
|
73
67
|
node.parent.name === undefined) {
|
|
74
68
|
return false;
|
|
75
69
|
}
|
|
@@ -82,7 +76,7 @@ function isOutputDeclaration(node, reflector, dtsReader) {
|
|
|
82
76
|
}
|
|
83
77
|
function getTargetPropertyDeclaration(targetSymbol) {
|
|
84
78
|
const valDeclaration = targetSymbol.valueDeclaration;
|
|
85
|
-
if (valDeclaration !== undefined &&
|
|
79
|
+
if (valDeclaration !== undefined && ts.isPropertyDeclaration(valDeclaration)) {
|
|
86
80
|
return valDeclaration;
|
|
87
81
|
}
|
|
88
82
|
return null;
|
|
@@ -96,12 +90,12 @@ function getOutputDecorator(node, reflector) {
|
|
|
96
90
|
// THINK: this utility + type is not specific to @Output, really, maybe move it to tsurge?
|
|
97
91
|
/** Computes an unique ID for a given Angular `@Output` property. */
|
|
98
92
|
function getUniqueIdForProperty(info, prop) {
|
|
99
|
-
const { id } =
|
|
93
|
+
const { id } = run_in_devkit.projectFile(prop.getSourceFile(), info);
|
|
100
94
|
id.replace(/\.d\.ts$/, '.ts');
|
|
101
95
|
return `${id}@@${prop.parent.name ?? 'unknown-class'}@@${prop.name.getText()}`;
|
|
102
96
|
}
|
|
103
97
|
function isTestRunnerImport(node) {
|
|
104
|
-
if (
|
|
98
|
+
if (ts.isImportDeclaration(node)) {
|
|
105
99
|
const moduleSpecifier = node.moduleSpecifier.getText();
|
|
106
100
|
return moduleSpecifier.includes('jasmine') || moduleSpecifier.includes('catalyst');
|
|
107
101
|
}
|
|
@@ -147,27 +141,27 @@ function checkNonTsReferenceCallsField(ref, fieldName) {
|
|
|
147
141
|
return potentialRead;
|
|
148
142
|
}
|
|
149
143
|
|
|
150
|
-
const printer =
|
|
144
|
+
const printer = ts.createPrinter();
|
|
151
145
|
function calculateDeclarationReplacement(info, node, aliasParam) {
|
|
152
146
|
const sf = node.getSourceFile();
|
|
153
|
-
const payloadTypes = node.initializer !== undefined &&
|
|
147
|
+
const payloadTypes = node.initializer !== undefined && ts.isNewExpression(node.initializer)
|
|
154
148
|
? node.initializer?.typeArguments
|
|
155
149
|
: undefined;
|
|
156
|
-
const outputCall =
|
|
150
|
+
const outputCall = ts.factory.createCallExpression(ts.factory.createIdentifier('output'), payloadTypes, aliasParam !== undefined
|
|
157
151
|
? [
|
|
158
|
-
|
|
159
|
-
|
|
152
|
+
ts.factory.createObjectLiteralExpression([
|
|
153
|
+
ts.factory.createPropertyAssignment('alias', ts.factory.createStringLiteral(aliasParam, true)),
|
|
160
154
|
], false),
|
|
161
155
|
]
|
|
162
156
|
: []);
|
|
163
|
-
const existingModifiers = (node.modifiers ?? []).filter((modifier) => !
|
|
164
|
-
const updatedOutputDeclaration =
|
|
157
|
+
const existingModifiers = (node.modifiers ?? []).filter((modifier) => !ts.isDecorator(modifier) && modifier.kind !== ts.SyntaxKind.ReadonlyKeyword);
|
|
158
|
+
const updatedOutputDeclaration = ts.factory.createPropertyDeclaration(
|
|
165
159
|
// Think: this logic of dealing with modifiers is applicable to all signal-based migrations
|
|
166
|
-
|
|
160
|
+
ts.factory.createNodeArray([
|
|
167
161
|
...existingModifiers,
|
|
168
|
-
|
|
162
|
+
ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword),
|
|
169
163
|
]), node.name, undefined, undefined, outputCall);
|
|
170
|
-
return prepareTextReplacementForNode(info, node, printer.printNode(
|
|
164
|
+
return prepareTextReplacementForNode(info, node, printer.printNode(ts.EmitHint.Unspecified, updatedOutputDeclaration, sf));
|
|
171
165
|
}
|
|
172
166
|
function calculateImportReplacements(info, sourceFiles) {
|
|
173
167
|
const importReplacements = {};
|
|
@@ -175,7 +169,7 @@ function calculateImportReplacements(info, sourceFiles) {
|
|
|
175
169
|
const importManager = new checker.ImportManager();
|
|
176
170
|
const addOnly = [];
|
|
177
171
|
const addRemove = [];
|
|
178
|
-
const file =
|
|
172
|
+
const file = run_in_devkit.projectFile(sf, info);
|
|
179
173
|
importManager.addImport({
|
|
180
174
|
requestedFile: sf,
|
|
181
175
|
exportModuleSpecifier: '@angular/core',
|
|
@@ -205,7 +199,7 @@ function calculateCompleteCallReplacement(info, node) {
|
|
|
205
199
|
return prepareTextReplacementForNode(info, node, '', node.getFullStart());
|
|
206
200
|
}
|
|
207
201
|
function calculatePipeCallReplacement(info, node) {
|
|
208
|
-
if (
|
|
202
|
+
if (ts.isPropertyAccessExpression(node.expression)) {
|
|
209
203
|
const sf = node.getSourceFile();
|
|
210
204
|
const importManager = new checker.ImportManager();
|
|
211
205
|
const outputToObservableIdent = importManager.addImport({
|
|
@@ -213,13 +207,13 @@ function calculatePipeCallReplacement(info, node) {
|
|
|
213
207
|
exportModuleSpecifier: '@angular/core/rxjs-interop',
|
|
214
208
|
exportSymbolName: 'outputToObservable',
|
|
215
209
|
});
|
|
216
|
-
const toObsCallExp =
|
|
210
|
+
const toObsCallExp = ts.factory.createCallExpression(outputToObservableIdent, undefined, [
|
|
217
211
|
node.expression.expression,
|
|
218
212
|
]);
|
|
219
|
-
const pipePropAccessExp =
|
|
220
|
-
const pipeCallExp =
|
|
213
|
+
const pipePropAccessExp = ts.factory.updatePropertyAccessExpression(node.expression, toObsCallExp, node.expression.name);
|
|
214
|
+
const pipeCallExp = ts.factory.updateCallExpression(node, pipePropAccessExp, [], node.arguments);
|
|
221
215
|
const replacements = [
|
|
222
|
-
prepareTextReplacementForNode(info, node, printer.printNode(
|
|
216
|
+
prepareTextReplacementForNode(info, node, printer.printNode(ts.EmitHint.Unspecified, pipeCallExp, sf)),
|
|
223
217
|
];
|
|
224
218
|
apply_import_manager.applyImportManagerChanges(importManager, replacements, [sf], info);
|
|
225
219
|
return replacements;
|
|
@@ -231,36 +225,36 @@ function calculatePipeCallReplacement(info, node) {
|
|
|
231
225
|
}
|
|
232
226
|
function prepareTextReplacementForNode(info, node, replacement, start) {
|
|
233
227
|
const sf = node.getSourceFile();
|
|
234
|
-
return new
|
|
228
|
+
return new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({
|
|
235
229
|
position: start ?? node.getStart(),
|
|
236
230
|
end: node.getEnd(),
|
|
237
231
|
toInsert: replacement,
|
|
238
232
|
}));
|
|
239
233
|
}
|
|
240
234
|
function prepareTextReplacement(file, replacement, start, end) {
|
|
241
|
-
return new
|
|
235
|
+
return new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
242
236
|
position: start,
|
|
243
237
|
end: end,
|
|
244
238
|
toInsert: replacement,
|
|
245
239
|
}));
|
|
246
240
|
}
|
|
247
241
|
|
|
248
|
-
class OutputMigration extends
|
|
242
|
+
class OutputMigration extends run_in_devkit.TsurgeFunnelMigration {
|
|
249
243
|
config;
|
|
250
244
|
constructor(config = {}) {
|
|
251
245
|
super();
|
|
252
246
|
this.config = config;
|
|
253
247
|
}
|
|
254
248
|
async analyze(info) {
|
|
255
|
-
const { sourceFiles, program
|
|
249
|
+
const { sourceFiles, program } = info;
|
|
256
250
|
const outputFieldReplacements = {};
|
|
257
251
|
const problematicUsages = {};
|
|
258
252
|
let problematicDeclarationCount = 0;
|
|
259
253
|
const filesWithOutputDeclarations = new Set();
|
|
260
|
-
const checker$1 = program
|
|
254
|
+
const checker$1 = program.getTypeChecker();
|
|
261
255
|
const reflector = new checker.TypeScriptReflectionHost(checker$1);
|
|
262
|
-
const dtsReader = new
|
|
263
|
-
const evaluator = new
|
|
256
|
+
const dtsReader = new index$1.DtsMetadataReader(checker$1, reflector);
|
|
257
|
+
const evaluator = new index$1.PartialEvaluator(reflector, checker$1, null);
|
|
264
258
|
const resourceLoader = info.ngCompiler?.['resourceManager'] ?? null;
|
|
265
259
|
// Pre-analyze the program and get access to the template type checker.
|
|
266
260
|
// If we are processing a non-Angular target, there is no template info.
|
|
@@ -288,7 +282,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
288
282
|
let isTestFile = false;
|
|
289
283
|
const outputMigrationVisitor = (node) => {
|
|
290
284
|
// detect output declarations
|
|
291
|
-
if (
|
|
285
|
+
if (ts.isPropertyDeclaration(node)) {
|
|
292
286
|
const outputDecorator = getOutputDecorator(node, reflector);
|
|
293
287
|
if (outputDecorator !== null) {
|
|
294
288
|
if (isOutputDeclarationEligibleForMigration(node)) {
|
|
@@ -296,7 +290,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
296
290
|
id: getUniqueIdForProperty(info, node),
|
|
297
291
|
aliasParam: outputDecorator.args?.at(0),
|
|
298
292
|
};
|
|
299
|
-
const outputFile =
|
|
293
|
+
const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
|
|
300
294
|
if (this.config.shouldMigrate === undefined ||
|
|
301
295
|
this.config.shouldMigrate({
|
|
302
296
|
key: outputDef.id,
|
|
@@ -320,21 +314,21 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
320
314
|
}
|
|
321
315
|
}
|
|
322
316
|
// detect .next usages that should be migrated to .emit
|
|
323
|
-
if (isPotentialNextCallUsage(node) &&
|
|
317
|
+
if (isPotentialNextCallUsage(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
324
318
|
const propertyDeclaration = isTargetOutputDeclaration(node.expression.expression, checker$1, reflector, dtsReader);
|
|
325
319
|
if (propertyDeclaration !== null) {
|
|
326
320
|
const id = getUniqueIdForProperty(info, propertyDeclaration);
|
|
327
|
-
const outputFile =
|
|
321
|
+
const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
|
|
328
322
|
addOutputReplacement(outputFieldReplacements, id, outputFile, calculateNextFnReplacement(info, node.expression.name));
|
|
329
323
|
}
|
|
330
324
|
}
|
|
331
325
|
// detect .complete usages that should be removed
|
|
332
|
-
if (isPotentialCompleteCallUsage(node) &&
|
|
326
|
+
if (isPotentialCompleteCallUsage(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
333
327
|
const propertyDeclaration = isTargetOutputDeclaration(node.expression.expression, checker$1, reflector, dtsReader);
|
|
334
328
|
if (propertyDeclaration !== null) {
|
|
335
329
|
const id = getUniqueIdForProperty(info, propertyDeclaration);
|
|
336
|
-
const outputFile =
|
|
337
|
-
if (
|
|
330
|
+
const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
|
|
331
|
+
if (ts.isExpressionStatement(node.parent)) {
|
|
338
332
|
addOutputReplacement(outputFieldReplacements, id, outputFile, calculateCompleteCallReplacement(info, node.parent));
|
|
339
333
|
}
|
|
340
334
|
else {
|
|
@@ -347,12 +341,12 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
347
341
|
isTestFile = true;
|
|
348
342
|
}
|
|
349
343
|
// detect unsafe access of the output property
|
|
350
|
-
if (isPotentialPipeCallUsage(node) &&
|
|
344
|
+
if (isPotentialPipeCallUsage(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
351
345
|
const propertyDeclaration = isTargetOutputDeclaration(node.expression.expression, checker$1, reflector, dtsReader);
|
|
352
346
|
if (propertyDeclaration !== null) {
|
|
353
347
|
const id = getUniqueIdForProperty(info, propertyDeclaration);
|
|
354
348
|
if (isTestFile) {
|
|
355
|
-
const outputFile =
|
|
349
|
+
const outputFile = run_in_devkit.projectFile(node.getSourceFile(), info);
|
|
356
350
|
addOutputReplacement(outputFieldReplacements, id, outputFile, ...calculatePipeCallReplacement(info, node));
|
|
357
351
|
}
|
|
358
352
|
else {
|
|
@@ -360,12 +354,12 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
360
354
|
}
|
|
361
355
|
}
|
|
362
356
|
}
|
|
363
|
-
|
|
357
|
+
ts.forEachChild(node, outputMigrationVisitor);
|
|
364
358
|
};
|
|
365
359
|
// calculate output migration replacements
|
|
366
360
|
for (const sf of sourceFiles) {
|
|
367
361
|
isTestFile = false;
|
|
368
|
-
|
|
362
|
+
ts.forEachChild(sf, outputMigrationVisitor);
|
|
369
363
|
}
|
|
370
364
|
// take care of the references in templates and host bindings
|
|
371
365
|
const referenceResult = { references: [] };
|
|
@@ -373,7 +367,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
373
367
|
referenceResult);
|
|
374
368
|
// calculate template / host binding replacements
|
|
375
369
|
for (const sf of sourceFiles) {
|
|
376
|
-
|
|
370
|
+
ts.forEachChild(sf, templateHostRefVisitor);
|
|
377
371
|
}
|
|
378
372
|
for (const ref of referenceResult.references) {
|
|
379
373
|
// detect .next usages that should be migrated to .emit in template and host binding expressions
|
|
@@ -396,7 +390,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
396
390
|
}
|
|
397
391
|
// calculate import replacements but do so only for files that have output declarations
|
|
398
392
|
const importReplacements = calculateImportReplacements(info, filesWithOutputDeclarations);
|
|
399
|
-
return
|
|
393
|
+
return run_in_devkit.confirmAsSerializable({
|
|
400
394
|
problematicDeclarationCount,
|
|
401
395
|
outputFields: outputFieldReplacements,
|
|
402
396
|
importReplacements,
|
|
@@ -426,7 +420,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
426
420
|
problematicUsages[declId] = unit.problematicUsages[declId];
|
|
427
421
|
}
|
|
428
422
|
}
|
|
429
|
-
return
|
|
423
|
+
return run_in_devkit.confirmAsSerializable({
|
|
430
424
|
problematicDeclarationCount,
|
|
431
425
|
outputFields,
|
|
432
426
|
importReplacements,
|
|
@@ -448,7 +442,7 @@ class OutputMigration extends project_paths.TsurgeFunnelMigration {
|
|
|
448
442
|
}
|
|
449
443
|
}
|
|
450
444
|
// Noop here as we don't have any form of special global metadata.
|
|
451
|
-
return
|
|
445
|
+
return run_in_devkit.confirmAsSerializable(combinedData);
|
|
452
446
|
}
|
|
453
447
|
async stats(globalMetadata) {
|
|
454
448
|
const detectedOutputs = new Set(Object.keys(globalMetadata.outputFields)).size +
|
|
@@ -507,73 +501,45 @@ function addOutputReplacement(outputFieldReplacements, outputId, file, ...replac
|
|
|
507
501
|
|
|
508
502
|
function migrate(options) {
|
|
509
503
|
return async (tree, context) => {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
504
|
+
await run_in_devkit.runMigrationInDevkit({
|
|
505
|
+
tree,
|
|
506
|
+
getMigration: (fs) => new OutputMigration({
|
|
507
|
+
shouldMigrate: (_, file) => {
|
|
508
|
+
return (file.rootRelativePath.startsWith(fs.normalize(options.path)) &&
|
|
509
|
+
!/(^|\/)node_modules\//.test(file.rootRelativePath));
|
|
510
|
+
},
|
|
511
|
+
}),
|
|
512
|
+
beforeProgramCreation: (tsconfigPath) => {
|
|
513
|
+
context.logger.info(`Preparing analysis for: ${tsconfigPath}...`);
|
|
520
514
|
},
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
const info = migration.prepareProgram(baseInfo);
|
|
528
|
-
// Support restricting the analysis to subfolders for larger projects.
|
|
529
|
-
if (analysisPath !== '/') {
|
|
530
|
-
info.sourceFiles = info.sourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
|
|
531
|
-
info.fullProgramSourceFiles = info.fullProgramSourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
|
|
532
|
-
}
|
|
533
|
-
return { info, tsconfigPath };
|
|
534
|
-
});
|
|
535
|
-
// Analyze phase. Treat all projects as compilation units as
|
|
536
|
-
// this allows us to support references between those.
|
|
537
|
-
for (const { info, tsconfigPath } of programInfos) {
|
|
538
|
-
context.logger.info(`Scanning for outputs: ${tsconfigPath}..`);
|
|
539
|
-
unitResults.push(await migration.analyze(info));
|
|
540
|
-
}
|
|
541
|
-
context.logger.info(``);
|
|
542
|
-
context.logger.info(`Processing analysis data between targets..`);
|
|
543
|
-
context.logger.info(``);
|
|
544
|
-
const combined = await project_paths.synchronouslyCombineUnitData(migration, unitResults);
|
|
545
|
-
if (combined === null) {
|
|
546
|
-
context.logger.error('Migration failed unexpectedly with no analysis data');
|
|
547
|
-
return;
|
|
548
|
-
}
|
|
549
|
-
const globalMeta = await migration.globalMeta(combined);
|
|
550
|
-
const replacementsPerFile = new Map();
|
|
551
|
-
for (const { info, tsconfigPath } of programInfos) {
|
|
552
|
-
context.logger.info(`Migrating: ${tsconfigPath}..`);
|
|
553
|
-
const { replacements } = await migration.migrate(globalMeta);
|
|
554
|
-
const changesPerFile = project_paths.groupReplacementsByFile(replacements);
|
|
555
|
-
for (const [file, changes] of changesPerFile) {
|
|
556
|
-
if (!replacementsPerFile.has(file)) {
|
|
557
|
-
replacementsPerFile.set(file, changes);
|
|
515
|
+
afterProgramCreation: (info, fs) => {
|
|
516
|
+
const analysisPath = fs.resolve(options.analysisDir);
|
|
517
|
+
// Support restricting the analysis to subfolders for larger projects.
|
|
518
|
+
if (analysisPath !== '/') {
|
|
519
|
+
info.sourceFiles = info.sourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
|
|
520
|
+
info.fullProgramSourceFiles = info.fullProgramSourceFiles.filter((sf) => sf.fileName.startsWith(analysisPath));
|
|
558
521
|
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
522
|
+
},
|
|
523
|
+
beforeUnitAnalysis: (tsconfigPath) => {
|
|
524
|
+
context.logger.info(`Scanning for outputs: ${tsconfigPath}...`);
|
|
525
|
+
},
|
|
526
|
+
afterAllAnalyzed: () => {
|
|
527
|
+
context.logger.info(``);
|
|
528
|
+
context.logger.info(`Processing analysis data between targets...`);
|
|
529
|
+
context.logger.info(``);
|
|
530
|
+
},
|
|
531
|
+
afterAnalysisFailure: () => {
|
|
532
|
+
context.logger.error('Migration failed unexpectedly with no analysis data');
|
|
533
|
+
},
|
|
534
|
+
whenDone: ({ counters }) => {
|
|
535
|
+
const { detectedOutputs, problematicOutputs, successRate } = counters;
|
|
536
|
+
const migratedOutputs = detectedOutputs - problematicOutputs;
|
|
537
|
+
const successRatePercent = (successRate * 100).toFixed(2);
|
|
538
|
+
context.logger.info('');
|
|
539
|
+
context.logger.info(`Successfully migrated to outputs as functions 🎉`);
|
|
540
|
+
context.logger.info(` -> Migrated ${migratedOutputs} out of ${detectedOutputs} detected outputs (${successRatePercent} %).`);
|
|
541
|
+
},
|
|
542
|
+
});
|
|
577
543
|
};
|
|
578
544
|
}
|
|
579
545
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v20.0.0-next.
|
|
3
|
+
* @license Angular v20.0.0-next.3
|
|
4
4
|
* (c) 2010-2025 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -8,23 +8,19 @@
|
|
|
8
8
|
|
|
9
9
|
var ts = require('typescript');
|
|
10
10
|
|
|
11
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
|
-
|
|
13
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
14
|
-
|
|
15
11
|
/**
|
|
16
12
|
* Gets the text of the given property name. Returns null if the property
|
|
17
13
|
* name couldn't be determined statically.
|
|
18
14
|
*/
|
|
19
15
|
function getPropertyNameText(node) {
|
|
20
|
-
if (
|
|
16
|
+
if (ts.isIdentifier(node) || ts.isStringLiteralLike(node)) {
|
|
21
17
|
return node.text;
|
|
22
18
|
}
|
|
23
19
|
return null;
|
|
24
20
|
}
|
|
25
21
|
/** Finds a property with a specific name in an object literal expression. */
|
|
26
22
|
function findLiteralProperty(literal, name) {
|
|
27
|
-
return literal.properties.find((prop) => prop.name &&
|
|
23
|
+
return literal.properties.find((prop) => prop.name && ts.isIdentifier(prop.name) && prop.name.text === name);
|
|
28
24
|
}
|
|
29
25
|
|
|
30
26
|
exports.findLiteralProperty = findLiteralProperty;
|