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 _ _ _ _) artifacts =
69 Args.Roots name names ->
70 do objectGraph <- organize summary graph
75 return $ Mode.debug target (getInterfaces summary artifacts)
78 return $ Mode.dev target
81 do noDebugUses summary objectGraph
82 return $ Mode.prod target objectGraph
84 generateMonolith realMode maybeOutput summary objectGraph (name:names)
87getInterfaces :: Summary.Summary -> Map.Map Module.Raw Compiler.Artifacts -> I.Interfaces
88getInterfaces (Summary.Summary _ project _ interfaces _) artifacts =
90 pkg = Project.getName project
91 addArtifact home (Compiler.Artifacts elmi _ _) ifaces =
92 Map.insert (ModuleName.Canonical pkg home) elmi ifaces
94 Map.foldrWithKey addArtifact interfaces artifacts
108generateMonolith mode maybeOutput (Summary.Summary _ project _ _ _) graph rootNames =
109 do let pkg = Project.getName project
110 let roots = map (Module.Canonical pkg) rootNames
111 case Obj.generate mode graph roots of
115 Obj.Some name _names builder ->
118 "(function(scope){\n'use strict';"
119 <> Functions.functions <> builder <> "}(this));"
124 IO.writeBuilder "elm.js" monolith
131 JavaScript maybeDir fileName ->
132 do path <- toWritablePath maybeDir fileName
133 IO.writeBuilder path monolith
136 putMVar mvar (Html.sandwich name monolith)
138 Html maybeDir fileName ->
139 do path <- toWritablePath maybeDir fileName
140 IO.writeBuilder path (Html.sandwich name monolith)
144-- GENERATE REPL MONOLITH
153 -> Task.Task FilePath
154generateReplFile localizer summary@(Summary.Summary _ project _ _ _) graph iface name =
156 objectGraph <- organize summary graph
158 let home = Module.Canonical (Project.getName project) N.replModule
159 let builder = Obj.generateForRepl True localizer objectGraph iface home name
161 liftIO $ IO.writeBuilder (Paths.temp "js") $
162 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
164 return (Paths.temp "js")
167replRecovery :: B.Builder
169 "process.on('uncaughtException', function(err) { process.stderr.write(err.toString()); process.exit(1); });"
176organize :: Summary.Summary -> Crawl.Result -> Task.Task Obj.Graph
177organize (Summary.Summary root _ _ _ deps) (Crawl.Graph _ locals _ _ _) =
178 do localObjs <- Obj.unions <$> traverse (loadModuleObj root) (Map.keys locals)
179 foreignObjs <- Obj.unions <$> traverse loadPackageObj (Map.toList deps)
180 return (Obj.union localObjs foreignObjs)
183loadModuleObj :: FilePath -> Module.Raw -> Task.Task Obj.Graph
184loadModuleObj root name =
185 IO.readBinary (Paths.elmo root name)
188loadPackageObj :: ( Pkg.Name, (Pkg.Version, deps) ) -> Task.Task Obj.Graph
189loadPackageObj ( name, (version,_) ) =
190 do dir <- Task.getPackageCacheDirFor name version
191 IO.readBinary (dir </> "objs.dat")
198noDebugUses :: Summary.Summary -> Obj.Graph -> Task.Task ()
199noDebugUses (Summary.Summary _ project _ _ _) graph =
200 case Nitpick.findDebugUses (Project.getName project) graph of
205 Task.throw (Exit.Make (E.CannotOptimizeDebugValues m ms))
208noDebugUsesInPackage :: Summary.Summary -> Crawl.Result -> Task.Task ()
209noDebugUsesInPackage summary graph =
210 noDebugUses summary =<< organize summary graph
219 | Html (Maybe FilePath) FilePath
220 | JavaScript (Maybe FilePath) FilePath
221 | HtmlBuilder (MVar B.Builder)
224toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
225toWritablePath maybeDir fileName =
231 do Dir.createDirectoryIfMissing True dir
232 return (dir </> fileName)
239output :: Parser Output
242 { _singular = "output file"
243 , _plural = "output files"
244 , _parser = parseOutput
245 , _suggest = \_ -> return []
246 , _examples = exampleOutput
250parseOutput :: String -> Maybe Output
252 if string == "/dev/null" || string == "NUL" || string == "$null" then
255 else if FP.takeExtension string == ".html" && length string > 5 then
256 splitOutput Html string
258 else if FP.takeExtension string == ".js" && length string > 3 then
259 splitOutput JavaScript string
265splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
266splitOutput toOutput string =
267 case FP.splitPath string of
272 Just $ toOutput Nothing name
275 Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
278exampleOutput :: String -> IO [String]
280 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