fix(language-service): remove repeated symbol definitions for structural directive (#34847)

For the structural directive, the 'path' will contain multiple `BoundDirectivePropertyAst` which depends on the number of directive property in the attribute value(e.g. '*ngFor="let item of []; trackBy: test;"', it has 2 `BoundDirectivePropertyAst`, 'ngForOf' and 'ngForTrackBy').

PR Close #34847
This commit is contained in:
ivanwonder 2020-01-26 22:48:11 +08:00 committed by Andrew Kushnir
parent e7dff9eb0c
commit 09869af90f
2 changed files with 9 additions and 2 deletions

View File

@ -29,6 +29,8 @@ export function locateSymbols(info: AstResult, position: number): SymbolInfo[] {
const templatePosition = position - info.template.span.start; const templatePosition = position - info.template.span.start;
// TODO: update `findTemplateAstAt` to use absolute positions. // TODO: update `findTemplateAstAt` to use absolute positions.
const path = findTemplateAstAt(info.templateAst, templatePosition); const path = findTemplateAstAt(info.templateAst, templatePosition);
const attribute = findAttribute(info, position);
if (!path.tail) return []; if (!path.tail) return [];
const narrowest = spanOf(path.tail); const narrowest = spanOf(path.tail);
@ -38,6 +40,11 @@ export function locateSymbols(info: AstResult, position: number): SymbolInfo[] {
toVisit.push(node); toVisit.push(node);
} }
// For the structural directive, only care about the last template AST.
if (attribute?.name.startsWith('*')) {
toVisit.splice(0, toVisit.length - 1);
}
return toVisit.map(ast => locateSymbol(ast, path, info)) return toVisit.map(ast => locateSymbol(ast, path, info))
.filter((sym): sym is SymbolInfo => sym !== undefined); .filter((sym): sym is SymbolInfo => sym !== undefined);
} }

View File

@ -311,7 +311,7 @@ describe('definitions', () => {
expect(definitions).toBeDefined(); expect(definitions).toBeDefined();
// The two definitions are setter and getter of 'ngForTrackBy'. // The two definitions are setter and getter of 'ngForTrackBy'.
expect(definitions !.length).toBe(4); expect(definitions !.length).toBe(2);
const refFileName = '/node_modules/@angular/common/common.d.ts'; const refFileName = '/node_modules/@angular/common/common.d.ts';
definitions !.forEach(def => { definitions !.forEach(def => {
@ -335,7 +335,7 @@ describe('definitions', () => {
expect(textSpan).toEqual(marker); expect(textSpan).toEqual(marker);
expect(definitions).toBeDefined(); expect(definitions).toBeDefined();
expect(definitions !.length).toBe(2); expect(definitions !.length).toBe(1);
const refFileName = '/app/parsing-cases.ts'; const refFileName = '/app/parsing-cases.ts';
const def = definitions ![0]; const def = definitions ![0];