fix(language-service): prune duplicate returned definitions (#34995)
Sometimes, a request for definitions will return multiple of the same definition. This can happen in at least the cases of - two-way bindings (one of the same definition for the property and event binding) - multiple template binding expressions in the same attribute - something like "*ngFor="let i of items; trackBy: test" has two template bindings, resulting in two template binding ASTs at the same location (the attribute span). The language service then parses both of these bindings individually, resulting in two independent but identical definitions. For more context, see https://github.com/angular/angular/pull/34847#discussion_r371006680. This commit prunes duplicate definitions by signing definitions with their location, and checking if that location signature has been seen in a previous definition returned to the client. PR Close #34995
This commit is contained in:

committed by
Andrew Kushnir

parent
3822455928
commit
b64ead5cb8
@ -60,19 +60,16 @@ describe('definitions', () => {
|
||||
expect(textSpan).toEqual(marker);
|
||||
expect(definitions).toBeDefined();
|
||||
|
||||
// There are exactly two, indentical definitions here, corresponding to the "name" on the
|
||||
// property and event bindings of the two-way binding. The two-way binding is effectively
|
||||
// syntactic sugar for `[ngModel]="name" (ngModel)="name=$event"`.
|
||||
expect(definitions !.length).toBe(2);
|
||||
for (const def of definitions !) {
|
||||
expect(def.fileName).toBe(PARSING_CASES);
|
||||
expect(def.name).toBe('title');
|
||||
expect(def.kind).toBe('property');
|
||||
expect(definitions !.length).toBe(1);
|
||||
const def = definitions ![0];
|
||||
|
||||
const fileContent = mockHost.readFile(def.fileName);
|
||||
expect(fileContent !.substring(def.textSpan.start, def.textSpan.start + def.textSpan.length))
|
||||
.toEqual(`title = 'Some title';`);
|
||||
}
|
||||
expect(def.fileName).toBe(PARSING_CASES);
|
||||
expect(def.name).toBe('title');
|
||||
expect(def.kind).toBe('property');
|
||||
|
||||
const fileContent = mockHost.readFile(def.fileName);
|
||||
expect(fileContent !.substring(def.textSpan.start, def.textSpan.start + def.textSpan.length))
|
||||
.toEqual(`title = 'Some title';`);
|
||||
});
|
||||
|
||||
it('should be able to find a method from a call', () => {
|
||||
|
Reference in New Issue
Block a user