on master help sign in
Elm.Compiler now exposes an opaque Obj.Graph

This is so only the compiler knows how to deal with object graphs. Folks outside can only union these graphs and convert them to binary for caching.

commit6eaff9e863d1ac88fc38f24c28731a2a41257505 authorEvan Czaplicki <evancz@users.noreply.github.com> dateTue 28 Mar 2017, 20:18 (10 years ago) parenteb30f83
6 files changed+164−78
elm-compiler.cabal+48−46 src/Elm/Compiler.hs+4−4 src/Elm/Compiler/Module.hs+17−21 src/Elm/Compiler/Objects.hs+11 src/Elm/Compiler/Objects/Internal.hs+77 src/Generate/JavaScript.hs+7−7
elm-compiler.cabal+48−46
@@ -42,7 +42,7 @@ Library
4242 if flag(dev)
4343 ghc-options: -O0 -W -Werror
4444 else
45− ghc-options: -O2
45+ ghc-options: -O2 -fsimpl-tick-factor=200
4646
4747 Hs-Source-Dirs:
4848 src
@@ -50,6 +50,7 @@ Library
5050 exposed-modules:
5151 Elm.Compiler,
5252 Elm.Compiler.Module,
53+ Elm.Compiler.Objects,
5354 Elm.Compiler.Type,
5455 Elm.Docs,
5556 Elm.Package,
@@ -83,6 +84,7 @@ Library
8384 Docs.Centralize,
8485 Docs.Check,
8586 Elm.Compiler.Imports,
87+ Elm.Compiler.Objects.Internal,
8688 Elm.Compiler.Type.Extract,
8789 Elm.Compiler.Version,
8890 Generate.JavaScript,
@@ -160,48 +162,48 @@ Library
160162 union-find >= 0.2 && < 0.3
161163
162164
163−Test-Suite compiler-tests
164− ghc-options:
165− -O0
166−
167− Type:
168− exitcode-stdio-1.0
169−
170− Hs-Source-Dirs:
171− tests, src
172−
173− Main-is:
174− Test.hs
175−
176− other-modules:
177− Test.Compiler
178− Test.Property
179− Test.Property.Arbitrary
180− AST.Helpers
181− AST.Literal
182−
183− build-depends:
184− test-framework > 0.8 && < 0.9,
185− test-framework-hunit >= 0.3 && < 0.4,
186− test-framework-quickcheck2 >= 0.3 && < 0.4,
187− HUnit >= 1.1 && < 2,
188− QuickCheck >= 2 && < 3,
189− aeson >= 0.11,
190− aeson-pretty >= 0.8 && < 0.9,
191− ansi-terminal >= 0.6.2.1 && < 0.7,
192− ansi-wl-pprint >= 0.6.7 && < 0.7,
193− base >=4.2 && <5,
194− binary >= 0.7.0.0 && < 0.8,
195− bytestring >= 0.9 && < 0.11,
196− containers >= 0.3 && < 0.6,
197− directory >= 1.0 && < 2.0,
198− edit-distance >= 0.2 && < 0.3,
199− filemanip >= 0.3.5 && < 0.4,
200− filepath >= 1 && < 2.0,
201− language-glsl >= 0.0.2 && < 0.3,
202− mtl >= 2.2 && < 3,
203− parsec,
204− pretty >= 1.0 && < 2.0,
205− process,
206− text >= 1 && < 2,
207− union-find >= 0.2 && < 0.3
165+--Test-Suite compiler-tests
166+-- ghc-options:
167+-- -O0
168+--
169+-- Type:
170+-- exitcode-stdio-1.0
171+--
172+-- Hs-Source-Dirs:
173+-- tests, src
174+--
175+-- Main-is:
176+-- Test.hs
177+--
178+-- other-modules:
179+-- Test.Compiler
180+-- Test.Property
181+-- Test.Property.Arbitrary
182+-- AST.Helpers
183+-- AST.Literal
184+--
185+-- build-depends:
186+-- test-framework > 0.8 && < 0.9,
187+-- test-framework-hunit >= 0.3 && < 0.4,
188+-- test-framework-quickcheck2 >= 0.3 && < 0.4,
189+-- HUnit >= 1.1 && < 2,
190+-- QuickCheck >= 2 && < 3,
191+-- aeson >= 0.11,
192+-- aeson-pretty >= 0.8 && < 0.9,
193+-- ansi-terminal >= 0.6.2.1 && < 0.7,
194+-- ansi-wl-pprint >= 0.6.7 && < 0.7,
195+-- base >=4.2 && <5,
196+-- binary >= 0.7.0.0 && < 0.8,
197+-- bytestring >= 0.9 && < 0.11,
198+-- containers >= 0.3 && < 0.6,
199+-- directory >= 1.0 && < 2.0,
200+-- edit-distance >= 0.2 && < 0.3,
201+-- filemanip >= 0.3.5 && < 0.4,
202+-- filepath >= 1 && < 2.0,
203+-- language-glsl >= 0.0.2 && < 0.3,
204+-- mtl >= 2.2 && < 3,
205+-- parsec,
206+-- pretty >= 1.0 && < 2.0,
207+-- process,
208+-- text >= 1 && < 2,
209+-- union-find >= 0.2 && < 0.3
src/Elm/Compiler.hs+4−4
@@ -17,13 +17,13 @@ import Data.Text (Text)
1717import qualified Data.ByteString.Builder as BS
1818import Text.PrettyPrint.ANSI.Leijen (Doc)
1919
20−import qualified AST.Expression.Optimized as Opt
2120import qualified AST.Module as Module
2221import qualified AST.Module.Name as ModuleName
2322import qualified Compile
2423import qualified Docs.Check as Docs
2524import qualified Elm.Compiler.Imports as Imports
2625import qualified Elm.Compiler.Module as M
26+import qualified Elm.Compiler.Objects.Internal as Obj
2727import qualified Elm.Compiler.Version
2828import qualified Elm.Docs as Docs
2929import qualified Elm.Package as Package
@@ -104,7 +104,7 @@ compile context source =
104104 docs <- Result.format id (docsGen exposed modul)
105105
106106 let iface = Module.toInterface modul
107− let objs = Module.program (Module.info modul)
107+ let objs = Obj.fromModule modul
108108
109109 return (Result docs iface objs)
110110 in
@@ -127,7 +127,7 @@ data Result =
127127 Result
128128 { _docs :: Maybe Docs.Documentation
129129 , _iface :: M.Interface
130− , _objs :: [(Text, Opt.Decl)]
130+ , _objs :: Obj.Graph
131131 }
132132
133133
@@ -152,7 +152,7 @@ docsGen isExposed (Module.Module name info) =
152152-- CODE GENERATION
153153
154154
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)
156156generate =
157157 JS.generate
158158
src/Elm/Compiler/Module.hs+17−21
@@ -21,9 +21,6 @@ module Elm.Compiler.Module
2121 -- canonical names
2222 , ModuleName.Canonical(..)
2323 , qualifiedVar
24−
25− -- variables
26− , Var.Global(..)
2724 )
2825 where
2926
@@ -37,7 +34,6 @@ import System.FilePath ((</>))
3734
3835import qualified AST.Module as Module
3936import qualified AST.Module.Name as ModuleName
40−import qualified AST.Variable as Var
4137import qualified Elm.Compiler.Type as PublicType
4238import qualified Elm.Compiler.Type.Extract as Extract
4339import qualified Generate.JavaScript.Variable as Gen
@@ -61,23 +57,6 @@ programTypes =
6157-- NAMES
6258
6359
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−
8160nameToPath :: ModuleName.Raw -> FilePath
8261nameToPath name =
8362 List.foldl1 (</>) (map Text.unpack (Text.splitOn "." name))
@@ -131,6 +110,15 @@ isGoodChar char =
131110-- JSON for NAME
132111
133112
113+newtype RawForJson =
114+ RawForJson ModuleName.Raw
115+
116+
117+fromJson :: RawForJson -> ModuleName.Raw
118+fromJson (RawForJson raw) =
119+ raw
120+
121+
134122instance Json.ToJSON RawForJson where
135123 toJSON (RawForJson name) =
136124 Json.toJSON (nameToString name)
@@ -148,3 +136,11 @@ instance Json.FromJSON RawForJson where
148136 parseJSON _ =
149137 fail "expecting the module name to be a string"
150138
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
1515import qualified AST.Module.Name as ModuleName
1616import qualified AST.Variable as Var
1717import qualified Elm.Package as Pkg
18+import qualified Elm.Compiler.Objects.Internal as Obj
1819import qualified Generate.JavaScript.Builder as JS
1920import qualified Generate.JavaScript.Expression as JS
2021import qualified Generate.JavaScript.Helpers as JS
@@ -25,15 +26,11 @@ import qualified Generate.JavaScript.Variable as JS
2526-- GENERATE JAVASCRIPT
2627
2728
28−type Graph =
29− Map.Map Var.Global Opt.Decl
30−
31−
32−generate :: Graph -> [Var.Global] -> (Set.Set ModuleName.Canonical, BS.Builder)
33−generate graph roots =
29+generate :: Obj.Graph -> Obj.Roots -> (Set.Set ModuleName.Canonical, BS.Builder)
30+generate (Obj.Graph graph) roots =
3431 let
3532 (State builders _ natives effects) =
36− List.foldl' (crawl graph) empty roots
33+ List.foldl' (crawl graph) empty (Obj.toGlobals roots)
3734
3835 managers =
3936 Map.foldrWithKey addManager "" effects
@@ -66,6 +63,9 @@ empty =
6663-- DEAD CODE ELIMINATION
6764
6865
66+type Graph = Map.Map Var.Global Opt.Decl
67+
68+
6969crawl :: Graph -> State -> Var.Global -> State
7070crawl graph state@(State js seen natives effects) name@(Var.Global home _) =
7171 if Set.member name seen then