Skip to content

Warry/elm-stuff

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

elm-stuff

Decode the Elm compiler's binary cache files from elm-stuff/.

When you run elm make, the compiler writes a set of binary cache files under elm-stuff/<compiler-version>/. These aren't documented or meant to be read by anything other than the compiler itself, but they contain useful information: what every module exposes, its inferred types, and its compiled (pre-JS) representation. This library decodes those files into plain Elm values.

What to do with it?

Unlike other tools (like elm-syntax parser), elm-stuff only has access to your code that has been verified by the compiler, as well as all the dependencies.

You can use the Interfaces to derive Json encoders/decoders, or the Graphs to transpile to something else.

File formats

File Decoder Contents
d.dat decodeDetails What the compiler built last time, used to decide what needs recompiling.
i.dat decodeInterfaces What every dependency module exposes.
o.dat decodeGlobalGraph Every dependency's compiled code.
FolderName-ModuleName.elmi decodeInterface What one locally-compiled module exposes.
FolderName-ModuleName.elmo decodeLocalGraph One locally-compiled module's own compiled code.

Installation

elm install Warry/elm-stuff

Usage

Each decoder takes Bytes (for example read via elm/file's File.toBytes) and returns a Maybe of the decoded value.

import Bytes exposing (Bytes)
import ElmStuff


readDetails : Bytes -> Maybe ElmStuff.Details
readDetails bytes =
    ElmStuff.decodeDetails bytes

A minimal example reading a file picked from disk:

import Bytes exposing (Bytes)
import ElmStuff
import File exposing (File)
import File.Select as Select
import Task


type Msg
    = PickFile
    | GotFile File
    | GotBytes Bytes


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        PickFile ->
            ( model, Select.file [] GotFile )

        GotFile file ->
            ( model, Task.perform GotBytes (File.toBytes file) )

        GotBytes bytes ->
            case ElmStuff.decodeDetails bytes of
                Just details ->
                    ( { model | details = Just details }, Cmd.none )

                Nothing ->
                    ( { model | error = Just "decode failed" }, Cmd.none )

See example/src/Main.elm for a complete browser-based app that lets you pick any of the 5 file kinds and inspect the decoded result.

API

The top-level ElmStuff module exposes one decoder per cache file:

decodeDetails : Bytes -> Maybe Details.Details
decodeInterfaces : Bytes -> Maybe (DictAny.Dict ModuleName.Canonical Interface.DependencyInterface)
decodeGlobalGraph : Bytes -> Maybe Optimized.GlobalGraph
decodeInterface : Bytes -> Maybe Interface.Interface
decodeLocalGraph : Bytes -> Maybe Optimized.LocalGraph

The decoded types themselves (Details, Interface, GlobalGraph, LocalGraph, and the supporting types they're built from -- canonical types, module names, packages, decision trees, kernel chunks, and so on) live in the ElmStuff.* modules and are also exposed, in case you need to decode a sub-structure directly or write your own Bytes.Decode.Decoder that composes with these:

  • ElmStuff.Details -- the d.dat record and its fields.
  • ElmStuff.Interface -- module interfaces (.elmi, and i.dat's values).
  • ElmStuff.Optimized -- compiled-code graphs (.elmo, o.dat).
  • ElmStuff.Canonical -- canonical AST types (annotations, unions, aliases).
  • ElmStuff.DecisionTree -- compiled pattern-match tests.
  • ElmStuff.Kernel -- kernel (JS) source chunks.
  • ElmStuff.ModuleName -- module names resolved to their defining package.
  • ElmStuff.Package -- package names and versions.
  • ElmStuff.Binop -- infix operator associativity/precedence.
  • ElmStuff.Region -- source-code spans.
  • ElmStuff.Outline -- elm.json source directory entries as embedded in Details.

HelpBytes is an internal module of low-level decoding helpers (fixed-size integers, length-prefixed strings, Haskell containers-style maps, and so on) that the rest of the library is built on. It isn't part of the public API and its shape may change without notice.

Compatibility

The decoders are derived from the Haskell compiler's Binary instances (compiler commit e20e8c8e, Elm 0.19.2). The cache files have no header, magic number, or version byte, so decoding failure just means either the bytes are corrupt or these decoders have drifted from whatever compiler version produced them.

Development

elm make src/ElmStuff.elm  # type-check the library
elm-test                   # run the test suite

About

Decode interfaces (.elmi, i.dat) and objects (.elmo, o.dat) from elm-stuff/

Resources

License

Stars

6 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages