Skip to content
This repository has been archived by the owner on Mar 4, 2023. It is now read-only.
nominolo edited this page Sep 13, 2010 · 3 revisions

Multiple API instances

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.

General API Design

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.

Reimplement Syntax Tree Traversal in Terms of SYB (started)

This should make it more robust to GHC API changes (fewer #ifdefs) 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.

Review Outline View Stuff

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.

Code Folding

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 …]

Store .hi files on disk to support large projects (e.g., GHC)

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.