diff --git a/packages/core/schematics/migrations/static-queries/angular/directive_inputs.ts b/packages/core/schematics/migrations/static-queries/angular/directive_inputs.ts index d9c8d20b6a..fa511a964a 100644 --- a/packages/core/schematics/migrations/static-queries/angular/directive_inputs.ts +++ b/packages/core/schematics/migrations/static-queries/angular/directive_inputs.ts @@ -68,7 +68,8 @@ function getInputNamesFromMetadata( // where inputs could be declared. This is an edge case because there // always needs to be an object literal, but in case there isn't we just // want to skip the invalid decorator and return null. - if (!ts.isObjectLiteralExpression(decoratorCall.arguments[0])) { + if (decoratorCall.arguments.length !== 1 || + !ts.isObjectLiteralExpression(decoratorCall.arguments[0])) { return null; } diff --git a/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts b/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts index 668a71b5e5..346a745f46 100644 --- a/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts +++ b/packages/core/schematics/migrations/static-queries/strategies/usage_strategy/declaration_usage_visitor.ts @@ -240,6 +240,17 @@ export class DeclarationUsageVisitor { callArgs: ts.NodeArray, parameters: ts.NodeArray) { parameters.forEach((parameter, index) => { let argumentNode: ts.Node = callArgs[index]; + + if (!argumentNode) { + if (!parameter.initializer) { + return; + } + + // Argument can be undefined in case the function parameter has a default + // value. In that case we want to store the parameter default value in the context. + argumentNode = parameter.initializer; + } + if (ts.isIdentifier(argumentNode)) { this.context.set(parameter, this._resolveIdentifier(argumentNode)); } else { @@ -285,7 +296,7 @@ export class DeclarationUsageVisitor { private _getPropertyAccessSymbol(node: ts.PropertyAccessExpression): ts.Symbol|null { let propertySymbol = this._getDeclarationSymbolOfNode(node.name); - if (!propertySymbol) { + if (!propertySymbol || !propertySymbol.valueDeclaration) { return null; } diff --git a/packages/core/schematics/test/static_queries_migration_usage_spec.ts b/packages/core/schematics/test/static_queries_migration_usage_spec.ts index 1b30aadf8b..4397e09686 100644 --- a/packages/core/schematics/test/static_queries_migration_usage_spec.ts +++ b/packages/core/schematics/test/static_queries_migration_usage_spec.ts @@ -1384,5 +1384,29 @@ describe('static-queries migration with usage strategy', () => { expect(testModule.promptForMigrationStrategy).toHaveBeenCalledTimes(0); }); + + it('should support function call with default parameter value', async() => { + writeFile('/index.ts', ` + import {Component, ${queryType}} from '@angular/core'; + + @Component({template: 'Test'}) + export class MyComponent { + @${queryType}('test') query: any; + + ngOnInit() { + this.myFunction(); + } + + myFunction(unused?: string, cb = () => this.query.doSomething) { + cb(); + } + } + `); + + await runMigration(); + + expect(tree.readContent('/index.ts')) + .toContain(`@${queryType}('test', { static: true }) query: any;`); + }); } });