1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
13import Control.Monad.Trans (liftIO)
14import qualified Data.ByteString.Builder as B
15import qualified Data.Map as Map
16import Data.Monoid ((<>))
17import qualified System.Directory as Dir
18import qualified System.FilePath as FP
19import System.FilePath ((</>))
21import qualified Elm.Compiler.Module as Module
22import qualified Elm.Compiler.Objects as Obj
23import qualified Elm.Interface as I
24import qualified Elm.Name as N
25import qualified Elm.Package as Pkg
27import qualified Elm.Project.Json as Project
28import qualified Elm.Project.Summary as Summary
29import qualified File.Args as Args
30import qualified File.Crawl as Crawl
31import qualified File.IO as IO
32import qualified Generate.Functions as Functions
33import qualified Generate.Html as Html
34import qualified Reporting.Task as Task
35import qualified Stuff.Paths as Paths
36import Terminal.Args (Parser(..), suggestFiles)
46 , _target :: Obj.Target
47 , _output :: Maybe Output
51generate :: Options -> Summary.Summary -> Crawl.Result -> Task.Task ()
52generate options summary graph@(Crawl.Graph args _ _ _ _) =
57 Args.Roots name names ->
58 generateMonolith options summary graph (name:names)
65generateMonolith :: Options -> Summary.Summary -> Crawl.Result -> [Module.Raw] -> Task.Task ()
66generateMonolith (Options mode target maybeOutput) summary@(Summary.Summary _ project _ ifaces _) graph rootNames =
67 do let pkg = Project.getName project
68 let roots = map (Module.Canonical pkg) rootNames
69 objectGraph <- organize summary graph
70 case Obj.generate mode target ifaces objectGraph roots of
74 Obj.Some name names builder ->
77 "(function(scope){\n'use strict';"
78 <> Functions.functions <> builder <> "}(this));"
83 IO.writeBuilder "elm.js" monolith
88 Just (JavaScript maybeDir fileName) ->
89 do path <- toWritablePath maybeDir fileName
90 IO.writeBuilder path monolith
92 Just (Html maybeDir fileName) ->
95 do path <- toWritablePath maybeDir fileName
96 IO.writeBuilder path (Html.sandwich name monolith)
103-- GENERATE REPL MONOLITH
106generateReplFile :: Summary.Summary -> Crawl.Result -> I.Interface -> N.Name -> Task.Task FilePath
107generateReplFile summary@(Summary.Summary _ project _ _ _) graph iface name =
109 objectGraph <- organize summary graph
111 let home = Module.Canonical (Project.getName project) "Elm_Repl"
112 let builder = Obj.generateForRepl objectGraph iface home name
114 liftIO $ IO.writeBuilder Paths.temp $
115 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
120replRecovery :: B.Builder
122 "process.on('uncaughtException', function(err) { process.stderr.write(err.toString()); process.exit(1); });"
129organize :: Summary.Summary -> Crawl.Result -> Task.Task Obj.Graph
130organize (Summary.Summary root _ _ _ deps) (Crawl.Graph _ locals _ _ _) =
131 do localObjs <- Obj.unions <$> traverse (loadModuleObj root) (Map.keys locals)
132 foreignObjs <- Obj.unions <$> traverse loadPackageObj (Map.toList deps)
133 return (Obj.union localObjs foreignObjs)
136loadModuleObj :: FilePath -> Module.Raw -> Task.Task Obj.Graph
137loadModuleObj root name =
138 IO.readBinary (Paths.elmo root name)
141loadPackageObj :: ( Pkg.Name, (Pkg.Version, deps) ) -> Task.Task Obj.Graph
142loadPackageObj ( name, (version,_) ) =
143 do dir <- Task.getPackageCacheDirFor name version
144 IO.readBinary (dir </> "objs.dat")
153 | Html (Maybe FilePath) FilePath
154 | JavaScript (Maybe FilePath) FilePath
157toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
158toWritablePath maybeDir fileName =
164 do Dir.createDirectoryIfMissing True dir
165 return (dir </> fileName)
172output :: Parser Output
175 { _singular = "output file"
176 , _plural = "output files"
177 , _parser = parseOutput
178 , _suggest = suggestFiles ["js","html"]
179 , _examples = exampleOutput
183parseOutput :: String -> Maybe Output
185 if string == "/dev/null" || string == "NUL" || string == "$null" then
188 else if FP.takeExtension string == ".html" && length string > 5 then
189 splitOutput Html string
191 else if FP.takeExtension string == ".js" && length string > 3 then
192 splitOutput JavaScript string
198splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
199splitOutput toOutput string =
200 case FP.splitPath string of
205 Just $ toOutput Nothing name
208 Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
211exampleOutput :: String -> IO [String]
213 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