@@ -24,8 +24,8 @@ module Language.PureScript.Make
25 -- * Make API
25 -- * Make API
26 RebuildPolicy(..)
26 RebuildPolicy(..)
27+ , ProgressMessage(..), renderProgressMessage
27 , MakeActions(..)
28 , MakeActions(..)
29 , Externs()
29 , Externs()
@@ -43,7 +43,6 @@ import Control.Monad.Trans.Except
43import Control.Monad.Reader
43import Control.Monad.Reader
44import Control.Monad.Writer
44import Control.Monad.Writer
45import Control.Monad.Supply
45import Control.Monad.Supply
46−import Control.Monad.Supply.Class (fresh)
48import Data.Function (on)
47import Data.Function (on)
49import Data.List (sortBy, groupBy)
48import Data.List (sortBy, groupBy)
@@ -79,8 +78,22 @@ import qualified Language.PureScript.CodeGen.JS as J
79import qualified Language.PureScript.CoreFn as CF
78import qualified Language.PureScript.CoreFn as CF
80import qualified Paths_purescript as Paths
79import qualified Paths_purescript as Paths
82−-- |
81+-- | Progress messages from the make process
83+ = CompilingModule ModuleName
84+ deriving (Show, Eq, Ord)
86+-- | Render a progress message
87+renderProgressMessage :: ProgressMessage -> String
88+renderProgressMessage (CompilingModule mn) = "Compiling " ++ runModuleName mn
83−-- Actions that require implementations when running in "make" mode.
90+-- | Actions that require implementations when running in "make" mode.
92+-- This type exists to make two things abstract:
94+-- * The particular backend being used (Javascript, C++11, etc.)
96+-- * The details of how files are read/written etc.
85data MakeActions m = MakeActions {
98data MakeActions m = MakeActions {
@@ -102,11 +115,11 @@ data MakeActions m = MakeActions {
103 -- Run the code generator for the module and write any required output files.
116 -- Run the code generator for the module and write any required output files.
105− , codegen :: CF.Module CF.Ann -> Environment -> SupplyVar -> Externs -> m ()
118+ , codegen :: CF.Module CF.Ann -> Environment -> Externs -> SupplyT m ()
107 -- Respond to a progress update.
120 -- Respond to a progress update.
109− , progress :: String -> m ()
122+ , progress :: ProgressMessage -> m ()
@@ -114,11 +127,6 @@ data MakeActions m = MakeActions {
115type Externs = String
128type Externs = String
118−-- A value to be used in the Supply monad.
120−type SupplyVar = Integer
123-- Determines when to rebuild a module
131-- Determines when to rebuild a module
@@ -160,7 +168,7 @@ make MakeActions{..} ms = do
160 (_, env') <- lift . runCheck' env $ typeCheckModule Nothing m
168 (_, env') <- lift . runCheck' env $ typeCheckModule Nothing m
161 go env' ms'
169 go env' ms'
162 go env ((True, m@(Module coms moduleName' _ exps)) : ms') = do
170 go env ((True, m@(Module coms moduleName' _ exps)) : ms') = do
163− lift $ progress $ "Compiling " ++ runModuleName moduleName'
171+ lift . progress $ CompilingModule moduleName'
164 (checked@(Module _ _ elaborated _), env') <- lift . runCheck' env $ typeCheckModule Nothing m
172 (checked@(Module _ _ elaborated _), env') <- lift . runCheck' env $ typeCheckModule Nothing m
165 checkExhaustiveModule env' checked
173 checkExhaustiveModule env' checked
166 regrouped <- createBindingGroups moduleName' . collapseBindingGroups $ elaborated
174 regrouped <- createBindingGroups moduleName' . collapseBindingGroups $ elaborated
@@ -168,8 +176,7 @@ make MakeActions{..} ms = do
168 corefn = CF.moduleToCoreFn env' mod'
176 corefn = CF.moduleToCoreFn env' mod'
169 [renamed] = renameInModules [corefn]
177 [renamed] = renameInModules [corefn]
170 exts = moduleToPs mod' env'
178 exts = moduleToPs mod' env'
172− lift $ codegen renamed env' nextVar exts
179+ codegen renamed env' exts
173 go env' ms'
180 go env' ms'
175 rebuildIfNecessary :: M.Map ModuleName [ModuleName] -> S.Set ModuleName -> [Module] -> m [(Bool, Module)]
182 rebuildIfNecessary :: M.Map ModuleName [ModuleName] -> S.Set ModuleName -> [Module] -> m [(Bool, Module)]
@@ -264,8 +271,8 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
264 let path = outputDir </> runModuleName mn </> "externs.purs"
271 let path = outputDir </> runModuleName mn </> "externs.purs"
265 (path, ) <$> readTextFile path
272 (path, ) <$> readTextFile path
267− codegen :: CF.Module CF.Ann -> Environment -> SupplyVar -> Externs -> Make ()
274+ codegen :: CF.Module CF.Ann -> Environment -> Externs -> SupplyT Make ()
268− codegen m _ nextVar exts = do
275+ codegen m _ exts = do
269 let mn = CF.moduleName m
276 let mn = CF.moduleName m
270 foreignInclude <- case mn `M.lookup` foreigns of
277 foreignInclude <- case mn `M.lookup` foreigns of
271 Just (path, _)
278 Just (path, _)
@@ -275,18 +282,17 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
275 | otherwise -> return $ Just $ J.JSApp (J.JSVar "require") [J.JSStringLiteral "./foreign"]
282 | otherwise -> return $ Just $ J.JSApp (J.JSVar "require") [J.JSStringLiteral "./foreign"]
276 Nothing | requiresForeign m -> throwError . errorMessage $ MissingFFIModule mn
283 Nothing | requiresForeign m -> throwError . errorMessage $ MissingFFIModule mn
277 | otherwise -> return Nothing
284 | otherwise -> return Nothing
278− pjs <- evalSupplyT nextVar $ prettyPrintJS <$> J.moduleToJs m foreignInclude
285+ pjs <- prettyPrintJS <$> J.moduleToJs m foreignInclude
279 let filePath = runModuleName mn
286 let filePath = runModuleName mn
280 jsFile = outputDir </> filePath </> "index.js"
287 jsFile = outputDir </> filePath </> "index.js"
281 externsFile = outputDir </> filePath </> "externs.purs"
288 externsFile = outputDir </> filePath </> "externs.purs"
282 foreignFile = outputDir </> filePath </> "foreign.js"
289 foreignFile = outputDir </> filePath </> "foreign.js"
283 prefix = ["Generated by psc version " ++ showVersion Paths.version | usePrefix]
290 prefix = ["Generated by psc version " ++ showVersion Paths.version | usePrefix]
284 js = unlines $ map ("// " ++) prefix ++ [pjs]
291 js = unlines $ map ("// " ++) prefix ++ [pjs]
285− verboseErrorsEnabled <- asks optionsVerboseErrors
292+ lift $ do
286− when verboseErrorsEnabled $ progress $ "Writing " ++ jsFile
287− writeTextFile jsFile js
293+ writeTextFile jsFile js
288− maybe (return ()) (writeTextFile foreignFile . snd) $ mn `M.lookup` foreigns
294+ maybe (return ()) (writeTextFile foreignFile . snd) $ mn `M.lookup` foreigns
289− writeTextFile externsFile exts
295+ writeTextFile externsFile exts
291 requiresForeign :: CF.Module a -> Bool
297 requiresForeign :: CF.Module a -> Bool
292 requiresForeign = not . null . CF.moduleForeign
298 requiresForeign = not . null . CF.moduleForeign
@@ -307,5 +313,5 @@ buildMakeActions outputDir filePathMap foreigns usePrefix =
307 mkdirp :: FilePath -> IO ()
313 mkdirp :: FilePath -> IO ()
308 mkdirp = createDirectoryIfMissing True . takeDirectory
314 mkdirp = createDirectoryIfMissing True . takeDirectory
310− progress :: String -> Make ()
316+ progress :: ProgressMessage -> Make ()
311− progress = liftIO . putStrLn
317+ progress = liftIO . putStrLn . renderProgressMessage