Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterator interface for LanguageService #15168

Open
felixfbecker opened this issue Apr 13, 2017 · 1 comment
Open

Iterator interface for LanguageService #15168

felixfbecker opened this issue Apr 13, 2017 · 1 comment
Labels
API Relates to the public API for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@felixfbecker
Copy link
Contributor

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> {
    // ...
}
@mhegazy
Copy link
Contributor

mhegazy commented Apr 19, 2017

This seems like a good suggestion. we would be open to adding a new API (we can not change the existing ones for back-compat purposes).

One thing to note, most users of the LS are on the tsserver, and that is what we would recommend moving forward. given the way the server protocol works, this change would not be of much benefit.

it would be useful to do a general pass over the LS API and implementation and see what would benefit from iterators/generators in general.

@mhegazy mhegazy added Suggestion An idea for TypeScript API Relates to the public API for TypeScript labels Apr 19, 2017
@RyanCavanaugh RyanCavanaugh added the Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature label Aug 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Relates to the public API for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

3 participants