1{-# LANGUAGE BangPatterns #-}
11import Prelude hiding (cycle, print)
12import Control.Concurrent (MVar, forkIO, newEmptyMVar, newMVar, putMVar, readMVar)
13import Control.Monad (liftM2)
14import qualified Data.ByteString.Builder as B
16import qualified Data.Map as Map
17import qualified Data.Maybe as Maybe
18import qualified Data.Name as N
19import qualified Data.NonEmptyList as NE
21import qualified AST.Optimized as Opt
23import qualified Elm.Compiler.Type.Extract as Extract
24import qualified Elm.Details as Details
25import qualified Elm.Interface as I
26import qualified Elm.ModuleName as ModuleName
27import qualified Elm.Package as Pkg
29import qualified Generate.JavaScript as JS
30import qualified Generate.Mode as Mode
31import qualified Nitpick.Debug as Nitpick
32import qualified Reporting.Exit as Exit
33import qualified Reporting.Task as Task
37-- NOTE: This is used by Make, Repl, and Reactor right now. But it may be
38-- desireable to have Repl and Reactor to keep foreign objects in memory
39-- to make things a bit faster?
47 Task.Task Exit.Generate a
50debug :: FilePath -> Details.Details -> Build.Artifacts -> Task B.Builder
51debug root details (Build.Artifacts pkg ifaces roots modules) =
52 do loading <- loadObjects root details modules
53 types <- loadTypes root ifaces modules
54 objects <- finalizeObjects loading
55 let mode = Mode.Dev (Just types)
56 let graph = objectsToGlobalGraph objects
57 let mains = gatherMains pkg objects roots
58 return $ JS.generate mode graph mains
61dev :: FilePath -> Details.Details -> Build.Artifacts -> Task B.Builder
62dev root details (Build.Artifacts pkg _ roots modules) =
63 do objects <- finalizeObjects =<< loadObjects root details modules
64 let mode = Mode.Dev Nothing
65 let graph = objectsToGlobalGraph objects
66 let mains = gatherMains pkg objects roots
67 return $ JS.generate mode graph mains
70prod :: FilePath -> Details.Details -> Build.Artifacts -> Task B.Builder
71prod root details (Build.Artifacts pkg _ roots modules) =
72 do objects <- finalizeObjects =<< loadObjects root details modules
73 checkForDebugUses objects
74 let graph = objectsToGlobalGraph objects
75 let mode = Mode.Prod (Mode.shortenFieldNames graph)
76 let mains = gatherMains pkg objects roots
77 return $ JS.generate mode graph mains
80repl :: FilePath -> Details.Details -> Bool -> Build.ReplArtifacts -> N.Name -> Task B.Builder
81repl root details ansi (Build.ReplArtifacts home modules localizer annotations) name =
82 do objects <- finalizeObjects =<< loadObjects root details modules
83 let graph = objectsToGlobalGraph objects
84 return $ JS.generateForRepl ansi localizer graph home name (annotations ! name)
91checkForDebugUses :: Objects -> Task ()
92checkForDebugUses (Objects _ locals) =
93 case Map.keys (Map.filter Nitpick.hasDebugUses locals) of
95 m:ms -> Task.throw (Exit.GenerateCannotOptimizeDebugValues m ms)
102gatherMains :: Pkg.Name -> Objects -> NE.List Build.Root -> Map.Map ModuleName.Canonical Opt.Main
103gatherMains pkg (Objects _ locals) roots =
104 Map.fromList $ Maybe.mapMaybe (lookupMain pkg locals) (NE.toList roots)
107lookupMain :: Pkg.Name -> Map.Map ModuleName.Raw Opt.LocalGraph -> Build.Root -> Maybe (ModuleName.Canonical, Opt.Main)
108lookupMain pkg locals root =
110 toPair name (Opt.LocalGraph maybeMain _ _) =
111 (,) (ModuleName.Canonical pkg name) <$> maybeMain
114 Build.Inside name -> toPair name =<< Map.lookup name locals
115 Build.Outside name _ g -> toPair name g
124 { _foreign_mvar :: MVar (Maybe Opt.GlobalGraph)
125 , _local_mvars :: Map.Map ModuleName.Raw (MVar (Maybe Opt.LocalGraph))
129loadObjects :: FilePath -> Details.Details -> [Build.Module] -> Task LoadingObjects
130loadObjects root details modules =
132 do mvar <- Details.loadObjects root details
133 mvars <- traverse (loadObject root) modules
134 return $ LoadingObjects mvar (Map.fromList mvars)
137loadObject :: FilePath -> Build.Module -> IO (ModuleName.Raw, MVar (Maybe Opt.LocalGraph))
138loadObject root modul =
140 Build.Fresh name _ graph ->
141 do mvar <- newMVar (Just graph)
144 Build.Cached name _ _ ->
145 do mvar <- newEmptyMVar
146 _ <- forkIO $ putMVar mvar =<< File.readBinary (Stuff.elmo root name)
156 { _foreign :: Opt.GlobalGraph
157 , _locals :: Map.Map ModuleName.Raw Opt.LocalGraph
161finalizeObjects :: LoadingObjects -> Task Objects
162finalizeObjects (LoadingObjects mvar mvars) =
164 do result <- readMVar mvar
165 results <- traverse readMVar mvars
166 case liftM2 Objects result (sequence results) of
167 Just loaded -> return (Right loaded)
168 Nothing -> return (Left Exit.GenerateCannotLoadArtifacts)
171objectsToGlobalGraph :: Objects -> Opt.GlobalGraph
172objectsToGlobalGraph (Objects globals locals) =
173 foldr Opt.addLocalGraph globals locals
180loadTypes :: FilePath -> Map.Map ModuleName.Canonical I.DependencyInterface -> [Build.Module] -> Task Extract.Types
181loadTypes root ifaces modules =
183 do mvars <- traverse (loadTypesHelp root) modules
184 let !foreigns = Extract.mergeMany (Map.elems (Map.mapWithKey Extract.fromDependencyInterface ifaces))
185 results <- traverse readMVar mvars
186 case sequence results of
187 Just ts -> return (Right (Extract.merge foreigns (Extract.mergeMany ts)))
188 Nothing -> return (Left Exit.GenerateCannotLoadArtifacts)
191loadTypesHelp :: FilePath -> Build.Module -> IO (MVar (Maybe Extract.Types))
192loadTypesHelp root modul =
194 Build.Fresh name iface _ ->
195 newMVar (Just (Extract.fromInterface name iface))
197 Build.Cached name _ ciMVar ->
198 do cachedInterface <- readMVar ciMVar
199 case cachedInterface of
201 do mvar <- newEmptyMVar
203 do maybeIface <- File.readBinary (Stuff.elmi root name)
204 putMVar mvar (Extract.fromInterface name <$> maybeIface)
207 Build.Loaded iface ->
208 newMVar (Just (Extract.fromInterface name iface))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list