on master help sign in
Elm.Compiler now exposes an opaque Obj.Graph
6eaff9eEvan Czaplicki
elm-compiler.cabal+48−46
@@ -42,7 +42,7 @@ Library
42 if flag(dev)
42 if flag(dev)
43 ghc-options: -O0 -W -Werror
43 ghc-options: -O0 -W -Werror
44 else
44 else
45− ghc-options: -O2
45+ ghc-options: -O2 -fsimpl-tick-factor=200
46
46
47 Hs-Source-Dirs:
47 Hs-Source-Dirs:
48 src
48 src
@@ -50,6 +50,7 @@ Library
50 exposed-modules:
50 exposed-modules:
51 Elm.Compiler,
51 Elm.Compiler,
52 Elm.Compiler.Module,
52 Elm.Compiler.Module,
53+ Elm.Compiler.Objects,
53 Elm.Compiler.Type,
54 Elm.Compiler.Type,
54 Elm.Docs,
55 Elm.Docs,
55 Elm.Package,
56 Elm.Package,
@@ -83,6 +84,7 @@ Library
83 Docs.Centralize,
84 Docs.Centralize,
84 Docs.Check,
85 Docs.Check,
85 Elm.Compiler.Imports,
86 Elm.Compiler.Imports,
87+ Elm.Compiler.Objects.Internal,
86 Elm.Compiler.Type.Extract,
88 Elm.Compiler.Type.Extract,
87 Elm.Compiler.Version,
89 Elm.Compiler.Version,
88 Generate.JavaScript,
90 Generate.JavaScript,
@@ -160,48 +162,48 @@ Library
160 union-find >= 0.2 && < 0.3
162 union-find >= 0.2 && < 0.3
161
163
162
164
163−Test-Suite compiler-tests
165+--Test-Suite compiler-tests
164− ghc-options:
166+-- ghc-options:
165− -O0
167+-- -O0
166−
168+--
167− Type:
169+-- Type:
168− exitcode-stdio-1.0
170+-- exitcode-stdio-1.0
169−
171+--
170− Hs-Source-Dirs:
172+-- Hs-Source-Dirs:
171− tests, src
173+-- tests, src
172−
174+--
173− Main-is:
175+-- Main-is:
174− Test.hs
176+-- Test.hs
175−
177+--
176− other-modules:
178+-- other-modules:
177− Test.Compiler
179+-- Test.Compiler
178− Test.Property
180+-- Test.Property
179− Test.Property.Arbitrary
181+-- Test.Property.Arbitrary
180− AST.Helpers
182+-- AST.Helpers
181− AST.Literal
183+-- AST.Literal
182−
184+--
183− build-depends:
185+-- build-depends:
184− test-framework > 0.8 && < 0.9,
186+-- test-framework > 0.8 && < 0.9,
185− test-framework-hunit >= 0.3 && < 0.4,
187+-- test-framework-hunit >= 0.3 && < 0.4,
186− test-framework-quickcheck2 >= 0.3 && < 0.4,
188+-- test-framework-quickcheck2 >= 0.3 && < 0.4,
187− HUnit >= 1.1 && < 2,
189+-- HUnit >= 1.1 && < 2,
188− QuickCheck >= 2 && < 3,
190+-- QuickCheck >= 2 && < 3,
189− aeson >= 0.11,
191+-- aeson >= 0.11,
190− aeson-pretty >= 0.8 && < 0.9,
192+-- aeson-pretty >= 0.8 && < 0.9,
191− ansi-terminal >= 0.6.2.1 && < 0.7,
193+-- ansi-terminal >= 0.6.2.1 && < 0.7,
192− ansi-wl-pprint >= 0.6.7 && < 0.7,
194+-- ansi-wl-pprint >= 0.6.7 && < 0.7,
193− base >=4.2 && <5,
195+-- base >=4.2 && <5,
194− binary >= 0.7.0.0 && < 0.8,
196+-- binary >= 0.7.0.0 && < 0.8,
195− bytestring >= 0.9 && < 0.11,
197+-- bytestring >= 0.9 && < 0.11,
196− containers >= 0.3 && < 0.6,
198+-- containers >= 0.3 && < 0.6,
197− directory >= 1.0 && < 2.0,
199+-- directory >= 1.0 && < 2.0,
198− edit-distance >= 0.2 && < 0.3,
200+-- edit-distance >= 0.2 && < 0.3,
199− filemanip >= 0.3.5 && < 0.4,
201+-- filemanip >= 0.3.5 && < 0.4,
200− filepath >= 1 && < 2.0,
202+-- filepath >= 1 && < 2.0,
201− language-glsl >= 0.0.2 && < 0.3,
203+-- language-glsl >= 0.0.2 && < 0.3,
202− mtl >= 2.2 && < 3,
204+-- mtl >= 2.2 && < 3,
203− parsec,
205+-- parsec,
204− pretty >= 1.0 && < 2.0,
206+-- pretty >= 1.0 && < 2.0,
205− process,
207+-- process,
206− text >= 1 && < 2,
208+-- text >= 1 && < 2,
207− union-find >= 0.2 && < 0.3
209+-- union-find >= 0.2 && < 0.3
src/Elm/Compiler.hs+4−4
@@ -17,13 +17,13 @@ import Data.Text (Text)
17import qualified Data.ByteString.Builder as BS
17import qualified Data.ByteString.Builder as BS
18import Text.PrettyPrint.ANSI.Leijen (Doc)
18import Text.PrettyPrint.ANSI.Leijen (Doc)
19
19
20−import qualified AST.Expression.Optimized as Opt
21import qualified AST.Module as Module
20import qualified AST.Module as Module
22import qualified AST.Module.Name as ModuleName
21import qualified AST.Module.Name as ModuleName
23import qualified Compile
22import qualified Compile
24import qualified Docs.Check as Docs
23import qualified Docs.Check as Docs
25import qualified Elm.Compiler.Imports as Imports
24import qualified Elm.Compiler.Imports as Imports
26import qualified Elm.Compiler.Module as M
25import qualified Elm.Compiler.Module as M
26+import qualified Elm.Compiler.Objects.Internal as Obj
27import qualified Elm.Compiler.Version
27import qualified Elm.Compiler.Version
28import qualified Elm.Docs as Docs
28import qualified Elm.Docs as Docs
29import qualified Elm.Package as Package
29import qualified Elm.Package as Package
@@ -104,7 +104,7 @@ compile context source =
104 docs <- Result.format id (docsGen exposed modul)
104 docs <- Result.format id (docsGen exposed modul)
105
105
106 let iface = Module.toInterface modul
106 let iface = Module.toInterface modul
107− let objs = Module.program (Module.info modul)
107+ let objs = Obj.fromModule modul
108
108
109 return (Result docs iface objs)
109 return (Result docs iface objs)
110 in
110 in
@@ -127,7 +127,7 @@ data Result =
127 Result
127 Result
128 { _docs :: Maybe Docs.Documentation
128 { _docs :: Maybe Docs.Documentation
129 , _iface :: M.Interface
129 , _iface :: M.Interface
130− , _objs :: [(Text, Opt.Decl)]
130+ , _objs :: Obj.Graph
131 }
131 }
132
132
133
133
@@ -152,7 +152,7 @@ docsGen isExposed (Module.Module name info) =
152-- CODE GENERATION
152-- CODE GENERATION
153
153
154
154
155−generate :: Map.Map M.Global Opt.Decl -> [M.Global] -> (Set.Set M.Canonical, BS.Builder)
155+generate :: Obj.Graph -> Obj.Roots -> (Set.Set M.Canonical, BS.Builder)
156generate =
156generate =
157 JS.generate
157 JS.generate
158
158
src/Elm/Compiler/Module.hs+17−21
@@ -21,9 +21,6 @@ module Elm.Compiler.Module
21 -- canonical names
21 -- canonical names
22 , ModuleName.Canonical(..)
22 , ModuleName.Canonical(..)
23 , qualifiedVar
23 , qualifiedVar
24−
25− -- variables
26− , Var.Global(..)
27 )
24 )
28 where
25 where
29
26
@@ -37,7 +34,6 @@ import System.FilePath ((</>))
37
34
38import qualified AST.Module as Module
35import qualified AST.Module as Module
39import qualified AST.Module.Name as ModuleName
36import qualified AST.Module.Name as ModuleName
40−import qualified AST.Variable as Var
41import qualified Elm.Compiler.Type as PublicType
37import qualified Elm.Compiler.Type as PublicType
42import qualified Elm.Compiler.Type.Extract as Extract
38import qualified Elm.Compiler.Type.Extract as Extract
43import qualified Generate.JavaScript.Variable as Gen
39import qualified Generate.JavaScript.Variable as Gen
@@ -61,23 +57,6 @@ programTypes =
61-- NAMES
57-- NAMES
62
58
63
59
64−newtype RawForJson = RawForJson ModuleName.Raw
65−
66−
67−fromJson :: RawForJson -> ModuleName.Raw
68−fromJson (RawForJson raw) =
69− raw
70−
71−
72−qualifiedVar :: ModuleName.Canonical -> Text -> Text
73−qualifiedVar =
74− Gen.qualified
75−
76−
77−
78−-- STRING CONVERSIONS for RAW NAMES
79−
80−
81nameToPath :: ModuleName.Raw -> FilePath
60nameToPath :: ModuleName.Raw -> FilePath
82nameToPath name =
61nameToPath name =
83 List.foldl1 (</>) (map Text.unpack (Text.splitOn "." name))
62 List.foldl1 (</>) (map Text.unpack (Text.splitOn "." name))
@@ -131,6 +110,15 @@ isGoodChar char =
131-- JSON for NAME
110-- JSON for NAME
132
111
133
112
113+newtype RawForJson =
114+ RawForJson ModuleName.Raw
115+
116+
117+fromJson :: RawForJson -> ModuleName.Raw
118+fromJson (RawForJson raw) =
119+ raw
120+
121+
134instance Json.ToJSON RawForJson where
122instance Json.ToJSON RawForJson where
135 toJSON (RawForJson name) =
123 toJSON (RawForJson name) =
136 Json.toJSON (nameToString name)
124 Json.toJSON (nameToString name)
@@ -148,3 +136,11 @@ instance Json.FromJSON RawForJson where
148 parseJSON _ =
136 parseJSON _ =
149 fail "expecting the module name to be a string"
137 fail "expecting the module name to be a string"
150
138
139+
140+
141+-- CANONICAL NAMES
142+
143+
144+qualifiedVar :: ModuleName.Canonical -> Text -> Text
145+qualifiedVar =
146+ Gen.qualified
src/Elm/Compiler/Objects.hsnew file+11
@@ -0,0 +1,11 @@
1+{-# OPTIONS_GHC -Wall #-}
2+module Elm.Compiler.Objects
3+ ( Graph
4+ , union
5+ , Roots
6+ , main
7+ )
8+ where
9+
10+
11+import Elm.Compiler.Objects.Internal
src/Elm/Compiler/Objects/Internal.hsnew file+77
@@ -0,0 +1,77 @@
1+{-# OPTIONS_GHC -Wall #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+module Elm.Compiler.Objects.Internal
4+ ( Graph(..)
5+ , fromModule
6+ , union
7+ , Roots
8+ , main
9+ , toGlobals
10+ )
11+ where
12+
13+
14+import Control.Arrow (first)
15+import Data.Binary
16+import qualified Data.Map as Map
17+
18+import qualified AST.Expression.Optimized as Opt
19+import qualified AST.Module.Name as ModuleName
20+import qualified AST.Module as Module
21+import qualified AST.Variable as Var
22+import qualified Elm.Package as Pkg
23+
24+
25+
26+-- OBJECTS
27+
28+
29+newtype Graph =
30+ Graph (Map.Map Var.Global Opt.Decl)
31+
32+
33+
34+-- HELPERS
35+
36+
37+fromModule :: Module.Optimized -> Graph
38+fromModule (Module.Module home info) =
39+ Graph $ Map.fromList $
40+ map (first (Var.Global home)) (Module.program info)
41+
42+
43+union :: Graph -> Graph -> Graph
44+union (Graph objs1) (Graph objs2) =
45+ Graph (Map.union objs1 objs2)
46+
47+
48+
49+-- ROOTS
50+
51+
52+data Roots
53+ = Main ModuleName.Canonical
54+
55+
56+main :: Pkg.Name -> ModuleName.Raw -> Roots
57+main pkg name =
58+ Main (ModuleName.Canonical pkg name)
59+
60+
61+toGlobals :: Roots -> [Var.Global]
62+toGlobals roots =
63+ case roots of
64+ Main home ->
65+ [ Var.Global home "main" ]
66+
67+
68+
69+-- BINARY
70+
71+
72+instance Binary Graph where
73+ put (Graph dict) =
74+ put dict
75+
76+ get =
77+ Graph <$> get
src/Generate/JavaScript.hs+7−7
@@ -15,6 +15,7 @@ import qualified AST.Expression.Optimized as Opt
15import qualified AST.Module.Name as ModuleName
15import qualified AST.Module.Name as ModuleName
16import qualified AST.Variable as Var
16import qualified AST.Variable as Var
17import qualified Elm.Package as Pkg
17import qualified Elm.Package as Pkg
18+import qualified Elm.Compiler.Objects.Internal as Obj
18import qualified Generate.JavaScript.Builder as JS
19import qualified Generate.JavaScript.Builder as JS
19import qualified Generate.JavaScript.Expression as JS
20import qualified Generate.JavaScript.Expression as JS
20import qualified Generate.JavaScript.Helpers as JS
21import qualified Generate.JavaScript.Helpers as JS
@@ -25,15 +26,11 @@ import qualified Generate.JavaScript.Variable as JS
25-- GENERATE JAVASCRIPT
26-- GENERATE JAVASCRIPT
26
27
27
28
28−type Graph =
29− Map.Map Var.Global Opt.Decl
30−
31−
32−generate :: Graph -> [Var.Global] -> (Set.Set ModuleName.Canonical, BS.Builder)
29+generate :: Obj.Graph -> Obj.Roots -> (Set.Set ModuleName.Canonical, BS.Builder)
33−generate graph roots =
30+generate (Obj.Graph graph) roots =
34 let
31 let
35 (State builders _ natives effects) =
32 (State builders _ natives effects) =
36− List.foldl' (crawl graph) empty roots
33+ List.foldl' (crawl graph) empty (Obj.toGlobals roots)
37
34
38 managers =
35 managers =
39 Map.foldrWithKey addManager "" effects
36 Map.foldrWithKey addManager "" effects
@@ -66,6 +63,9 @@ empty =
66-- DEAD CODE ELIMINATION
63-- DEAD CODE ELIMINATION
67
64
68
65
66+type Graph = Map.Map Var.Global Opt.Decl
67+
68+
69crawl :: Graph -> State -> Var.Global -> State
69crawl :: Graph -> State -> Var.Global -> State
70crawl graph state@(State js seen natives effects) name@(Var.Global home _) =
70crawl graph state@(State js seen natives effects) name@(Var.Global home _) =
71 if Set.member name seen then
71 if Set.member name seen then