Skip to content

Commit 4a2c214

Browse files
committed
fix(migrations): avoid migrating queries multiple times in signal queries migration
When a source file was part of multiple tsconfigs (e.g. a library's build, prod and spec configs), the signal queries migration rewrote its queries once per compilation unit, producing duplicated fields and imports. This happened because source queries were collected from all program files instead of only the files owned by the current unit. Only migrate queries whose file belongs to the current compilation unit, while still registering all queries for reference resolution. Tested by adding a schematic spec with overlapping build and test tsconfigs. Fixes angular#71147
1 parent f4b7064 commit 4a2c214

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

‎packages/core/schematics/migrations/signal-queries-migration/migration.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,14 +420,18 @@ export class SignalQueriesMigration extends TsurgeComplexMigration<
420420
const knownQueries = new KnownQueries(info, this.config, globalMetadata);
421421
const referenceResult: ReferenceResult<ClassFieldDescriptor> = {references: []};
422422
const sourceQueries: ExtractedQuery[] = [];
423+
const unitSourceFiles = new Set(sourceFiles);
423424

424425
// Detect all queries in this unit.
425426
const queryWholeProgramVisitor = (node: ts.Node) => {
426427
// Detect all SOURCE queries and migrate them, if possible.
427428
const extractedQuery = extractSourceQueryDefinition(node, reflector, evaluator, info);
428429
if (extractedQuery !== null) {
429430
knownQueries.registerQueryField(extractedQuery.node, extractedQuery.id);
430-
sourceQueries.push(extractedQuery);
431+
// Files shared between tsconfigs are only migrated by the unit that owns them.
432+
if (unitSourceFiles.has(extractedQuery.node.getSourceFile())) {
433+
sourceQueries.push(extractedQuery);
434+
}
431435
return;
432436
}
433437

‎packages/core/schematics/test/queries_migration_spec.ts‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,41 @@ describe('signal queries migration', () => {
7171
expect(content).toContain("readonly ref = contentChild.required<ElementRef>('ref');");
7272
});
7373

74+
it('should migrate a query once when its file is part of multiple tsconfigs', async () => {
75+
writeFile('/tsconfig.spec.json', '{}');
76+
writeFile(
77+
'/angular.json',
78+
JSON.stringify({
79+
version: 1,
80+
projects: {
81+
t: {
82+
root: '',
83+
architect: {
84+
build: {options: {tsConfig: './tsconfig.json'}},
85+
test: {options: {tsConfig: './tsconfig.spec.json'}},
86+
},
87+
},
88+
},
89+
}),
90+
);
91+
writeFile(
92+
'/index.ts',
93+
`
94+
import {ContentChild, ElementRef, Directive} from '@angular/core';
95+
96+
@Directive({})
97+
export class SomeDirective {
98+
@ContentChild('ref') ref!: ElementRef;
99+
}`,
100+
);
101+
102+
await runMigration();
103+
104+
const content = tree.readContent('/index.ts');
105+
expect(content.match(/contentChild\.required/g)?.length).toBe(1);
106+
expect(content.match(/from '@angular\/core'/g)?.length).toBe(1);
107+
});
108+
74109
it('should report correct statistics', async () => {
75110
writeFile(`node_modules/@tsconfig/strictest/tsconfig.json`, `{}`);
76111
writeFile(

0 commit comments

Comments
 (0)