-
Notifications
You must be signed in to change notification settings - Fork 43
TODOs
Since version 6.12.1 GHC’s API should be somewhat more thread-safe. It should now be safe to run several sessions at the same time.
Ideally, the compiler is just a function (source files, flags, packages) -> Maybe a
for whatever a
we are currently interested in. E.g., a
could be a compiled binary, a list of definitions, a graph describing dependencies between different source files or definitions, etc. The important “magic” would then be to implement this efficiently using lots of caching and smart discovery of which things are outdated.
Of course there are many other tricky bits, e.g.:
- How to handle dependencies across multiple open projects?
- Project A depends on project B. Both are opened at the same time and the user makes modification to files in A, should this be reflected in project B? Probably not without an explicit commit step (i.e.,
ghc-pkg register
or somesuch). - File F is shared between project A and B (e.g., B is an executable based on library A). Where should the changes to F be reflected? I guess it should be in both A and B. Arguably such a setup is a Bad Idea™ anyway.
- Project A depends on project B. Both are opened at the same time and the user makes modification to files in A, should this be reflected in project B? Probably not without an explicit commit step (i.e.,
This should make it more robust to GHC API changes (fewer #ifdef
s) and possibly make the code shorter. The latter is not obvious since GHC’s syntax trees support different traversal modes such as “before renamer”, “after renamer”, “only user-visible stuff”, and more.
The outline view needs some cleaning up. E.g., we should distinguish between data family
and type family
. All in all, there aren’t too many different kinds of Haskell top-level declarations, so we can support them all.
A useful feature would be to record both declaration and implementation. For type classes there may be multiple implementations.
The outline view stuff can serve as a basis for code folding; the required information is essentially the same. Both, however, currently require the whole file to parse and type check.
Parse errors can be fixed by parsing each top-level declaration separately, using the indentation level as a heuristic for how far a declaration is supposed to span. E.g.,
foo x y = bar (baz, bar -- oops, forgot the closing ")"
bar z = 42 — parse error would be reported here.
We want to attribute the parse error to
foo
and restart at bar
since it’s at the same level as foo
and thus probably intended to be separate.
Since in Haskell a function declared at the beginning of the file can reference a function declared later in the same file, we need to call GHC’s renamer to figure out the dependencies between top-level definitions. Unfortunately, in the GHC API the renamer can only be run together with the type checker since the two phases can be mutually recursive when the code contains Template Haskell. […specify problem more precisely and list workarounds …]
Invoking --make
style API functionality on a large project like GHC is prohibitively slow. I don’t even want to speak of memory usage. Since we do not actually need to keep around all that info, writing out .hi files and using GHC in one-shot mode should work well enough. Since we don’t need any unfoldings or other Core stuff, makeSimpleIface
should do for this purpose.