1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
15import Control.Concurrent.MVar (MVar, putMVar)
16import Control.Monad.Trans (liftIO)
17import qualified Data.ByteString.Builder as B
18import qualified Data.Map as Map
19import Data.Monoid ((<>))
20import qualified System.Directory as Dir
21import qualified System.FilePath as FP
22import System.FilePath ((</>))
24import qualified Elm.Compiler as Compiler
25import qualified Elm.Compiler.Module as Module
26import qualified Elm.Compiler.Objects as Obj
27import qualified Elm.Interface as I
28import qualified Elm.Name as N
29import qualified Elm.Package as Pkg
31import qualified AST.Module.Name as ModuleName
32import qualified Elm.Project.Json as Project
33import qualified Elm.Project.Summary as Summary
34import qualified File.Args as Args
35import qualified File.Crawl as Crawl
36import qualified File.IO as IO
37import qualified Generate.Functions as Functions
38import qualified Generate.Html as Html
39import qualified Generate.Nitpick as Nitpick
40import qualified Generate.JavaScript.Mode as Mode
41import qualified Reporting.Exit as Exit
42import qualified Reporting.Exit.Make as E
43import qualified Reporting.Render.Type.Localizer as L
44import qualified Reporting.Task as Task
45import qualified Stuff.Paths as Paths
46import Terminal.Args (Parser(..))
53data Mode = Debug | Dev | Prod
62 -> Map.Map Module.Raw Compiler.Artifacts
64generate mode target maybeOutput summary graph@(Crawl.Graph args locals _ _ _) artifacts =
69 Args.Roots name names ->
70 do objectGraph <- organize summary graph
75 do interfaces <- getInterfaces summary locals artifacts
76 return $ Mode.debug target interfaces
79 return $ Mode.dev target
82 do noDebugUses summary objectGraph
83 return $ Mode.prod target objectGraph
85 generateMonolith realMode maybeOutput summary objectGraph (name:names)
90 -> Map.Map Module.Raw a
91 -> Map.Map Module.Raw Compiler.Artifacts
92 -> Task.Task I.Interfaces
93getInterfaces (Summary.Summary root project _ interfaces _) locals artifacts =
96 Project.getName project
98 addArtifact home (Compiler.Artifacts elmi _ _) ifaces =
99 (ModuleName.Canonical pkg home, elmi) : ifaces
101 addInterface home iface ifaces =
102 (ModuleName.Canonical pkg home, iface) : ifaces
104 readInterface home _ =
105 IO.readBinary (Paths.elmi root home)
107 do cached <- Map.traverseWithKey readInterface (Map.difference locals artifacts)
109 Map.union interfaces $ Map.fromList $
110 Map.foldrWithKey addInterface (Map.foldrWithKey addArtifact [] artifacts) cached
124generateMonolith mode maybeOutput (Summary.Summary _ project _ _ _) graph rootNames =
125 do let pkg = Project.getName project
126 let roots = map (Module.Canonical pkg) rootNames
127 case Obj.generate mode graph roots of
131 Obj.Some name _names builder ->
134 "(function(scope){\n'use strict';"
135 <> Functions.functions <> builder <> "}(this));"
140 IO.writeBuilder "index.html" (Html.sandwich name monolith)
147 JavaScript maybeDir fileName ->
148 do path <- toWritablePath maybeDir fileName
149 IO.writeBuilder path monolith
152 putMVar mvar (Html.sandwich name monolith)
154 Html maybeDir fileName ->
155 do path <- toWritablePath maybeDir fileName
156 IO.writeBuilder path (Html.sandwich name monolith)
160-- GENERATE REPL MONOLITH
170 -> Task.Task FilePath
171generateReplFile noColors localizer summary@(Summary.Summary _ project _ _ _) graph iface name =
173 objectGraph <- organize summary graph
175 let home = Module.Canonical (Project.getName project) N.replModule
176 let builder = Obj.generateForRepl (not noColors) localizer objectGraph iface home name
178 liftIO $ IO.writeBuilder (Paths.temp "js") $
179 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
181 return (Paths.temp "js")
184replRecovery :: B.Builder
186 "process.on('uncaughtException', function(err) { process.stderr.write(err.toString()); process.exit(1); });"
193organize :: Summary.Summary -> Crawl.Result -> Task.Task Obj.Graph
194organize (Summary.Summary root _ _ _ deps) (Crawl.Graph _ locals _ _ _) =
195 do localObjs <- Obj.unions <$> traverse (loadModuleObj root) (Map.keys locals)
196 foreignObjs <- Obj.unions <$> traverse loadPackageObj (Map.toList deps)
197 return (Obj.union localObjs foreignObjs)
200loadModuleObj :: FilePath -> Module.Raw -> Task.Task Obj.Graph
201loadModuleObj root name =
202 IO.readBinary (Paths.elmo root name)
205loadPackageObj :: ( Pkg.Name, (Pkg.Version, deps) ) -> Task.Task Obj.Graph
206loadPackageObj ( name, (version,_) ) =
207 do dir <- Task.getPackageCacheDirFor name version
208 IO.readBinary (dir </> "objs.dat")
215noDebugUses :: Summary.Summary -> Obj.Graph -> Task.Task ()
216noDebugUses (Summary.Summary _ project _ _ _) graph =
217 case Nitpick.findDebugUses (Project.getName project) graph of
222 Task.throw (Exit.Make (E.CannotOptimizeDebugValues m ms))
225noDebugUsesInPackage :: Summary.Summary -> Crawl.Result -> Task.Task ()
226noDebugUsesInPackage summary graph =
227 noDebugUses summary =<< organize summary graph
236 | Html (Maybe FilePath) FilePath
237 | JavaScript (Maybe FilePath) FilePath
238 | HtmlBuilder (MVar B.Builder)
241toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
242toWritablePath maybeDir fileName =
248 do Dir.createDirectoryIfMissing True dir
249 return (dir </> fileName)
256output :: Parser Output
259 { _singular = "output file"
260 , _plural = "output files"
261 , _parser = parseOutput
262 , _suggest = \_ -> return []
263 , _examples = exampleOutput
267parseOutput :: String -> Maybe Output
269 if string == "/dev/null" || string == "NUL" || string == "$null" then
272 else if FP.takeExtension string == ".html" && length string > 5 then
273 splitOutput Html string
275 else if FP.takeExtension string == ".js" && length string > 3 then
276 splitOutput JavaScript string
282splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
283splitOutput toOutput string =
284 case FP.splitPath string of
289 Just $ toOutput Nothing name
292 Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
295exampleOutput :: String -> IO [String]
297 return [ "elm.js", "index.html", "/dev/null" ]
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