1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
13import Control.Monad.Trans (liftIO)
14import qualified Data.ByteString.Builder as B
15import qualified Data.List.NonEmpty as NonEmpty
16import qualified Data.Map as Map
17import Data.Monoid ((<>))
18import qualified System.Directory as Dir
19import qualified System.FilePath as FP
20import System.FilePath ((</>))
22import qualified Elm.Compiler.Module as Module
23import qualified Elm.Compiler.Objects as Obj
24import qualified Elm.Interface as I
25import qualified Elm.Name as N
26import qualified Elm.Package as Pkg
28import qualified Elm.Project.Json as Project
29import qualified Elm.Project.Summary as Summary
30import qualified File.Args as Args
31import qualified File.Crawl as Crawl
32import qualified File.IO as IO
33import qualified Generate.Functions as Functions
34import qualified Generate.Html as Html
35import qualified Reporting.Task as Task
36import qualified Stuff.Paths as Paths
37import Terminal.Args (Parser(..), suggestFiles)
47 , _target :: Obj.Target
48 , _output :: Maybe Output
52generate :: Options -> Summary.Summary -> Crawl.Result -> Task.Task ()
53generate options summary graph@(Crawl.Graph args _ _ _ _) =
59 generateMonolith options summary graph (NonEmpty.toList names)
66generateMonolith :: Options -> Summary.Summary -> Crawl.Result -> [Module.Raw] -> Task.Task ()
67generateMonolith (Options debug target maybeOutput) summary@(Summary.Summary _ project _ ifaces _) graph rootNames =
68 do let pkg = Project.getName project
69 let roots = map (Module.Canonical pkg) rootNames
70 objectGraph <- organize summary graph
71 case Obj.generate debug target ifaces objectGraph roots of
75 Obj.Some name names builder ->
78 "(function(scope){\n'use strict';"
79 <> Functions.functions <> builder <> "}(this));"
84 IO.writeBuilder "elm.js" monolith
89 Just (JavaScript maybeDir fileName) ->
90 do path <- toWritablePath maybeDir fileName
91 IO.writeBuilder path monolith
93 Just (Html maybeDir fileName) ->
96 do path <- toWritablePath maybeDir fileName
97 IO.writeBuilder path (Html.sandwich name monolith)
104-- GENERATE REPL MONOLITH
107generateReplFile :: Summary.Summary -> Crawl.Result -> I.Interface -> N.Name -> Task.Task FilePath
108generateReplFile summary@(Summary.Summary _ project _ _ _) graph iface name =
110 objectGraph <- organize summary graph
112 let home = Module.Canonical (Project.getName project) "Elm_Repl"
113 let builder = Obj.generateForRepl objectGraph iface home name
115 liftIO $ IO.writeBuilder Paths.temp $
116 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
121replRecovery :: B.Builder
123 "process.on('uncaughtException', function(err) { process.stderr.write(err.toString()); process.exit(1); });"
130organize :: Summary.Summary -> Crawl.Result -> Task.Task Obj.Graph
131organize (Summary.Summary root _ _ _ deps) (Crawl.Graph _ locals _ _ _) =
132 do localObjs <- Obj.unions <$> traverse (loadModuleObj root) (Map.keys locals)
133 foreignObjs <- Obj.unions <$> traverse loadPackageObj (Map.toList deps)
134 return (Obj.union localObjs foreignObjs)
137loadModuleObj :: FilePath -> Module.Raw -> Task.Task Obj.Graph
138loadModuleObj root name =
139 IO.readBinary (Paths.elmo root name)
142loadPackageObj :: ( Pkg.Name, (Pkg.Version, deps) ) -> Task.Task Obj.Graph
143loadPackageObj ( name, (version,_) ) =
144 do dir <- Task.getPackageCacheDirFor name version
145 IO.readBinary (dir </> "objs.dat")
154 | Html (Maybe FilePath) FilePath
155 | JavaScript (Maybe FilePath) FilePath
158toWritablePath :: Maybe FilePath -> FilePath -> IO FilePath
159toWritablePath maybeDir fileName =
165 do Dir.createDirectoryIfMissing True dir
166 return (dir </> fileName)
173output :: Parser Output
176 { _singular = "output file"
177 , _plural = "output files"
178 , _parser = parseOutput
179 , _suggest = suggestFiles ["js","html"]
180 , _examples = exampleOutput
184parseOutput :: String -> Maybe Output
186 if string == "/dev/null" || string == "NUL" || string == "$null" then
189 else if FP.takeExtension string == ".html" && length string > 5 then
190 splitOutput Html string
192 else if FP.takeExtension string == ".js" && length string > 3 then
193 splitOutput JavaScript string
199splitOutput :: (Maybe FilePath -> FilePath -> Output) -> String -> Maybe Output
200splitOutput toOutput string =
201 case FP.splitPath string of
206 Just $ toOutput Nothing name
209 Just $ toOutput (Just (FP.joinPath (init segments))) (last segments)
212exampleOutput :: String -> IO [String]
214 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