microsoft / microsoft/TypeScript

Iterator interface for LanguageService

Offen
#15,168 1 Kommentar 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Awaiting More Feedback Domain: API Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

Currently, functions like LanguageService.getReferencesAtPosition() or getNavigateToItems() return an array. That means, they have to collect all references/navigation items before returning, and blocks the CPU until then.
If you invoke such a function in repos like angular/angular the returned array can easily have 50k elements and the function can take a very long time to return. That means a UI can only show the results until all items have been aggregated (of course, you can pass a limit, but in the case of getNavigateToItems() that can result in the relevant items you wanted not being found because matching is done fuzzily and the function returns early when limit items that matched the query fuzzily were found. For example, in angular/angular, a query for Http with a limit will return a lot of not-relevant http variables, but a query without a limit will return the Http class). If you have to do more filtering, transformation etc to the items you end up with an unneeded extra iteration.

I would like to propose to add or change the API to return an Iterable instead. This can be achieved with generators. This would allow the consumer to pull items lazily from the iterator.
That means

  • results (e.g. references, symbols) can be streamed and shown in the UI as soon as they are found in the source
  • requests can be easily cancelled by aborting iteration (e.g. break in a for of)
  • a limit parameter is not needed anymore, you can just abort the iteration after your limit is reached
  • if you need to perform filtering, transformation etc on the result, you can do that in the same iteration "pipeline"

There is no dependency needed to make this work, it's all in the language.
The returned Iterable can be consumed in a variety of ways, with for of, generator delegation, with iteration libraries or Observables, or easily coverted to an Array with Array.from().

This API could be added in a backwards-compatible way by adding a new variant and changing the old one to delegate and convert to array:

getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] {
    return Array.from(this.getReferencesIterableAtPosition(fileName, position);
}
getReferencesIterableAtPosition(fileName: string, position: number): IterableIterator<ReferenceEntry> {
    // ...
}

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, die LanguageService-Implementierungen von getReferencesAtPosition() und getNavigateToItems() zu finden, und untersuche anschließend, wie sie Ergebnisse sammeln und begrenzen. Bestimme die API-Oberfläche und die Kompatibilitätsauswirkungen iterierbarer Varianten und bestehender Methoden, die Arrays zurückgeben. Erledigt ist die Aufgabe, wenn das vorgeschlagene Verhalten der verzögerten Iteration konsistent implementiert und durch relevante LanguageService-Tests abgedeckt ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
devtools
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.