mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(migrations): inject migration not handling super parameter referenced via this (#60602)
The inject migration has some logic that treats parameters referenced directly inside of `super` differently. This logic didn't account for the fact that the parameters could be inside of inline functions which have less strict access requirements. PR Close #60602
This commit is contained in:
committed by
Jessica Janiuk
parent
7c971566ad
commit
3ff48b6467
@@ -304,7 +304,9 @@ export function getSuperParameters(
|
||||
usedParams.add(decl);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Parameters referenced inside callbacks can be used directly
|
||||
// within `super` so don't descend into inline functions.
|
||||
} else if (!isInlineFunction(node)) {
|
||||
node.forEachChild(walk);
|
||||
}
|
||||
});
|
||||
@@ -423,3 +425,12 @@ function findSuperCall(root: ts.Node): ts.CallExpression | null {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Checks whether a node is an inline function. */
|
||||
export function isInlineFunction(
|
||||
node: ts.Node,
|
||||
): node is ts.FunctionDeclaration | ts.FunctionExpression | ts.ArrowFunction {
|
||||
return (
|
||||
ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import ts from 'typescript';
|
||||
import {isAccessedViaThis, parameterDeclaresProperty} from './analysis';
|
||||
import {isAccessedViaThis, isInlineFunction, parameterDeclaresProperty} from './analysis';
|
||||
|
||||
/** Property that is a candidate to be combined. */
|
||||
interface CombineCandidate {
|
||||
@@ -299,11 +299,7 @@ function isInsideInlineFunction(startNode: ts.Node, boundary: ts.Node): boolean
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
ts.isFunctionDeclaration(current) ||
|
||||
ts.isFunctionExpression(current) ||
|
||||
ts.isArrowFunction(current)
|
||||
) {
|
||||
if (isInlineFunction(current)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1800,6 +1800,41 @@ describe('inject migration', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle parameter referenced through `this` inside a callback within super()', 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({callback: () => this.service.doStuff()});`,
|
||||
` }`,
|
||||
`}`,
|
||||
].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 = inject(Service);`,
|
||||
``,
|
||||
` constructor() {`,
|
||||
` super({callback: () => this.service.doStuff()});`,
|
||||
` }`,
|
||||
`}`,
|
||||
]);
|
||||
});
|
||||
|
||||
describe('internal-only behavior', () => {
|
||||
function runInternalMigration() {
|
||||
return runMigration({_internalCombineMemberInitializers: true});
|
||||
|
||||
Reference in New Issue
Block a user