@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,26 +1,21 @@
|
|
|
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
|
-
var checker = require('./checker-
|
|
9
|
+
var checker = require('./checker-BHb19MHt.js');
|
|
10
10
|
var ts = require('typescript');
|
|
11
11
|
require('os');
|
|
12
12
|
var assert = require('assert');
|
|
13
|
-
var index = require('./index-
|
|
14
|
-
var
|
|
15
|
-
var leading_space = require('./leading_space-
|
|
16
|
-
require('./
|
|
13
|
+
var index = require('./index-BL9kAIe5.js');
|
|
14
|
+
var run_in_devkit = require('./run_in_devkit-C0JPtK2u.js');
|
|
15
|
+
var leading_space = require('./leading_space-D9nQ8UQC.js');
|
|
16
|
+
require('./index-I8VbxQcO.js');
|
|
17
17
|
require('path');
|
|
18
18
|
|
|
19
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
20
|
-
|
|
21
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
22
|
-
var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert);
|
|
23
|
-
|
|
24
19
|
/**
|
|
25
20
|
* Reasons why a field cannot be migrated.
|
|
26
21
|
*
|
|
@@ -557,11 +552,11 @@ class SpyOnFieldPattern {
|
|
|
557
552
|
this.fields = fields;
|
|
558
553
|
}
|
|
559
554
|
detect(node) {
|
|
560
|
-
if (
|
|
561
|
-
|
|
555
|
+
if (ts.isCallExpression(node) &&
|
|
556
|
+
ts.isIdentifier(node.expression) &&
|
|
562
557
|
node.expression.text === 'spyOn' &&
|
|
563
558
|
node.arguments.length === 2 &&
|
|
564
|
-
|
|
559
|
+
ts.isStringLiteralLike(node.arguments[1])) {
|
|
565
560
|
const spyTargetType = this.checker.getTypeAtLocation(node.arguments[0]);
|
|
566
561
|
const spyProperty = spyTargetType.getProperty(node.arguments[1].text);
|
|
567
562
|
if (spyProperty === undefined) {
|
|
@@ -593,19 +588,19 @@ function checkIncompatiblePatterns(inheritanceGraph, checker$1, groupedTsAstVisi
|
|
|
593
588
|
const inputClassSymbolsToClass = new Map();
|
|
594
589
|
for (const knownFieldClass of getAllClassesWithKnownFields()) {
|
|
595
590
|
const classSymbol = checker$1.getTypeAtLocation(knownFieldClass).symbol;
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
591
|
+
assert(classSymbol != null, 'Expected a symbol to exist for the container of known field class.');
|
|
592
|
+
assert(classSymbol.valueDeclaration !== undefined, 'Expected declaration to exist for known field class.');
|
|
593
|
+
assert(ts.isClassDeclaration(classSymbol.valueDeclaration), 'Expected declaration to be a class.');
|
|
599
594
|
// track class symbol for derived class checks.
|
|
600
595
|
inputClassSymbolsToClass.set(classSymbol, classSymbol.valueDeclaration);
|
|
601
596
|
}
|
|
602
597
|
const spyOnPattern = new SpyOnFieldPattern(checker$1, fields);
|
|
603
598
|
const visitor = (node) => {
|
|
604
599
|
// Check for manual class instantiations.
|
|
605
|
-
if (
|
|
600
|
+
if (ts.isNewExpression(node) && ts.isIdentifier(checker.unwrapExpression(node.expression))) {
|
|
606
601
|
let newTarget = checker$1.getSymbolAtLocation(checker.unwrapExpression(node.expression));
|
|
607
602
|
// Plain identifier references can point to alias symbols (e.g. imports).
|
|
608
|
-
if (newTarget !== undefined && newTarget.flags &
|
|
603
|
+
if (newTarget !== undefined && newTarget.flags & ts.SymbolFlags.Alias) {
|
|
609
604
|
newTarget = checker$1.getAliasedSymbol(newTarget);
|
|
610
605
|
}
|
|
611
606
|
if (newTarget && inputClassSymbolsToClass.has(newTarget)) {
|
|
@@ -620,11 +615,11 @@ function checkIncompatiblePatterns(inheritanceGraph, checker$1, groupedTsAstVisi
|
|
|
620
615
|
// class inherits a non-input member with the same name.
|
|
621
616
|
// Suddenly the derived class changes its signature, but the base class may not.
|
|
622
617
|
problematicReferencesCheck: if (insidePropertyDeclaration !== null &&
|
|
623
|
-
|
|
618
|
+
ts.isIdentifier(node) &&
|
|
624
619
|
insidePropertyDeclaration.parent.heritageClauses !== undefined) {
|
|
625
620
|
let newTarget = checker$1.getSymbolAtLocation(checker.unwrapExpression(node));
|
|
626
621
|
// Plain identifier references can point to alias symbols (e.g. imports).
|
|
627
|
-
if (newTarget !== undefined && newTarget.flags &
|
|
622
|
+
if (newTarget !== undefined && newTarget.flags & ts.SymbolFlags.Alias) {
|
|
628
623
|
newTarget = checker$1.getAliasedSymbol(newTarget);
|
|
629
624
|
}
|
|
630
625
|
if (newTarget && inputClassSymbolsToClass.has(newTarget)) {
|
|
@@ -750,19 +745,19 @@ class InheritanceGraph {
|
|
|
750
745
|
expensivePopulate(files) {
|
|
751
746
|
for (const file of files) {
|
|
752
747
|
const visitor = (node) => {
|
|
753
|
-
if ((
|
|
748
|
+
if ((ts.isClassLike(node) || ts.isInterfaceDeclaration(node)) &&
|
|
754
749
|
node.heritageClauses !== undefined) {
|
|
755
750
|
const heritageTypes = getInheritedTypes(node, this.checker);
|
|
756
751
|
const parents = heritageTypes
|
|
757
752
|
// Interfaces participate in the graph and are not "value declarations".
|
|
758
753
|
// Also, symbol may be undefined for unresolvable nodes.
|
|
759
754
|
.map((t) => (t.symbol ? t.symbol.declarations?.[0] : undefined))
|
|
760
|
-
.filter((d) => d !== undefined && (
|
|
755
|
+
.filter((d) => d !== undefined && (ts.isClassLike(d) || ts.isInterfaceDeclaration(d)));
|
|
761
756
|
this.registerClass(node, parents);
|
|
762
757
|
}
|
|
763
|
-
|
|
758
|
+
ts.forEachChild(node, visitor);
|
|
764
759
|
};
|
|
765
|
-
|
|
760
|
+
ts.forEachChild(file, visitor);
|
|
766
761
|
}
|
|
767
762
|
return this;
|
|
768
763
|
}
|
|
@@ -796,17 +791,17 @@ class GroupedTsAstVisitor {
|
|
|
796
791
|
for (const v of this.visitors) {
|
|
797
792
|
v(node);
|
|
798
793
|
}
|
|
799
|
-
if (
|
|
794
|
+
if (ts.isPropertyDeclaration(node)) {
|
|
800
795
|
this.state.insidePropertyDeclaration = node;
|
|
801
|
-
|
|
796
|
+
ts.forEachChild(node, visitor);
|
|
802
797
|
this.state.insidePropertyDeclaration = null;
|
|
803
798
|
}
|
|
804
799
|
else {
|
|
805
|
-
|
|
800
|
+
ts.forEachChild(node, visitor);
|
|
806
801
|
}
|
|
807
802
|
};
|
|
808
803
|
for (const file of this.files) {
|
|
809
|
-
|
|
804
|
+
ts.forEachChild(file, visitor);
|
|
810
805
|
}
|
|
811
806
|
for (const doneFn of this.doneFns) {
|
|
812
807
|
doneFn();
|
|
@@ -836,13 +831,13 @@ class GroupedTsAstVisitor {
|
|
|
836
831
|
* would then have other derived classes as well, it would propagate the status.
|
|
837
832
|
*/
|
|
838
833
|
function checkInheritanceOfKnownFields(inheritanceGraph, metaRegistry, fields, opts) {
|
|
839
|
-
const allInputClasses = Array.from(inheritanceGraph.allClassesInInheritance).filter((t) =>
|
|
834
|
+
const allInputClasses = Array.from(inheritanceGraph.allClassesInInheritance).filter((t) => ts.isClassDeclaration(t) && opts.isClassWithKnownFields(t));
|
|
840
835
|
for (const inputClass of allInputClasses) {
|
|
841
836
|
// Note: Class parents of `inputClass` were already checked by
|
|
842
837
|
// the previous iterations (given the reverse topological sort)—
|
|
843
838
|
// hence it's safe to assume that incompatibility of parent classes will
|
|
844
839
|
// not change again, at a later time.
|
|
845
|
-
|
|
840
|
+
assert(ts.isClassDeclaration(inputClass), 'Expected input graph node to be always a class.');
|
|
846
841
|
const classFields = opts.getFieldsForClass(inputClass);
|
|
847
842
|
const inputFieldNamesFromMetadataArray = new Set();
|
|
848
843
|
// Iterate through derived class chains and determine all inputs that are overridden
|
|
@@ -850,7 +845,7 @@ function checkInheritanceOfKnownFields(inheritanceGraph, metaRegistry, fields, o
|
|
|
850
845
|
// potential similar class input as incompatible— because those cannot be migrated.
|
|
851
846
|
if (metaRegistry !== null) {
|
|
852
847
|
for (const derivedClasses of inheritanceGraph.traceDerivedClasses(inputClass)) {
|
|
853
|
-
const derivedMeta =
|
|
848
|
+
const derivedMeta = ts.isClassDeclaration(derivedClasses) && derivedClasses.name !== undefined
|
|
854
849
|
? metaRegistry.getDirectiveMetadata(new checker.Reference(derivedClasses))
|
|
855
850
|
: null;
|
|
856
851
|
if (derivedMeta !== null && derivedMeta.inputFieldNamesFromMetadataArray !== null) {
|
|
@@ -865,7 +860,7 @@ function checkInheritanceOfKnownFields(inheritanceGraph, metaRegistry, fields, o
|
|
|
865
860
|
// If we discover a derived, input re-declared via class metadata, then it
|
|
866
861
|
// will cause conflicts as we cannot migrate it/ nor mark it as signal-based.
|
|
867
862
|
if (fieldDescr.node.name !== undefined &&
|
|
868
|
-
(
|
|
863
|
+
(ts.isIdentifier(fieldDescr.node.name) || ts.isStringLiteralLike(fieldDescr.node.name)) &&
|
|
869
864
|
inputFieldNamesFromMetadataArray.has(fieldDescr.node.name.text)) {
|
|
870
865
|
fields.captureUnknownDerivedField(fieldDescr);
|
|
871
866
|
}
|
|
@@ -906,7 +901,7 @@ function removeFromUnionIfPossible(union, filter) {
|
|
|
906
901
|
if (filtered.length === 1) {
|
|
907
902
|
return filtered[0];
|
|
908
903
|
}
|
|
909
|
-
return
|
|
904
|
+
return ts.factory.updateUnionTypeNode(union, ts.factory.createNodeArray(filtered));
|
|
910
905
|
}
|
|
911
906
|
|
|
912
907
|
/**
|
|
@@ -917,7 +912,7 @@ function removeFromUnionIfPossible(union, filter) {
|
|
|
917
912
|
*/
|
|
918
913
|
function insertPrecedingLine(node, info, text) {
|
|
919
914
|
const leadingSpace = leading_space.getLeadingLineWhitespaceOfNode(node);
|
|
920
|
-
return new
|
|
915
|
+
return new run_in_devkit.Replacement(run_in_devkit.projectFile(node.getSourceFile(), info), new run_in_devkit.TextUpdate({
|
|
921
916
|
position: node.getStart(),
|
|
922
917
|
end: node.getStart(),
|
|
923
918
|
toInsert: `${text}\n${leadingSpace}`,
|
|
@@ -1109,7 +1104,7 @@ const ReservedMarker = Symbol();
|
|
|
1109
1104
|
*/
|
|
1110
1105
|
function isIdentifierFreeInScope(name, location) {
|
|
1111
1106
|
const startContainer = findClosestParentLocalsContainer(location);
|
|
1112
|
-
|
|
1107
|
+
assert(startContainer !== undefined, 'Expecting a locals container.');
|
|
1113
1108
|
// Traverse up and check for potential collisions.
|
|
1114
1109
|
let container = startContainer;
|
|
1115
1110
|
let firstNextContainer = undefined;
|
|
@@ -1136,7 +1131,7 @@ function isIdentifierFreeInScope(name, location) {
|
|
|
1136
1131
|
}
|
|
1137
1132
|
/** Finds the closest parent locals container. */
|
|
1138
1133
|
function findClosestParentLocalsContainer(node) {
|
|
1139
|
-
return
|
|
1134
|
+
return ts.findAncestor(node, isLocalsContainer);
|
|
1140
1135
|
}
|
|
1141
1136
|
/** Whether the given identifier is free in the given locals container. */
|
|
1142
1137
|
function isIdentifierFreeInContainer(name, container) {
|
|
@@ -1148,7 +1143,7 @@ function isIdentifierFreeInContainer(name, container) {
|
|
|
1148
1143
|
// typescript/stable/src/compiler/emitter.ts;l=5436;rcl=651008033
|
|
1149
1144
|
const local = container.locals.get(name);
|
|
1150
1145
|
return (local !== ReservedMarker &&
|
|
1151
|
-
!(local.flags & (
|
|
1146
|
+
!(local.flags & (ts.SymbolFlags.Value | ts.SymbolFlags.ExportValue | ts.SymbolFlags.Alias)));
|
|
1152
1147
|
}
|
|
1153
1148
|
/**
|
|
1154
1149
|
* Whether the given node can contain local variables.
|
|
@@ -1158,36 +1153,36 @@ function isIdentifierFreeInContainer(name, container) {
|
|
|
1158
1153
|
*/
|
|
1159
1154
|
function isLocalsContainer(node) {
|
|
1160
1155
|
switch (node.kind) {
|
|
1161
|
-
case
|
|
1162
|
-
case
|
|
1163
|
-
case
|
|
1164
|
-
case
|
|
1165
|
-
case
|
|
1166
|
-
case
|
|
1167
|
-
case
|
|
1168
|
-
case
|
|
1169
|
-
case
|
|
1170
|
-
case
|
|
1171
|
-
case
|
|
1172
|
-
case
|
|
1173
|
-
case
|
|
1174
|
-
case
|
|
1175
|
-
case
|
|
1176
|
-
case
|
|
1177
|
-
case
|
|
1178
|
-
case
|
|
1179
|
-
case
|
|
1180
|
-
case
|
|
1181
|
-
case
|
|
1182
|
-
case
|
|
1183
|
-
case
|
|
1184
|
-
case
|
|
1185
|
-
case
|
|
1186
|
-
case
|
|
1187
|
-
case
|
|
1188
|
-
case
|
|
1189
|
-
case
|
|
1190
|
-
case
|
|
1156
|
+
case ts.SyntaxKind.ArrowFunction:
|
|
1157
|
+
case ts.SyntaxKind.Block:
|
|
1158
|
+
case ts.SyntaxKind.CallSignature:
|
|
1159
|
+
case ts.SyntaxKind.CaseBlock:
|
|
1160
|
+
case ts.SyntaxKind.CatchClause:
|
|
1161
|
+
case ts.SyntaxKind.ClassStaticBlockDeclaration:
|
|
1162
|
+
case ts.SyntaxKind.ConditionalType:
|
|
1163
|
+
case ts.SyntaxKind.Constructor:
|
|
1164
|
+
case ts.SyntaxKind.ConstructorType:
|
|
1165
|
+
case ts.SyntaxKind.ConstructSignature:
|
|
1166
|
+
case ts.SyntaxKind.ForStatement:
|
|
1167
|
+
case ts.SyntaxKind.ForInStatement:
|
|
1168
|
+
case ts.SyntaxKind.ForOfStatement:
|
|
1169
|
+
case ts.SyntaxKind.FunctionDeclaration:
|
|
1170
|
+
case ts.SyntaxKind.FunctionExpression:
|
|
1171
|
+
case ts.SyntaxKind.FunctionType:
|
|
1172
|
+
case ts.SyntaxKind.GetAccessor:
|
|
1173
|
+
case ts.SyntaxKind.IndexSignature:
|
|
1174
|
+
case ts.SyntaxKind.JSDocCallbackTag:
|
|
1175
|
+
case ts.SyntaxKind.JSDocEnumTag:
|
|
1176
|
+
case ts.SyntaxKind.JSDocFunctionType:
|
|
1177
|
+
case ts.SyntaxKind.JSDocSignature:
|
|
1178
|
+
case ts.SyntaxKind.JSDocTypedefTag:
|
|
1179
|
+
case ts.SyntaxKind.MappedType:
|
|
1180
|
+
case ts.SyntaxKind.MethodDeclaration:
|
|
1181
|
+
case ts.SyntaxKind.MethodSignature:
|
|
1182
|
+
case ts.SyntaxKind.ModuleDeclaration:
|
|
1183
|
+
case ts.SyntaxKind.SetAccessor:
|
|
1184
|
+
case ts.SyntaxKind.SourceFile:
|
|
1185
|
+
case ts.SyntaxKind.TypeAliasDeclaration:
|
|
1191
1186
|
return true;
|
|
1192
1187
|
default:
|
|
1193
1188
|
return false;
|
|
@@ -1252,26 +1247,26 @@ function createNewBlockToInsertVariable(node, file, toInsert) {
|
|
|
1252
1247
|
// For indentation, we traverse up and find the earliest statement.
|
|
1253
1248
|
// This node is most of the time a good candidate for acceptable
|
|
1254
1249
|
// indentation of a new block.
|
|
1255
|
-
const spacingNode =
|
|
1256
|
-
const { character } =
|
|
1250
|
+
const spacingNode = ts.findAncestor(node, ts.isStatement) ?? node.parent;
|
|
1251
|
+
const { character } = ts.getLineAndCharacterOfPosition(sf, spacingNode.getStart());
|
|
1257
1252
|
const blockSpace = ' '.repeat(character);
|
|
1258
1253
|
const contentSpace = ' '.repeat(character + 2);
|
|
1259
1254
|
return [
|
|
1260
1255
|
// Delete leading whitespace of the concise body.
|
|
1261
|
-
new
|
|
1256
|
+
new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
1262
1257
|
position: node.body.getFullStart(),
|
|
1263
1258
|
end: node.body.getStart(),
|
|
1264
1259
|
toInsert: '',
|
|
1265
1260
|
})),
|
|
1266
1261
|
// Insert leading block braces, and `toInsert` content.
|
|
1267
1262
|
// Wrap the previous expression in a return now.
|
|
1268
|
-
new
|
|
1263
|
+
new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
1269
1264
|
position: node.body.getStart(),
|
|
1270
1265
|
end: node.body.getStart(),
|
|
1271
1266
|
toInsert: ` {\n${contentSpace}${toInsert}\n${contentSpace}return `,
|
|
1272
1267
|
})),
|
|
1273
1268
|
// Add trailing brace.
|
|
1274
|
-
new
|
|
1269
|
+
new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
1275
1270
|
position: node.body.getEnd(),
|
|
1276
1271
|
end: node.body.getEnd(),
|
|
1277
1272
|
toInsert: `;\n${blockSpace}}`,
|
|
@@ -1301,28 +1296,28 @@ function migrateBindingElementInputReference(tsReferencesInBindingElements, info
|
|
|
1301
1296
|
const bindingElement = reference.parent;
|
|
1302
1297
|
const bindingDecl = index.getBindingElementDeclaration(bindingElement);
|
|
1303
1298
|
const sourceFile = bindingElement.getSourceFile();
|
|
1304
|
-
const file =
|
|
1299
|
+
const file = run_in_devkit.projectFile(sourceFile, info);
|
|
1305
1300
|
const inputFieldName = bindingElement.propertyName ?? bindingElement.name;
|
|
1306
|
-
|
|
1301
|
+
assert(!ts.isObjectBindingPattern(inputFieldName) && !ts.isArrayBindingPattern(inputFieldName), 'Property of binding element cannot be another pattern.');
|
|
1307
1302
|
const tmpName = nameGenerator.generate(reference.text, bindingElement);
|
|
1308
1303
|
// Only use the temporary name, if really needed. A temporary name is needed if
|
|
1309
1304
|
// the input field simply aliased via the binding element, or if the exposed identifier
|
|
1310
1305
|
// is a string-literal like.
|
|
1311
|
-
const useTmpNameForInputField = !
|
|
1306
|
+
const useTmpNameForInputField = !ts.isObjectBindingPattern(bindingElement.name) || !ts.isIdentifier(inputFieldName);
|
|
1312
1307
|
const propertyName = useTmpNameForInputField ? inputFieldName : undefined;
|
|
1313
1308
|
const exposedName = useTmpNameForInputField
|
|
1314
|
-
?
|
|
1309
|
+
? ts.factory.createIdentifier(tmpName)
|
|
1315
1310
|
: inputFieldName;
|
|
1316
|
-
const newBindingToAccessInputField =
|
|
1311
|
+
const newBindingToAccessInputField = ts.factory.updateBindingElement(bindingElement, bindingElement.dotDotDotToken, propertyName, exposedName, bindingElement.initializer);
|
|
1317
1312
|
const temporaryVariableReplacements = insertTemporaryVariableForBindingElement(bindingDecl, file, `const ${bindingElement.name.getText()} = ${exposedName.text}();`);
|
|
1318
1313
|
if (temporaryVariableReplacements === null) {
|
|
1319
1314
|
console.error(`Could not migrate reference ${reference.text} in ${file.rootRelativePath}`);
|
|
1320
1315
|
continue;
|
|
1321
1316
|
}
|
|
1322
|
-
replacements.push(new
|
|
1317
|
+
replacements.push(new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
1323
1318
|
position: bindingElement.getStart(),
|
|
1324
1319
|
end: bindingElement.getEnd(),
|
|
1325
|
-
toInsert: printer.printNode(
|
|
1320
|
+
toInsert: printer.printNode(ts.EmitHint.Unspecified, newBindingToAccessInputField, sourceFile),
|
|
1326
1321
|
})), ...temporaryVariableReplacements);
|
|
1327
1322
|
}
|
|
1328
1323
|
}
|
|
@@ -1339,12 +1334,12 @@ function insertTemporaryVariableForBindingElement(expansionDecl, file, toInsert)
|
|
|
1339
1334
|
// The snippet is simply inserted after the variable declaration.
|
|
1340
1335
|
// The other case of a variable declaration inside a catch clause is handled
|
|
1341
1336
|
// below.
|
|
1342
|
-
if (
|
|
1343
|
-
const leadingSpaceCount =
|
|
1337
|
+
if (ts.isVariableDeclaration(expansionDecl) && ts.isVariableDeclarationList(parent)) {
|
|
1338
|
+
const leadingSpaceCount = ts.getLineAndCharacterOfPosition(sf, parent.getStart()).character;
|
|
1344
1339
|
const leadingSpace = ' '.repeat(leadingSpaceCount);
|
|
1345
1340
|
const statement = parent.parent;
|
|
1346
1341
|
return [
|
|
1347
|
-
new
|
|
1342
|
+
new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
1348
1343
|
position: statement.getEnd(),
|
|
1349
1344
|
end: statement.getEnd(),
|
|
1350
1345
|
toInsert: `\n${leadingSpace}${toInsert}`,
|
|
@@ -1359,10 +1354,10 @@ function insertTemporaryVariableForBindingElement(expansionDecl, file, toInsert)
|
|
|
1359
1354
|
const firstElementInBlock = bodyBlock.statements[0];
|
|
1360
1355
|
const spaceReferenceNode = firstElementInBlock ?? bodyBlock;
|
|
1361
1356
|
const spaceOffset = firstElementInBlock !== undefined ? 0 : 2;
|
|
1362
|
-
const leadingSpaceCount =
|
|
1357
|
+
const leadingSpaceCount = ts.getLineAndCharacterOfPosition(sf, spaceReferenceNode.getStart()).character + spaceOffset;
|
|
1363
1358
|
const leadingSpace = ' '.repeat(leadingSpaceCount);
|
|
1364
1359
|
return [
|
|
1365
|
-
new
|
|
1360
|
+
new run_in_devkit.Replacement(file, new run_in_devkit.TextUpdate({
|
|
1366
1361
|
position: bodyBlock.getStart() + 1,
|
|
1367
1362
|
end: bodyBlock.getStart() + 1,
|
|
1368
1363
|
toInsert: `\n${leadingSpace}${toInsert}`,
|
|
@@ -1371,23 +1366,23 @@ function insertTemporaryVariableForBindingElement(expansionDecl, file, toInsert)
|
|
|
1371
1366
|
}
|
|
1372
1367
|
// Other cases where we see an arrow function without a block.
|
|
1373
1368
|
// We need to create one now.
|
|
1374
|
-
if (
|
|
1369
|
+
if (ts.isArrowFunction(parent) && !ts.isBlock(parent.body)) {
|
|
1375
1370
|
return createNewBlockToInsertVariable(parent, file, toInsert);
|
|
1376
1371
|
}
|
|
1377
1372
|
return null;
|
|
1378
1373
|
}
|
|
1379
1374
|
/** Gets the body block of a given node, if available. */
|
|
1380
1375
|
function getBodyBlockOfNode(node) {
|
|
1381
|
-
if ((
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1376
|
+
if ((ts.isMethodDeclaration(node) ||
|
|
1377
|
+
ts.isFunctionDeclaration(node) ||
|
|
1378
|
+
ts.isGetAccessorDeclaration(node) ||
|
|
1379
|
+
ts.isConstructorDeclaration(node) ||
|
|
1380
|
+
ts.isArrowFunction(node)) &&
|
|
1386
1381
|
node.body !== undefined &&
|
|
1387
|
-
|
|
1382
|
+
ts.isBlock(node.body)) {
|
|
1388
1383
|
return node.body;
|
|
1389
1384
|
}
|
|
1390
|
-
if (
|
|
1385
|
+
if (ts.isCatchClause(node.parent)) {
|
|
1391
1386
|
return node.parent.block;
|
|
1392
1387
|
}
|
|
1393
1388
|
return null;
|
|
@@ -1398,25 +1393,25 @@ function getBodyBlockOfNode(node) {
|
|
|
1398
1393
|
* E.g. variables cannot be narrowed when descending into children of `node`.
|
|
1399
1394
|
*/
|
|
1400
1395
|
function isControlFlowBoundary(node) {
|
|
1401
|
-
return ((
|
|
1402
|
-
node.kind ===
|
|
1403
|
-
node.kind ===
|
|
1404
|
-
node.kind ===
|
|
1396
|
+
return ((ts.isFunctionLike(node) && !getImmediatelyInvokedFunctionExpression(node)) ||
|
|
1397
|
+
node.kind === ts.SyntaxKind.ModuleBlock ||
|
|
1398
|
+
node.kind === ts.SyntaxKind.SourceFile ||
|
|
1399
|
+
node.kind === ts.SyntaxKind.PropertyDeclaration);
|
|
1405
1400
|
}
|
|
1406
1401
|
/** Determines the current flow container of a given node. */
|
|
1407
1402
|
function getControlFlowContainer(node) {
|
|
1408
|
-
return
|
|
1403
|
+
return ts.findAncestor(node.parent, (node) => isControlFlowBoundary(node));
|
|
1409
1404
|
}
|
|
1410
1405
|
/** Checks whether the given node refers to an IIFE declaration. */
|
|
1411
1406
|
function getImmediatelyInvokedFunctionExpression(func) {
|
|
1412
|
-
if (func.kind ===
|
|
1407
|
+
if (func.kind === ts.SyntaxKind.FunctionExpression || func.kind === ts.SyntaxKind.ArrowFunction) {
|
|
1413
1408
|
let prev = func;
|
|
1414
1409
|
let parent = func.parent;
|
|
1415
|
-
while (parent.kind ===
|
|
1410
|
+
while (parent.kind === ts.SyntaxKind.ParenthesizedExpression) {
|
|
1416
1411
|
prev = parent;
|
|
1417
1412
|
parent = parent.parent;
|
|
1418
1413
|
}
|
|
1419
|
-
if (parent.kind ===
|
|
1414
|
+
if (parent.kind === ts.SyntaxKind.CallExpression &&
|
|
1420
1415
|
parent.expression === prev) {
|
|
1421
1416
|
return parent;
|
|
1422
1417
|
}
|
|
@@ -1471,10 +1466,10 @@ function traverseFlowForInterestingNodes(flow) {
|
|
|
1471
1466
|
if (flags & FlowFlags.Assignment) {
|
|
1472
1467
|
const assignment = flow;
|
|
1473
1468
|
queue.add(assignment.antecedent);
|
|
1474
|
-
if (
|
|
1469
|
+
if (ts.isVariableDeclaration(assignment.node)) {
|
|
1475
1470
|
interestingNodes.push(assignment.node.name);
|
|
1476
1471
|
}
|
|
1477
|
-
else if (
|
|
1472
|
+
else if (ts.isBindingElement(assignment.node)) {
|
|
1478
1473
|
interestingNodes.push(assignment.node.name);
|
|
1479
1474
|
}
|
|
1480
1475
|
else {
|
|
@@ -1594,7 +1589,7 @@ function analyzeControlFlow(entries, checker) {
|
|
|
1594
1589
|
for (const entry of entries) {
|
|
1595
1590
|
const { flowContainer, resultIndex } = referenceToMetadata.get(entry);
|
|
1596
1591
|
const flowPathInterestingNodes = traverseFlowForInterestingNodes(getFlowNode(entry));
|
|
1597
|
-
|
|
1592
|
+
assert(flowContainer !== null && flowPathInterestingNodes !== null, 'Expected a flow container to exist.');
|
|
1598
1593
|
const narrowPartners = getAllMatchingReferencesInFlowPath(flowPathInterestingNodes, entry, referenceToMetadata, flowContainer, checker);
|
|
1599
1594
|
if (narrowPartners.length !== 0) {
|
|
1600
1595
|
connectSharedReferences(result, narrowPartners, resultIndex);
|
|
@@ -1620,8 +1615,8 @@ function connectSharedReferences(result, flowPartners, refId) {
|
|
|
1620
1615
|
earliestPartnerId = partnerId;
|
|
1621
1616
|
}
|
|
1622
1617
|
}
|
|
1623
|
-
|
|
1624
|
-
|
|
1618
|
+
assert(earliestPartner !== null, 'Expected an earliest partner to be found.');
|
|
1619
|
+
assert(earliestPartnerId !== null, 'Expected an earliest partner to be found.');
|
|
1625
1620
|
// Earliest partner ID could be higher than `refId` in cyclic
|
|
1626
1621
|
// situations like `loop` flow nodes. We need to find the minimum
|
|
1627
1622
|
// and maximum to iterate through partners in between.
|
|
@@ -1662,14 +1657,14 @@ function connectSharedReferences(result, flowPartners, refId) {
|
|
|
1662
1657
|
if (!highestBlock) {
|
|
1663
1658
|
console.error(earliestPartnerId, refId, refFlowContainer.getText(), seenBlocks);
|
|
1664
1659
|
}
|
|
1665
|
-
|
|
1660
|
+
assert(highestBlock, 'Expected a block anchor to be found');
|
|
1666
1661
|
result[earliestPartnerId].recommendedNode = highestBlock;
|
|
1667
1662
|
}
|
|
1668
1663
|
function isPotentialInsertionAncestor(node) {
|
|
1669
1664
|
// Note: Arrow functions may not have a block, but instead use an expression
|
|
1670
1665
|
// directly. This still signifies a "block" as we can convert the concise body
|
|
1671
1666
|
// to a block.
|
|
1672
|
-
return (
|
|
1667
|
+
return (ts.isSourceFile(node) || ts.isBlock(node) || ts.isArrowFunction(node) || ts.isClassLike(node));
|
|
1673
1668
|
}
|
|
1674
1669
|
/**
|
|
1675
1670
|
* Looks through the flow path and interesting nodes to determine which
|
|
@@ -1698,7 +1693,7 @@ function getAllMatchingReferencesInFlowPath(flowPathInterestingNodes, reference,
|
|
|
1698
1693
|
* matches the given reference. If so, returns its flow ID.
|
|
1699
1694
|
*/
|
|
1700
1695
|
function findSimilarReferenceNode(start, reference, referenceToMetadata, restrainingFlowContainer, checker) {
|
|
1701
|
-
return (
|
|
1696
|
+
return (ts.forEachChild(start, function visitChild(node) {
|
|
1702
1697
|
// do not descend into control flow boundaries.
|
|
1703
1698
|
// only references sharing the same container are relevant.
|
|
1704
1699
|
// This is a performance optimization.
|
|
@@ -1706,9 +1701,9 @@ function findSimilarReferenceNode(start, reference, referenceToMetadata, restrai
|
|
|
1706
1701
|
return;
|
|
1707
1702
|
}
|
|
1708
1703
|
// If this is not a potential matching identifier, check its children.
|
|
1709
|
-
if (!
|
|
1704
|
+
if (!ts.isIdentifier(node) ||
|
|
1710
1705
|
referenceToMetadata.get(node)?.flowContainer !== restrainingFlowContainer) {
|
|
1711
|
-
return
|
|
1706
|
+
return ts.forEachChild(node, visitChild);
|
|
1712
1707
|
}
|
|
1713
1708
|
// If this refers to a different instantiation of the input reference,
|
|
1714
1709
|
// continue looking.
|
|
@@ -1726,7 +1721,7 @@ function isLexicalSameReference(checker, sharePartner, reference) {
|
|
|
1726
1721
|
const aParent = index.unwrapParent(reference.parent);
|
|
1727
1722
|
// If the reference is not part a property access, return true. The references
|
|
1728
1723
|
// are guaranteed symbol matches.
|
|
1729
|
-
if (!
|
|
1724
|
+
if (!ts.isPropertyAccessExpression(aParent) && !ts.isElementAccessExpression(aParent)) {
|
|
1730
1725
|
return sharePartner.text === reference.text;
|
|
1731
1726
|
}
|
|
1732
1727
|
// If reference parent is part of a property expression, but the share
|
|
@@ -1763,7 +1758,7 @@ function migrateStandardTsReference(tsReferencesWithNarrowing, checker, info, re
|
|
|
1763
1758
|
// Unwrap the signal directly.
|
|
1764
1759
|
if (recommendedNode === 'preserve') {
|
|
1765
1760
|
// Append `()` to unwrap the signal.
|
|
1766
|
-
replacements.push(new
|
|
1761
|
+
replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({
|
|
1767
1762
|
position: originalNode.getEnd(),
|
|
1768
1763
|
end: originalNode.getEnd(),
|
|
1769
1764
|
toInsert: '()',
|
|
@@ -1776,8 +1771,8 @@ function migrateStandardTsReference(tsReferencesWithNarrowing, checker, info, re
|
|
|
1776
1771
|
// Extract the shared field name.
|
|
1777
1772
|
const toInsert = idToSharedField.get(recommendedNode);
|
|
1778
1773
|
const replaceNode = index.traverseAccess(originalNode);
|
|
1779
|
-
|
|
1780
|
-
replacements.push(new
|
|
1774
|
+
assert(toInsert, 'no shared variable yet available');
|
|
1775
|
+
replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({
|
|
1781
1776
|
position: replaceNode.getStart(),
|
|
1782
1777
|
end: replaceNode.getEnd(),
|
|
1783
1778
|
toInsert,
|
|
@@ -1797,12 +1792,12 @@ function migrateStandardTsReference(tsReferencesWithNarrowing, checker, info, re
|
|
|
1797
1792
|
parent = parent.parent;
|
|
1798
1793
|
}
|
|
1799
1794
|
const replaceNode = index.traverseAccess(originalNode);
|
|
1800
|
-
const filePath =
|
|
1795
|
+
const filePath = run_in_devkit.projectFile(sf, info);
|
|
1801
1796
|
const initializer = `${replaceNode.getText()}()`;
|
|
1802
1797
|
const fieldName = nameGenerator.generate(originalNode.text, referenceNodeInBlock);
|
|
1803
1798
|
let sharedValueAccessExpr;
|
|
1804
1799
|
let temporaryVariableStr;
|
|
1805
|
-
if (
|
|
1800
|
+
if (ts.isClassLike(recommendedNode)) {
|
|
1806
1801
|
sharedValueAccessExpr = `this.${fieldName}`;
|
|
1807
1802
|
temporaryVariableStr = `private readonly ${fieldName} = ${initializer};`;
|
|
1808
1803
|
}
|
|
@@ -1814,18 +1809,18 @@ function migrateStandardTsReference(tsReferencesWithNarrowing, checker, info, re
|
|
|
1814
1809
|
// If the common ancestor block of all shared references is an arrow function
|
|
1815
1810
|
// without a block, convert the arrow function to a block and insert the temporary
|
|
1816
1811
|
// variable at the beginning.
|
|
1817
|
-
if (
|
|
1812
|
+
if (ts.isArrowFunction(parent) && !ts.isBlock(parent.body)) {
|
|
1818
1813
|
replacements.push(...createNewBlockToInsertVariable(parent, filePath, temporaryVariableStr));
|
|
1819
1814
|
}
|
|
1820
1815
|
else {
|
|
1821
|
-
const leadingSpace =
|
|
1822
|
-
replacements.push(new
|
|
1816
|
+
const leadingSpace = ts.getLineAndCharacterOfPosition(sf, referenceNodeInBlock.getStart());
|
|
1817
|
+
replacements.push(new run_in_devkit.Replacement(filePath, new run_in_devkit.TextUpdate({
|
|
1823
1818
|
position: referenceNodeInBlock.getStart(),
|
|
1824
1819
|
end: referenceNodeInBlock.getStart(),
|
|
1825
1820
|
toInsert: `${temporaryVariableStr}\n${' '.repeat(leadingSpace.character)}`,
|
|
1826
1821
|
})));
|
|
1827
1822
|
}
|
|
1828
|
-
replacements.push(new
|
|
1823
|
+
replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({
|
|
1829
1824
|
position: replaceNode.getStart(),
|
|
1830
1825
|
end: replaceNode.getEnd(),
|
|
1831
1826
|
toInsert: sharedValueAccessExpr,
|
|
@@ -1921,8 +1916,8 @@ function migrateTypeScriptTypeReferences(host, references, importManager, info)
|
|
|
1921
1916
|
}
|
|
1922
1917
|
seenTypeNodes.add(reference.from.node);
|
|
1923
1918
|
if (reference.isPartialReference && reference.isPartOfCatalystFile) {
|
|
1924
|
-
|
|
1925
|
-
|
|
1919
|
+
assert(reference.from.node.typeArguments, 'Expected type arguments for partial reference.');
|
|
1920
|
+
assert(reference.from.node.typeArguments.length === 1, 'Expected an argument for reference.');
|
|
1926
1921
|
const firstArg = reference.from.node.typeArguments[0];
|
|
1927
1922
|
const sf = firstArg.getSourceFile();
|
|
1928
1923
|
// Naive detection of the import. Sufficient for this test file migration.
|
|
@@ -1934,12 +1929,12 @@ function migrateTypeScriptTypeReferences(host, references, importManager, info)
|
|
|
1934
1929
|
exportSymbolName: 'UnwrapSignalInputs',
|
|
1935
1930
|
requestedFile: sf,
|
|
1936
1931
|
});
|
|
1937
|
-
host.replacements.push(new
|
|
1932
|
+
host.replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({
|
|
1938
1933
|
position: firstArg.getStart(),
|
|
1939
1934
|
end: firstArg.getStart(),
|
|
1940
|
-
toInsert: `${host.printer.printNode(
|
|
1935
|
+
toInsert: `${host.printer.printNode(ts.EmitHint.Unspecified, unwrapImportExpr, sf)}<`,
|
|
1941
1936
|
})));
|
|
1942
|
-
host.replacements.push(new
|
|
1937
|
+
host.replacements.push(new run_in_devkit.Replacement(run_in_devkit.projectFile(sf, info), new run_in_devkit.TextUpdate({ position: firstArg.getEnd(), end: firstArg.getEnd(), toInsert: '>' })));
|
|
1943
1938
|
}
|
|
1944
1939
|
}
|
|
1945
1940
|
}
|
|
@@ -1,23 +1,19 @@
|
|
|
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
9
|
var ts = require('typescript');
|
|
10
|
-
var imports = require('./imports-
|
|
11
|
-
|
|
12
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
13
|
-
|
|
14
|
-
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
10
|
+
var imports = require('./imports-CIX-JgAN.js');
|
|
15
11
|
|
|
16
12
|
function getCallDecoratorImport(typeChecker, decorator) {
|
|
17
13
|
// Note that this does not cover the edge case where decorators are called from
|
|
18
14
|
// a namespace import: e.g. "@core.Component()". This is not handled by Ngtsc either.
|
|
19
|
-
if (!
|
|
20
|
-
!
|
|
15
|
+
if (!ts.isCallExpression(decorator.expression) ||
|
|
16
|
+
!ts.isIdentifier(decorator.expression.expression)) {
|
|
21
17
|
return null;
|
|
22
18
|
}
|
|
23
19
|
const identifier = decorator.expression.expression;
|