tsutils
tsutils copied to clipboard
Refactor collectVariableUsage
The current API is somewhat difficult to use and does too much by analyzing the whole source file ahead of time.
The new API should return an object that can be used to:
- get all declarations of an identifier (also with an identifier of a usage)
- get all uses of a declaration (allow filtering by domain)
- check if identifier is in scope
- get a list of all declarations in the file
optionally:
- get all identifiers in scope (optionally filtered by kind)
- get all locations where the identifier is in scope (excluding TDZ)
- lazily analyze only the scopes necessary to answer requests
Needs a good name:
- ScopeAnalyzer
- UsageTracker
- ReferenceFinder
This doesn't need to be shipped in a new major version. It can simply be published once it's ready while still keeping the old API around
It turns out that this analysis in not possible without the type checker. Namespace merging and imports in namespaces can introduce identifiers whose domain is not known. That's already an issue in the current implementation, which has yet to be reported.
// foo.ts
namespace foo {
export class C {}
}
// bar.ts
class C {}
namespace foo {
new C(); // references `foo.C`
}
namespace bar {
import C = foo.C;
new C(); // references `foo.C`
}
Everything that doesn't involve namespaces during name resolution could still work as expected.
TBD: how to proceed from here?
- keep the current, broken implementation
- require TypeChecker
- always
- only if namespaces are involved (might be very surprising if this never occurs in tests and only crashes on user code)
It might be the best to simply return undefined if the result of a request is not fully known. That is: if no TypeChecker was provided and there is a namespace involved (or an import)