Skip to content

Commit 6357d4a

Browse files
devversionalxhub
authored andcommitted
fix(core): static-query migration fails with default parameter values (#30269)
Currently when someone has a call expression within the `ngOnInit` call and we try to peek into that function with respect to the current function context, the schematic errors because a call expression argument is undefined. This is valid because the target function declaration defines that parameter with a default value. In order to fix this, we need to respect parameter default values. PR Close #30269
1 parent 29786e8 commit 6357d4a

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

‎packages/core/schematics/migrations/static-queries/angular/directive_inputs.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ function getInputNamesFromMetadata(
6868
// where inputs could be declared. This is an edge case because there
6969
// always needs to be an object literal, but in case there isn't we just
7070
// want to skip the invalid decorator and return null.
71-
if (!ts.isObjectLiteralExpression(decoratorCall.arguments[0])) {
71+
if (decoratorCall.arguments.length !== 1 ||
72+
!ts.isObjectLiteralExpression(decoratorCall.arguments[0])) {
7273
return null;
7374
}
7475

‎packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,17 @@ export class DeclarationUsageVisitor {
240240
callArgs: ts.NodeArray<ts.Expression>, parameters: ts.NodeArray<ts.ParameterDeclaration>) {
241241
parameters.forEach((parameter, index) => {
242242
let argumentNode: ts.Node = callArgs[index];
243+
244+
if (!argumentNode) {
245+
if (!parameter.initializer) {
246+
return;
247+
}
248+
249+
// Argument can be undefined in case the function parameter has a default
250+
// value. In that case we want to store the parameter default value in the context.
251+
argumentNode = parameter.initializer;
252+
}
253+
243254
if (ts.isIdentifier(argumentNode)) {
244255
this.context.set(parameter, this._resolveIdentifier(argumentNode));
245256
} else {
@@ -285,7 +296,7 @@ export class DeclarationUsageVisitor {
285296
private _getPropertyAccessSymbol(node: ts.PropertyAccessExpression): ts.Symbol|null {
286297
let propertySymbol = this._getDeclarationSymbolOfNode(node.name);
287298

288-
if (!propertySymbol) {
299+
if (!propertySymbol || !propertySymbol.valueDeclaration) {
289300
return null;
290301
}
291302

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,5 +1384,29 @@ describe('static-queries migration with usage strategy', () => {
13841384

13851385
expect(testModule.promptForMigrationStrategy).toHaveBeenCalledTimes(0);
13861386
});
1387+
1388+
it('should support function call with default parameter value', async() => {
1389+
writeFile('/index.ts', `
1390+
import {Component, ${queryType}} from '@angular/core';
1391+
1392+
@Component({template: '<span>Test</span>'})
1393+
export class MyComponent {
1394+
@${queryType}('test') query: any;
1395+
1396+
ngOnInit() {
1397+
this.myFunction();
1398+
}
1399+
1400+
myFunction(unused?: string, cb = () => this.query.doSomething) {
1401+
cb();
1402+
}
1403+
}
1404+
`);
1405+
1406+
await runMigration();
1407+
1408+
expect(tree.readContent('/index.ts'))
1409+
.toContain(`@${queryType}('test', { static: true }) query: any;`);
1410+
});
13871411
}
13881412
});

0 commit comments

Comments
 (0)