refactor(migrations): inject migration internal mode incorrectly migration properties initialized to identifiers (#58393)

Fixes that when the `inject` migration in internal mode was starting to visit the nodes one level down from the root when considering whether an expression contains local references. This lead it to skip over top-level identifiers and migrate some code incorrectly.

PR Close #58393
This commit is contained in:
Kristiyan Kostadinov 2024-10-28 15:21:26 +01:00 committed by Alex Rickabaugh
parent 7a65cdd911
commit eafe9040a2
2 changed files with 43 additions and 2 deletions

View file

@ -158,7 +158,7 @@ function hasLocalReferences(
const sourceFile = root.getSourceFile();
let hasLocalRefs = false;
root.forEachChild(function walk(node) {
const walk = (node: ts.Node) => {
// Stop searching if we know that it has local references.
if (hasLocalRefs) {
return;
@ -193,7 +193,9 @@ function hasLocalReferences(
if (!hasLocalRefs) {
node.forEachChild(walk);
}
});
};
walk(root);
return hasLocalRefs;
}

View file

@ -1986,5 +1986,44 @@ describe('inject migration', () => {
`}`,
]);
});
it('should not inline properties initialized to identifiers referring to constructor parameters', async () => {
writeFile(
'/dir.ts',
[
`import { Injectable } from '@angular/core';`,
`import { OtherService } from './other-service';`,
``,
`@Injectable()`,
`export class SomeService {`,
` readonly otherService: OtherService;`,
``,
` constructor(readonly differentName: OtherService) {`,
` this.otherService = differentName;`,
` }`,
`}`,
].join('\n'),
);
await runInternalMigration();
expect(tree.readContent('/dir.ts').split('\n')).toEqual([
`import { Injectable, inject } from '@angular/core';`,
`import { OtherService } from './other-service';`,
``,
`@Injectable()`,
`export class SomeService {`,
` readonly differentName = inject(OtherService);`,
``,
` readonly otherService: OtherService;`,
``,
` constructor() {`,
` const differentName = this.differentName;`,
``,
` this.otherService = differentName;`,
` }`,
`}`,
]);
});
});
});