1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
14import Control.Concurrent.MVar (MVar, putMVar)
15import Control.Monad.Trans (liftIO)
16import qualified Data.ByteString.Builder as B
17import qualified Data.Map as Map
18import Data.Monoid ((<>))
19import qualified System.Directory as Dir
20import qualified System.FilePath as FP
21import System.FilePath ((</>))
23import qualified Elm.Compiler.Module as Module
24import qualified Elm.Compiler.Objects as Obj
25import qualified Elm.Interface as I
26import qualified Elm.Name as N
27import qualified Elm.Package as Pkg
29import qualified Elm.Project.Json as Project
30import qualified Elm.Project.Summary as Summary
31import qualified File.Args as Args
32import qualified File.Crawl as Crawl
33import qualified File.IO as IO
34import qualified Generate.Functions as Functions
35import qualified Generate.Html as Html
36import qualified Generate.Nitpick as Nitpick
37import qualified Reporting.Exit as Exit
38import qualified Reporting.Exit.Make as E
39import qualified Reporting.Task as Task
40import qualified Stuff.Paths as Paths
41import Terminal.Args (Parser(..))
51 , _target :: Obj.Target
52 , _output :: Maybe Output
56generate :: Options -> Summary.Summary -> Crawl.Result -> Task.Task ()
57generate options summary graph@(Crawl.Graph args _ _ _ _) =
62 Args.Roots name names ->
63 do objectGraph <- organize summary graph
66 Obj.Debug -> return ()
68 Obj.Prod -> noDebugUses summary objectGraph
70 generateMonolith options summary objectGraph (name:names)
77generateMonolith :: Options -> Summary.Summary -> Obj.Graph -> [Module.Raw] -> Task.Task ()
78generateMonolith (Options mode target maybeOutput) (Summary.Summary _ project _ ifaces _) graph rootNames =
79 do let pkg = Project.getName project
80 let roots = map (Module.Canonical pkg) rootNames
81 case Obj.generate mode target ifaces graph roots of
85 Obj.Some name _names builder ->
88 "(function(scope){\n'use strict';"
89 <> Functions.functions <> builder <> "}(this));"
94 IO.writeBuilder "elm.js" monolith
101 JavaScript maybeDir fileName ->
102 do path <- toWritablePath maybeDir fileName
103 IO.writeBuilder path monolith
106 putMVar mvar (Html.sandwich name monolith)
108 Html maybeDir fileName ->
109 do path <- toWritablePath maybeDir fileName
110 IO.writeBuilder path (Html.sandwich name monolith)
114-- GENERATE REPL MONOLITH
117generateReplFile :: Summary.Summary -> Crawl.Result -> I.Interface -> N.Name -> Task.Task FilePath
118generateReplFile summary@(Summary.Summary _ project _ _ _) graph iface name =
120 objectGraph <- organize summary graph
122 let home = Module.Canonical (Project.getName project) "Elm_Repl"
123 let builder = Obj.generateForRepl objectGraph iface home name
125 liftIO $ IO.writeBuilder (Paths.temp "js") $
126 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
128 return (Paths.temp "js")
131replRecovery :: B.Builder
133 "process.on('uncaughtException', function(err) { process.stderr.write(err.toString()); process.exit(1); });"
140organize :: Summary.Summary -> Crawl.Result -> Task.Task Obj.Graph
141organize (Summary.Summary root _ _ _ deps) (Crawl.Graph _ locals _ _ _) =
142 do localObjs <- Obj.unions <$> traverse (loadModuleObj root) (Map.keys locals)
143 foreignObjs <- Obj.unions <$> traverse loadPackageObj (Map.toList deps)
144 return (Obj.union localObjs foreignObjs)
147loadModuleObj :: FilePath -> Module.Raw -> Task.Task Obj.Graph
148loadModuleObj root name =
149 IO.readBinary (Paths.elmo root name)
152loadPackageObj :: ( Pkg.Name, (Pkg.Version, deps) ) -> Task.Task Obj.Graph
153loadPackageObj ( name, (version,_) ) =
154 do dir <- Task.getPackageCacheDirFor name version
155 IO.readBinary (dir </> "objs.dat")
162noDebugUses :: Summary.Summary -> Obj.Graph -> Task.Task ()
163noDebugUses (Summary.Summary _ project _ _ _) graph =
164 case Nitpick.findDebugUses (Project.getName project) graph of
169 Task.throw (Exit.Make (E.CannotOptimizeDebugValues m ms))
172noDebugUsesInPackage :: Summary.Summary -> Crawl.Result -> Task.Task ()
173noDebugUsesInPackage summary graph =
174 noDebugUses summary =<< organize summary graph
183 | Html (Maybe FilePath) FilePath
184 | JavaScript (Maybe FilePath) FilePath
185 | HtmlBuilder (MVar B.Builder)
188toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
189toWritablePath maybeDir fileName =
195 do Dir.createDirectoryIfMissing True dir
196 return (dir </> fileName)
203output :: Parser Output
206 { _singular = "output file"
207 , _plural = "output files"
208 , _parser = parseOutput
209 , _suggest = \_ -> return []
210 , _examples = exampleOutput
214parseOutput :: String -> Maybe Output
216 if string == "/dev/null" || string == "NUL" || string == "$null" then
219 else if FP.takeExtension string == ".html" && length string > 5 then
220 splitOutput Html string
222 else if FP.takeExtension string == ".js" && length string > 3 then
223 splitOutput JavaScript string
229splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
230splitOutput toOutput string =
231 case FP.splitPath string of
236 Just $ toOutput Nothing name
239 Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
242exampleOutput :: String -> IO [String]
244 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