From 0c53970aeb54033cce880bd9a8b51d8c67513f74 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 28 Mar 2025 10:07:49 +0100 Subject: [PATCH] fix(migrations): handle shorthand assignments in super call (#60602) Fixes that the logic which checks whether a parameter is used inside a `super` call wasn't accounting for shorthand assignments. PR Close #60602 --- .../ng-generate/inject-migration/analysis.ts | 10 +++++ .../schematics/test/inject_migration_spec.ts | 39 +++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/packages/core/schematics/ng-generate/inject-migration/analysis.ts b/packages/core/schematics/ng-generate/inject-migration/analysis.ts index a513eba6c82..ec3ced79b18 100644 --- a/packages/core/schematics/ng-generate/inject-migration/analysis.ts +++ b/packages/core/schematics/ng-generate/inject-migration/analysis.ts @@ -302,6 +302,16 @@ export function getSuperParameters( localTypeChecker.getSymbolAtLocation(node)?.declarations?.forEach((decl) => { if (ts.isParameter(decl) && topLevelParameters.has(decl)) { usedParams.add(decl); + } else if ( + ts.isShorthandPropertyAssignment(decl) && + topLevelParameterNames.has(decl.name.text) + ) { + for (const param of topLevelParameters) { + if (ts.isIdentifier(param.name) && decl.name.text === param.name.text) { + usedParams.add(param); + break; + } + } } }); // Parameters referenced inside callbacks can be used directly diff --git a/packages/core/schematics/test/inject_migration_spec.ts b/packages/core/schematics/test/inject_migration_spec.ts index fb5e906e049..010a4a0c1e6 100644 --- a/packages/core/schematics/test/inject_migration_spec.ts +++ b/packages/core/schematics/test/inject_migration_spec.ts @@ -1835,6 +1835,45 @@ describe('inject migration', () => { ]); }); + it('should handle super parameter used in shorthand assignment', async () => { + writeFile( + '/dir.ts', + [ + `import { Directive } from '@angular/core';`, + `import { Service } from './service';`, + `import { Parent } from './parent';`, + ``, + `@Directive()`, + `export class MyDir extends Parent {`, + ` constructor(private service: Service) {`, + ` super({service});`, + ` }`, + `}`, + ].join('\n'), + ); + + await runMigration(); + + expect(tree.readContent('/dir.ts').split('\n')).toEqual([ + `import { Directive, inject } from '@angular/core';`, + `import { Service } from './service';`, + `import { Parent } from './parent';`, + ``, + `@Directive()`, + `export class MyDir extends Parent {`, + ` private service: Service;`, + ``, + ` constructor() {`, + ` const service = inject(Service);`, + ``, + ` super({service});`, + ` `, + ` this.service = service;`, + ` }`, + `}`, + ]); + }); + describe('internal-only behavior', () => { function runInternalMigration() { return runMigration({_internalCombineMemberInitializers: true});