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
154 -> Task.Task FilePath
155generateReplFile noColors localizer summary@(Summary.Summary _ project _ _ _) graph iface name =
157 objectGraph <- organize summary graph
159 let home = Module.Canonical (Project.getName project) N.replModule
160 let builder = Obj.generateForRepl (not noColors) localizer objectGraph iface home name
162 liftIO $ IO.writeBuilder (Paths.temp "js") $
163 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
165 return (Paths.temp "js")
168replRecovery :: B.Builder
170 "process.on('uncaughtException', function(err) { process.stderr.write(err.toString()); process.exit(1); });"
177organize :: Summary.Summary -> Crawl.Result -> Task.Task Obj.Graph
178organize (Summary.Summary root _ _ _ deps) (Crawl.Graph _ locals _ _ _) =
179 do localObjs <- Obj.unions <$> traverse (loadModuleObj root) (Map.keys locals)
180 foreignObjs <- Obj.unions <$> traverse loadPackageObj (Map.toList deps)
181 return (Obj.union localObjs foreignObjs)
184loadModuleObj :: FilePath -> Module.Raw -> Task.Task Obj.Graph
185loadModuleObj root name =
186 IO.readBinary (Paths.elmo root name)
189loadPackageObj :: ( Pkg.Name, (Pkg.Version, deps) ) -> Task.Task Obj.Graph
190loadPackageObj ( name, (version,_) ) =
191 do dir <- Task.getPackageCacheDirFor name version
192 IO.readBinary (dir </> "objs.dat")
199noDebugUses :: Summary.Summary -> Obj.Graph -> Task.Task ()
200noDebugUses (Summary.Summary _ project _ _ _) graph =
201 case Nitpick.findDebugUses (Project.getName project) graph of
206 Task.throw (Exit.Make (E.CannotOptimizeDebugValues m ms))
209noDebugUsesInPackage :: Summary.Summary -> Crawl.Result -> Task.Task ()
210noDebugUsesInPackage summary graph =
211 noDebugUses summary =<< organize summary graph
220 | Html (Maybe FilePath) FilePath
221 | JavaScript (Maybe FilePath) FilePath
222 | HtmlBuilder (MVar B.Builder)
225toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
226toWritablePath maybeDir fileName =
232 do Dir.createDirectoryIfMissing True dir
233 return (dir </> fileName)
240output :: Parser Output
243 { _singular = "output file"
244 , _plural = "output files"
245 , _parser = parseOutput
246 , _suggest = \_ -> return []
247 , _examples = exampleOutput
251parseOutput :: String -> Maybe Output
253 if string == "/dev/null" || string == "NUL" || string == "$null" then
256 else if FP.takeExtension string == ".html" && length string > 5 then
257 splitOutput Html string
259 else if FP.takeExtension string == ".js" && length string > 3 then
260 splitOutput JavaScript string
266splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
267splitOutput toOutput string =
268 case FP.splitPath string of
273 Just $ toOutput Nothing name
276 Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
279exampleOutput :: String -> IO [String]
281 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