refactor(core): static-query migration does not detect external call expressions. (#29133)

Currently the static-query migration does not properly handle functions which
are declared externally. This is because we don't resolve the symbol of the
call-expression through its type. Currently we just determine the symbol of the
call-expression through the given call expression node, which doesn't necessarily
refer to the *value declaration* of the call expression. e.g. the symbol refers to the
import declaration which imports the external function. This means that we currently
can't check the external function as we couldn't find the actual value declaration.
We can fix this by resolving the type of the call expression and using the type in order
to retrieve the symbol containing the *value declaration*

PR Close #29133
This commit is contained in:
Paul Gschwendtner 2019-03-09 16:10:50 +01:00 committed by Kara Erickson
parent fca1724ebf
commit 360730ce59
2 changed files with 31 additions and 1 deletions

View File

@ -35,7 +35,8 @@ export class DeclarationUsageVisitor {
return; return;
} }
const callExprSymbol = this.typeChecker.getSymbolAtLocation(node); const callExprType = this.typeChecker.getTypeAtLocation(node);
const callExprSymbol = callExprType.getSymbol();
if (!callExprSymbol || !callExprSymbol.valueDeclaration || if (!callExprSymbol || !callExprSymbol.valueDeclaration ||
!isFunctionLikeDeclaration(callExprSymbol.valueDeclaration)) { !isFunctionLikeDeclaration(callExprSymbol.valueDeclaration)) {

View File

@ -711,6 +711,35 @@ describe('static-queries migration', () => {
.toContain(`@${queryType}('test', { static: true }) query2: any;`); .toContain(`@${queryType}('test', { static: true }) query2: any;`);
}); });
it('should detect static queries used in external function-like declaration', () => {
writeFile('/index.ts', `
import {Component, ${queryType}} from '@angular/core';
import {externalFn} from './external';
@Component({template: '<span #test></span>'})
export class MyComp {
private @${queryType}('test') query: any;
ngOnInit() {
externalFn(this);
}
}
`);
writeFile('/external.ts', `
import {MyComp} from './index';
export function externalFn(ctx: MyComp) {
ctx.query.usedStatically();
}
`);
runMigration();
expect(tree.readContent('/index.ts'))
.toContain(`@${queryType}('test', { static: true }) query: any;`);
});
it('should properly handle multiple tsconfig files', () => { it('should properly handle multiple tsconfig files', () => {
writeFile('/src/index.ts', ` writeFile('/src/index.ts', `
import {Component, ${queryType}} from '@angular/core'; import {Component, ${queryType}} from '@angular/core';