@angular/core 19.0.0-next.8 → 19.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/core.mjs +21591 -19590
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +71 -47
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +8 -6
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +90 -10
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +177 -114
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +591 -101
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +7 -4
- package/primitives/signals/index.d.ts +7 -1
- package/rxjs-interop/index.d.ts +35 -4
- package/schematics/bundles/{checker-e68dd7ce.js → checker-2451e7c5.js} +2464 -1132
- package/schematics/bundles/{group_replacements-472b2387.js → combine_units-c52492ab.js} +1964 -2207
- package/schematics/bundles/{compiler_host-9a4d0c2b.js → compiler_host-f54f8309.js} +2 -2
- package/schematics/bundles/control-flow-migration.js +3 -3
- package/schematics/bundles/explicit-standalone-flag.js +31 -11
- package/schematics/bundles/{imports-4ac08251.js → imports-44987700.js} +1 -1
- package/schematics/bundles/inject-migration.js +122 -48
- package/schematics/bundles/{leading_space-d190b83b.js → leading_space-6e7a8ec6.js} +1 -1
- package/schematics/bundles/migrate_ts_type_references-ab18a7c3.js +1463 -0
- package/schematics/bundles/{nodes-0e7d45ca.js → ng_decorators-3ad437d2.js} +2 -15
- package/schematics/bundles/nodes-ffdce442.js +27 -0
- package/schematics/bundles/output-migration.js +7450 -0
- package/schematics/bundles/pending-tasks.js +5 -5
- package/schematics/bundles/{program-105283c5.js → program-58424797.js} +1359 -455
- package/schematics/bundles/{project_tsconfig_paths-e9ccccbf.js → project_tsconfig_paths-6c9cde78.js} +1 -1
- package/schematics/bundles/provide-initializer.js +190 -0
- package/schematics/bundles/route-lazy-loading.js +4 -4
- package/schematics/bundles/signal-input-migration.js +197 -349
- package/schematics/bundles/signal-queries-migration.js +462 -185
- package/schematics/bundles/signals.js +54 -0
- package/schematics/bundles/standalone-migration.js +38 -20
- package/schematics/collection.json +11 -0
- package/schematics/migrations.json +7 -1
- package/schematics/ng-generate/output-migration/schema.json +19 -0
- package/schematics/ng-generate/signal-queries-migration/schema.json +11 -0
- package/schematics/ng-generate/signals/schema.json +65 -0
- package/testing/index.d.ts +3 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-
|
|
3
|
+
* @license Angular v19.0.0-rc.0
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
9
|
var ts = require('typescript');
|
|
10
|
-
var checker = require('./checker-
|
|
10
|
+
var checker = require('./checker-2451e7c5.js');
|
|
11
11
|
require('os');
|
|
12
12
|
var p = require('path');
|
|
13
13
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-
|
|
3
|
+
* @license Angular v19.0.0-rc.0
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -10,8 +10,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
10
10
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
var p = require('path');
|
|
13
|
-
var compiler_host = require('./compiler_host-
|
|
14
|
-
var checker = require('./checker-
|
|
13
|
+
var compiler_host = require('./compiler_host-f54f8309.js');
|
|
14
|
+
var checker = require('./checker-2451e7c5.js');
|
|
15
15
|
var ts = require('typescript');
|
|
16
16
|
require('os');
|
|
17
17
|
require('fs');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-
|
|
3
|
+
* @license Angular v19.0.0-rc.0
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -10,12 +10,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
10
10
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
var p = require('path');
|
|
13
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-
|
|
14
|
-
var compiler_host = require('./compiler_host-
|
|
13
|
+
var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
|
|
14
|
+
var compiler_host = require('./compiler_host-f54f8309.js');
|
|
15
15
|
var ts = require('typescript');
|
|
16
|
-
var imports = require('./imports-
|
|
16
|
+
var imports = require('./imports-44987700.js');
|
|
17
17
|
require('@angular-devkit/core');
|
|
18
|
-
require('./checker-
|
|
18
|
+
require('./checker-2451e7c5.js');
|
|
19
19
|
require('os');
|
|
20
20
|
require('fs');
|
|
21
21
|
require('module');
|
|
@@ -77,16 +77,23 @@ function migrateFile(sourceFile, rewriteFn) {
|
|
|
77
77
|
}
|
|
78
78
|
const properties = decoratorArgument.properties;
|
|
79
79
|
const standaloneProp = getStandaloneProperty(properties);
|
|
80
|
-
|
|
81
|
-
//
|
|
80
|
+
const hasImports = decoratorHasImports(decoratorArgument);
|
|
81
|
+
// We'll use the presence of imports to keep the migration idempotent
|
|
82
|
+
// We need to take care of 3 cases
|
|
83
|
+
// - standalone: true => remove the property if we have imports
|
|
82
84
|
// - standalone: false => nothing
|
|
83
|
-
// - No standalone property => add a standalone: false property
|
|
85
|
+
// - No standalone property => add a standalone: false property if there are no imports
|
|
84
86
|
let newProperties;
|
|
85
87
|
if (!standaloneProp) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
if (!hasImports) {
|
|
89
|
+
const standaloneFalseProperty = ts__default["default"].factory.createPropertyAssignment('standalone', ts__default["default"].factory.createFalse());
|
|
90
|
+
newProperties = [...properties, standaloneFalseProperty];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (standaloneProp.value === ts__default["default"].SyntaxKind.TrueKeyword && hasImports) {
|
|
94
|
+
// To keep the migration idempotent, we'll only remove the standalone prop when there are imports
|
|
95
|
+
newProperties = properties.filter((p) => p !== standaloneProp.property);
|
|
88
96
|
}
|
|
89
|
-
else if (standaloneProp.value === ts__default["default"].SyntaxKind.TrueKeyword) ;
|
|
90
97
|
if (newProperties) {
|
|
91
98
|
// At this point we know that we need to add standalone: false or
|
|
92
99
|
// remove an existing standalone: true property.
|
|
@@ -123,6 +130,19 @@ function getStandaloneProperty(properties) {
|
|
|
123
130
|
function isStandaloneProperty(prop) {
|
|
124
131
|
return (ts__default["default"].isPropertyAssignment(prop) && ts__default["default"].isIdentifier(prop.name) && prop.name.text === 'standalone');
|
|
125
132
|
}
|
|
133
|
+
function decoratorHasImports(decoratorArgument) {
|
|
134
|
+
for (const prop of decoratorArgument.properties) {
|
|
135
|
+
if (ts__default["default"].isPropertyAssignment(prop) &&
|
|
136
|
+
ts__default["default"].isIdentifier(prop.name) &&
|
|
137
|
+
prop.name.text === 'imports') {
|
|
138
|
+
if (prop.initializer.kind === ts__default["default"].SyntaxKind.ArrayLiteralExpression ||
|
|
139
|
+
prop.initializer.kind === ts__default["default"].SyntaxKind.Identifier) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
126
146
|
|
|
127
147
|
function migrate() {
|
|
128
148
|
return async (tree) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-
|
|
3
|
+
* @license Angular v19.0.0-rc.0
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -10,12 +10,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
10
10
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
var p = require('path');
|
|
13
|
-
var compiler_host = require('./compiler_host-
|
|
13
|
+
var compiler_host = require('./compiler_host-f54f8309.js');
|
|
14
14
|
var ts = require('typescript');
|
|
15
|
-
var
|
|
16
|
-
var imports = require('./imports-
|
|
17
|
-
var
|
|
18
|
-
require('./
|
|
15
|
+
var ng_decorators = require('./ng_decorators-3ad437d2.js');
|
|
16
|
+
var imports = require('./imports-44987700.js');
|
|
17
|
+
var nodes = require('./nodes-ffdce442.js');
|
|
18
|
+
var leading_space = require('./leading_space-6e7a8ec6.js');
|
|
19
|
+
require('./checker-2451e7c5.js');
|
|
19
20
|
require('os');
|
|
20
21
|
require('fs');
|
|
21
22
|
require('module');
|
|
@@ -105,7 +106,7 @@ function analyzeFile(sourceFile, localTypeChecker) {
|
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
else if (ts__default["default"].isClassDeclaration(node)) {
|
|
108
|
-
const decorators =
|
|
109
|
+
const decorators = ng_decorators.getAngularDecorators(localTypeChecker, ts__default["default"].getDecorators(node) || []);
|
|
109
110
|
const supportsDI = decorators.some((dec) => DECORATORS_SUPPORTING_DI.has(dec.name));
|
|
110
111
|
const constructorNode = node.members.find((member) => ts__default["default"].isConstructorDeclaration(member) &&
|
|
111
112
|
member.body != null &&
|
|
@@ -145,7 +146,7 @@ function getConstructorUnusedParameters(declaration, localTypeChecker, removedSt
|
|
|
145
146
|
}
|
|
146
147
|
declaration.body.forEachChild(function walk(node) {
|
|
147
148
|
// Don't descend into statements that were removed already.
|
|
148
|
-
if (
|
|
149
|
+
if (ts__default["default"].isStatement(node) && removedStatements.has(node)) {
|
|
149
150
|
return;
|
|
150
151
|
}
|
|
151
152
|
if (!ts__default["default"].isIdentifier(node) || !topLevelParameterNames.has(node.text)) {
|
|
@@ -286,7 +287,8 @@ function findSuperCall(root) {
|
|
|
286
287
|
* @param localTypeChecker Type checker scoped to the current file.
|
|
287
288
|
*/
|
|
288
289
|
function findUninitializedPropertiesToCombine(node, constructor, localTypeChecker) {
|
|
289
|
-
let
|
|
290
|
+
let toCombine = null;
|
|
291
|
+
let toHoist = [];
|
|
290
292
|
const membersToDeclarations = new Map();
|
|
291
293
|
for (const member of node.members) {
|
|
292
294
|
if (ts__default["default"].isPropertyDeclaration(member) &&
|
|
@@ -296,20 +298,40 @@ function findUninitializedPropertiesToCombine(node, constructor, localTypeChecke
|
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
300
|
if (membersToDeclarations.size === 0) {
|
|
299
|
-
return
|
|
301
|
+
return null;
|
|
300
302
|
}
|
|
301
303
|
const memberInitializers = getMemberInitializers(constructor);
|
|
302
304
|
if (memberInitializers === null) {
|
|
303
|
-
return
|
|
305
|
+
return null;
|
|
304
306
|
}
|
|
305
|
-
for (const [name,
|
|
306
|
-
if (
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
307
|
+
for (const [name, decl] of membersToDeclarations.entries()) {
|
|
308
|
+
if (memberInitializers.has(name)) {
|
|
309
|
+
const initializer = memberInitializers.get(name);
|
|
310
|
+
if (!hasLocalReferences(initializer, constructor, localTypeChecker)) {
|
|
311
|
+
toCombine = toCombine || new Map();
|
|
312
|
+
toCombine.set(membersToDeclarations.get(name), initializer);
|
|
313
|
+
}
|
|
310
314
|
}
|
|
311
|
-
|
|
312
|
-
|
|
315
|
+
else {
|
|
316
|
+
// Mark members that have no initializers and can't be combined to be hoisted above the
|
|
317
|
+
// injected members. This is either a no-op or it allows us to avoid some patterns internally
|
|
318
|
+
// like the following:
|
|
319
|
+
// ```
|
|
320
|
+
// class Foo {
|
|
321
|
+
// publicFoo: Foo;
|
|
322
|
+
// private privateFoo: Foo;
|
|
323
|
+
//
|
|
324
|
+
// constructor() {
|
|
325
|
+
// this.initializePrivateFooSomehow();
|
|
326
|
+
// this.publicFoo = this.privateFoo;
|
|
327
|
+
// }
|
|
328
|
+
// }
|
|
329
|
+
// ```
|
|
330
|
+
toHoist.push(decl);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// If no members need to be combined, none need to be hoisted either.
|
|
334
|
+
return toCombine === null ? null : { toCombine, toHoist };
|
|
313
335
|
}
|
|
314
336
|
/**
|
|
315
337
|
* Finds the expressions from the constructor that initialize class members, for example:
|
|
@@ -366,7 +388,7 @@ function getMemberInitializers(constructor) {
|
|
|
366
388
|
function hasLocalReferences(root, constructor, localTypeChecker) {
|
|
367
389
|
const sourceFile = root.getSourceFile();
|
|
368
390
|
let hasLocalRefs = false;
|
|
369
|
-
|
|
391
|
+
const walk = (node) => {
|
|
370
392
|
// Stop searching if we know that it has local references.
|
|
371
393
|
if (hasLocalRefs) {
|
|
372
394
|
return;
|
|
@@ -396,7 +418,8 @@ function hasLocalReferences(root, constructor, localTypeChecker) {
|
|
|
396
418
|
if (!hasLocalRefs) {
|
|
397
419
|
node.forEachChild(walk);
|
|
398
420
|
}
|
|
399
|
-
}
|
|
421
|
+
};
|
|
422
|
+
walk(root);
|
|
400
423
|
return hasLocalRefs;
|
|
401
424
|
}
|
|
402
425
|
/**
|
|
@@ -444,21 +467,13 @@ function migrateFile(sourceFile, options) {
|
|
|
444
467
|
const printer = ts__default["default"].createPrinter();
|
|
445
468
|
const tracker = new compiler_host.ChangeTracker(printer);
|
|
446
469
|
analysis.classes.forEach(({ node, constructor, superCall }) => {
|
|
447
|
-
|
|
470
|
+
const memberIndentation = leading_space.getLeadingLineWhitespaceOfNode(node.members[0]);
|
|
471
|
+
const prependToClass = [];
|
|
472
|
+
const removedStatements = new Set();
|
|
448
473
|
if (options._internalCombineMemberInitializers) {
|
|
449
|
-
|
|
450
|
-
const statement = nodes.closestNode(initializer, ts__default["default"].isStatement);
|
|
451
|
-
if (!statement) {
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
const newProperty = ts__default["default"].factory.createPropertyDeclaration(cloneModifiers(property.modifiers), cloneName(property.name), property.questionToken, property.type, initializer);
|
|
455
|
-
tracker.replaceText(statement.getSourceFile(), statement.getFullStart(), statement.getFullWidth(), '');
|
|
456
|
-
tracker.replaceNode(property, newProperty);
|
|
457
|
-
removedStatements = removedStatements || new Set();
|
|
458
|
-
removedStatements.add(statement);
|
|
459
|
-
});
|
|
474
|
+
applyInternalOnlyChanges(node, constructor, localTypeChecker, tracker, printer, removedStatements, prependToClass, memberIndentation);
|
|
460
475
|
}
|
|
461
|
-
migrateClass(node, constructor, superCall, options, removedStatements, localTypeChecker, printer, tracker);
|
|
476
|
+
migrateClass(node, constructor, superCall, options, memberIndentation, prependToClass, removedStatements, localTypeChecker, printer, tracker);
|
|
462
477
|
});
|
|
463
478
|
DI_PARAM_SYMBOLS.forEach((name) => {
|
|
464
479
|
// Both zero and undefined are fine here.
|
|
@@ -474,12 +489,14 @@ function migrateFile(sourceFile, options) {
|
|
|
474
489
|
* @param constructor Reference to the class' constructor node.
|
|
475
490
|
* @param superCall Reference to the constructor's `super()` call, if any.
|
|
476
491
|
* @param options Options used to configure the migration.
|
|
492
|
+
* @param memberIndentation Indentation string of the members of the class.
|
|
493
|
+
* @param prependToClass Text that should be prepended to the class.
|
|
477
494
|
* @param removedStatements Statements that have been removed from the constructor already.
|
|
478
495
|
* @param localTypeChecker Type checker set up for the specific file.
|
|
479
496
|
* @param printer Printer used to output AST nodes as strings.
|
|
480
497
|
* @param tracker Object keeping track of the changes made to the file.
|
|
481
498
|
*/
|
|
482
|
-
function migrateClass(node, constructor, superCall, options, removedStatements, localTypeChecker, printer, tracker) {
|
|
499
|
+
function migrateClass(node, constructor, superCall, options, memberIndentation, prependToClass, removedStatements, localTypeChecker, printer, tracker) {
|
|
483
500
|
const isAbstract = !!node.modifiers?.some((m) => m.kind === ts__default["default"].SyntaxKind.AbstractKeyword);
|
|
484
501
|
// Don't migrate abstract classes by default, because
|
|
485
502
|
// their parameters aren't guaranteed to be injectable.
|
|
@@ -491,20 +508,17 @@ function migrateClass(node, constructor, superCall, options, removedStatements,
|
|
|
491
508
|
const superParameters = superCall
|
|
492
509
|
? getSuperParameters(constructor, superCall, localTypeChecker)
|
|
493
510
|
: null;
|
|
494
|
-
const
|
|
495
|
-
const
|
|
496
|
-
const innerReference = superCall ||
|
|
497
|
-
constructor.body?.statements.find((statement) => !removedStatements?.has(statement)) ||
|
|
498
|
-
constructor;
|
|
511
|
+
const removedStatementCount = removedStatements.size;
|
|
512
|
+
const firstConstructorStatement = constructor.body?.statements.find((statement) => !removedStatements.has(statement));
|
|
513
|
+
const innerReference = superCall || firstConstructorStatement || constructor;
|
|
499
514
|
const innerIndentation = leading_space.getLeadingLineWhitespaceOfNode(innerReference);
|
|
500
|
-
const propsToAdd = [];
|
|
501
515
|
const prependToConstructor = [];
|
|
502
516
|
const afterSuper = [];
|
|
503
517
|
const removedMembers = new Set();
|
|
504
518
|
for (const param of constructor.parameters) {
|
|
505
519
|
const usedInSuper = superParameters !== null && superParameters.has(param);
|
|
506
520
|
const usedInConstructor = !unusedParameters.has(param);
|
|
507
|
-
migrateParameter(param, options, localTypeChecker, printer, tracker, superCall, usedInSuper, usedInConstructor, memberIndentation, innerIndentation, prependToConstructor,
|
|
521
|
+
migrateParameter(param, options, localTypeChecker, printer, tracker, superCall, usedInSuper, usedInConstructor, memberIndentation, innerIndentation, prependToConstructor, prependToClass, afterSuper);
|
|
508
522
|
}
|
|
509
523
|
// Delete all of the constructor overloads since below we're either going to
|
|
510
524
|
// remove the implementation, or we're going to delete all of the parameters.
|
|
@@ -524,11 +538,16 @@ function migrateClass(node, constructor, superCall, options, removedStatements,
|
|
|
524
538
|
// We always do this no matter what is passed into `backwardsCompatibleConstructors`.
|
|
525
539
|
stripConstructorParameters(constructor, tracker);
|
|
526
540
|
if (prependToConstructor.length > 0) {
|
|
527
|
-
tracker.insertText(sourceFile, innerReference.getFullStart(), `\n${prependToConstructor.join('\n')}\n`);
|
|
541
|
+
tracker.insertText(sourceFile, (firstConstructorStatement || innerReference).getFullStart(), `\n${prependToConstructor.join('\n')}\n`);
|
|
528
542
|
}
|
|
529
543
|
}
|
|
530
544
|
if (afterSuper.length > 0 && superCall !== null) {
|
|
531
|
-
|
|
545
|
+
// Note that if we can, we should insert before the next statement after the `super` call,
|
|
546
|
+
// rather than after the end of it. Otherwise the string buffering implementation may drop
|
|
547
|
+
// the text if the statement after the `super` call is being deleted. This appears to be because
|
|
548
|
+
// the full start of the next statement appears to always be the end of the `super` call plus 1.
|
|
549
|
+
const nextStatement = getNextPreservedStatement(superCall, removedStatements);
|
|
550
|
+
tracker.insertText(sourceFile, nextStatement ? nextStatement.getFullStart() : superCall.getEnd() + 1, `\n${afterSuper.join('\n')}\n`);
|
|
532
551
|
}
|
|
533
552
|
// Need to resolve this once all constructor signatures have been removed.
|
|
534
553
|
const memberReference = node.members.find((m) => !removedMembers.has(m)) || node.members[0];
|
|
@@ -539,19 +558,19 @@ function migrateClass(node, constructor, superCall, options, removedStatements,
|
|
|
539
558
|
`${memberIndentation}constructor(...args: unknown[]);`;
|
|
540
559
|
// The new signature always has to be right before the constructor implementation.
|
|
541
560
|
if (memberReference === constructor) {
|
|
542
|
-
|
|
561
|
+
prependToClass.push(extraSignature);
|
|
543
562
|
}
|
|
544
563
|
else {
|
|
545
564
|
tracker.insertText(sourceFile, constructor.getFullStart(), '\n' + extraSignature);
|
|
546
565
|
}
|
|
547
566
|
}
|
|
548
|
-
if (
|
|
567
|
+
if (prependToClass.length > 0) {
|
|
549
568
|
if (removedMembers.size === node.members.length) {
|
|
550
|
-
tracker.insertText(sourceFile, constructor.getEnd() + 1, `${
|
|
569
|
+
tracker.insertText(sourceFile, constructor.getEnd() + 1, `${prependToClass.join('\n')}\n`);
|
|
551
570
|
}
|
|
552
571
|
else {
|
|
553
572
|
// Insert the new properties after the first member that hasn't been deleted.
|
|
554
|
-
tracker.insertText(sourceFile, memberReference.getFullStart(), `\n${
|
|
573
|
+
tracker.insertText(sourceFile, memberReference.getFullStart(), `\n${prependToClass.join('\n')}\n`);
|
|
555
574
|
}
|
|
556
575
|
}
|
|
557
576
|
}
|
|
@@ -635,7 +654,7 @@ function migrateParameter(node, options, localTypeChecker, printer, tracker, sup
|
|
|
635
654
|
function createInjectReplacementCall(param, options, localTypeChecker, printer, tracker) {
|
|
636
655
|
const moduleName = '@angular/core';
|
|
637
656
|
const sourceFile = param.getSourceFile();
|
|
638
|
-
const decorators =
|
|
657
|
+
const decorators = ng_decorators.getAngularDecorators(localTypeChecker, ts__default["default"].getDecorators(param) || []);
|
|
639
658
|
const literalProps = [];
|
|
640
659
|
const type = param.type;
|
|
641
660
|
let injectedType = '';
|
|
@@ -877,6 +896,61 @@ function canRemoveConstructor(options, constructor, removedStatementCount, super
|
|
|
877
896
|
return (statementCount === 0 ||
|
|
878
897
|
(statementCount === 1 && superCall !== null && superCall.arguments.length === 0));
|
|
879
898
|
}
|
|
899
|
+
/**
|
|
900
|
+
* Gets the next statement after a node that *won't* be deleted by the migration.
|
|
901
|
+
* @param startNode Node from which to start the search.
|
|
902
|
+
* @param removedStatements Statements that have been removed by the migration.
|
|
903
|
+
* @returns
|
|
904
|
+
*/
|
|
905
|
+
function getNextPreservedStatement(startNode, removedStatements) {
|
|
906
|
+
const body = nodes.closestNode(startNode, ts__default["default"].isBlock);
|
|
907
|
+
const closestStatement = nodes.closestNode(startNode, ts__default["default"].isStatement);
|
|
908
|
+
if (body === null || closestStatement === null) {
|
|
909
|
+
return null;
|
|
910
|
+
}
|
|
911
|
+
const index = body.statements.indexOf(closestStatement);
|
|
912
|
+
if (index === -1) {
|
|
913
|
+
return null;
|
|
914
|
+
}
|
|
915
|
+
for (let i = index + 1; i < body.statements.length; i++) {
|
|
916
|
+
if (!removedStatements.has(body.statements[i])) {
|
|
917
|
+
return body.statements[i];
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Applies the internal-specific migrations to a class.
|
|
924
|
+
* @param node Class being migrated.
|
|
925
|
+
* @param constructor The migrated class' constructor.
|
|
926
|
+
* @param localTypeChecker File-specific type checker.
|
|
927
|
+
* @param tracker Object keeping track of the changes.
|
|
928
|
+
* @param printer Printer used to output AST nodes as text.
|
|
929
|
+
* @param removedStatements Statements that have been removed by the migration.
|
|
930
|
+
* @param prependToClass Text that will be prepended to a class.
|
|
931
|
+
* @param memberIndentation Indentation string of the class' members.
|
|
932
|
+
*/
|
|
933
|
+
function applyInternalOnlyChanges(node, constructor, localTypeChecker, tracker, printer, removedStatements, prependToClass, memberIndentation) {
|
|
934
|
+
const result = findUninitializedPropertiesToCombine(node, constructor, localTypeChecker);
|
|
935
|
+
result?.toCombine.forEach((initializer, property) => {
|
|
936
|
+
const statement = nodes.closestNode(initializer, ts__default["default"].isStatement);
|
|
937
|
+
if (!statement) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
const newProperty = ts__default["default"].factory.createPropertyDeclaration(cloneModifiers(property.modifiers), cloneName(property.name), property.questionToken, property.type, initializer);
|
|
941
|
+
tracker.replaceText(statement.getSourceFile(), statement.getFullStart(), statement.getFullWidth(), '');
|
|
942
|
+
tracker.replaceNode(property, newProperty);
|
|
943
|
+
removedStatements.add(statement);
|
|
944
|
+
});
|
|
945
|
+
result?.toHoist.forEach((decl) => {
|
|
946
|
+
prependToClass.push(memberIndentation + printer.printNode(ts__default["default"].EmitHint.Unspecified, decl, decl.getSourceFile()));
|
|
947
|
+
tracker.replaceText(decl.getSourceFile(), decl.getFullStart(), decl.getFullWidth(), '');
|
|
948
|
+
});
|
|
949
|
+
// If we added any hoisted properties, separate them visually with a new line.
|
|
950
|
+
if (prependToClass.length > 0) {
|
|
951
|
+
prependToClass.push('');
|
|
952
|
+
}
|
|
953
|
+
}
|
|
880
954
|
|
|
881
955
|
function migrate(options) {
|
|
882
956
|
return async (tree) => {
|