git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Change psci to use the common Make support
f7147d2John Lenz
psci/Make.hsdeleted−127
@@ -1,127 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Make
4−-- Copyright : (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15−{-# LANGUAGE DataKinds #-}
16−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
17−{-# LANGUAGE TupleSections #-}
18−
19−module Make where
20−
21−import Data.List (isPrefixOf)
22−import Data.Maybe (fromMaybe)
23−import Data.Time.Clock
24−import Data.Traversable (traverse)
25−import qualified Data.Map as M
26−
27−import Control.Applicative
28−import Control.Monad
29−import Control.Monad.Error.Class (MonadError(..))
30−import Control.Monad.IO.Class (MonadIO, liftIO)
31−import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
32−import Control.Monad.Trans.Except (ExceptT(..), runExceptT)
33−import Control.Monad.Writer (MonadWriter, WriterT, runWriterT, tell)
34−
35−import System.Directory (getModificationTime, doesFileExist)
36−import System.FilePath ((</>), pathSeparator)
37−import System.IO.Error (tryIOError)
38−
39−import qualified Language.PureScript as P
40−import qualified Language.PureScript.CodeGen.JS as J
41−import qualified Language.PureScript.CoreFn as CF
42−
43−import IO (mkdirp)
44−
45−options :: P.Options
46−options = P.Options False False Nothing False False False Nothing
47−
48−modulesDir :: FilePath
49−modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
50−
51−newtype Make a = Make { unMake :: ReaderT P.Options (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
52− deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader P.Options)
53−
54−runMake :: Make a -> IO (Either P.MultipleErrors a)
55−runMake = runExceptT . fmap fst . runWriterT . flip runReaderT options . unMake
56−
57−makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
58−makeIO f io = do
59− e <- liftIO $ tryIOError io
60− either (throwError . P.singleError . f) return e
61−
62−-- Traverse (Either e) instance (base 4.7)
63−traverseEither :: Applicative f => (a -> f b) -> Either e a -> f (Either e b)
64−traverseEither _ (Left x) = pure (Left x)
65−traverseEither f (Right y) = Right <$> f y
66−
67−buildMakeActions :: M.Map P.ModuleName (Either P.RebuildPolicy String)
68− -> M.Map P.ModuleName P.ForeignJS
69− -> P.MakeActions Make
70−buildMakeActions filePathMap foreigns =
71− P.MakeActions getInputTimestamp getOutputTimestamp readExterns codegen progress
72− where
73−
74− getInputTimestamp :: P.ModuleName -> Make (Either P.RebuildPolicy (Maybe UTCTime))
75− getInputTimestamp mn = do
76− let path = fromMaybe (error "Module has no filename in 'make'") $ M.lookup mn filePathMap
77− traverseEither getTimestamp path
78−
79− getOutputTimestamp :: P.ModuleName -> Make (Maybe UTCTime)
80− getOutputTimestamp mn = do
81− let filePath = P.runModuleName mn
82− jsFile = modulesDir </> filePath </> "index.js"
83− externsFile = modulesDir </> filePath </> "externs.purs"
84− min <$> getTimestamp jsFile <*> getTimestamp externsFile
85−
86− readExterns :: P.ModuleName -> Make (FilePath, String)
87− readExterns mn = do
88− let path = modulesDir </> P.runModuleName mn </> "externs.purs"
89− (path, ) <$> readTextFile path
90−
91− codegen :: CF.Module CF.Ann -> P.Environment -> P.SupplyVar -> P.Externs -> Make ()
92− codegen m _ nextVar exts = do
93− let mn = CF.moduleName m
94− foreignInclude <- case CF.moduleName m `M.lookup` foreigns of
95− Just path
96− | not $ requiresForeign m -> do tell $ P.errorMessage $ P.UnnecessaryFFIModule mn path
97− return Nothing
98− | otherwise -> return $ Just $ J.JSApp (J.JSVar "require") [J.JSStringLiteral "./foreign"]
99− Nothing | requiresForeign m -> throwError . P.errorMessage $ P.MissingFFIModule mn
100− | otherwise -> return Nothing
101− pjs <- P.evalSupplyT nextVar $ P.prettyPrintJS <$> J.moduleToJs m foreignInclude
102− let filePath = P.runModuleName $ CF.moduleName m
103− jsFile = modulesDir </> filePath </> "index.js"
104− externsFile = modulesDir </> filePath </> "externs.purs"
105− foreignFile = modulesDir </> filePath </> "foreign.js"
106− writeTextFile jsFile pjs
107− maybe (return ()) (writeTextFile foreignFile) $ CF.moduleName m `M.lookup` foreigns
108− writeTextFile externsFile exts
109−
110− requiresForeign :: CF.Module a -> Bool
111− requiresForeign = not . null . CF.moduleForeign
112−
113− getTimestamp :: FilePath -> Make (Maybe UTCTime)
114− getTimestamp path = makeIO (const (P.SimpleErrorWrapper $ P.CannotGetFileInfo path)) $ do
115− exists <- doesFileExist path
116− traverse (const $ getModificationTime path) $ guard exists
117−
118− readTextFile :: FilePath -> Make String
119− readTextFile path = makeIO (const (P.SimpleErrorWrapper $ P.CannotReadFile path)) $ readFile path
120−
121− writeTextFile :: FilePath -> String -> Make ()
122− writeTextFile path text = makeIO (const (P.SimpleErrorWrapper $ P.CannotWriteFile path)) $ do
123− mkdirp path
124− writeFile path text
125−
126− progress :: String -> Make ()
127− progress s = unless ("Compiling $PSCI" `isPrefixOf` s) $ liftIO . putStrLn $ s
psci/PSCi.hs+23−6
@@ -21,7 +21,7 @@
21module PSCi where
21module PSCi where
22
22
23import Data.Foldable (traverse_)
23import Data.Foldable (traverse_)
24−import Data.List (intercalate, nub, sort)
24+import Data.List (intercalate, nub, sort, isPrefixOf)
25import Data.Traversable (traverse)
25import Data.Traversable (traverse)
26import Data.Tuple (swap)
26import Data.Tuple (swap)
27import Data.Version (showVersion)
27import Data.Version (showVersion)
@@ -30,10 +30,12 @@ import qualified Data.Map as M
30import Control.Applicative
30import Control.Applicative
31import Control.Arrow (first)
31import Control.Arrow (first)
32import Control.Monad
32import Control.Monad
33+import Control.Monad.Error.Class (MonadError(..))
33import Control.Monad.Trans.Class
34import Control.Monad.Trans.Class
34import Control.Monad.Trans.Except (runExceptT)
35import Control.Monad.Trans.Except (runExceptT)
35import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
36import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
36import Control.Monad.Trans.State.Strict
37import Control.Monad.Trans.State.Strict
38+import Control.Monad.IO.Class (liftIO)
37import Control.Monad.Writer (runWriter)
39import Control.Monad.Writer (runWriter)
38import qualified Control.Monad.Trans.State.Lazy as L
40import qualified Control.Monad.Trans.State.Lazy as L
39
41
@@ -45,6 +47,7 @@ import System.Exit
45import System.FilePath (pathSeparator, (</>), isPathSeparator)
47import System.FilePath (pathSeparator, (</>), isPathSeparator)
46import System.FilePath.Glob (glob)
48import System.FilePath.Glob (glob)
47import System.Process (readProcessWithExitCode)
49import System.Process (readProcessWithExitCode)
50+import System.IO.Error (tryIOError)
48
51
49import qualified Language.PureScript as P
52import qualified Language.PureScript as P
50import qualified Language.PureScript.Names as N
53import qualified Language.PureScript.Names as N
@@ -53,7 +56,6 @@ import qualified Paths_purescript as Paths
53import qualified Directive as D
56import qualified Directive as D
54import Completion (completion)
57import Completion (completion)
55import IO (mkdirp)
58import IO (mkdirp)
56−import Make
57import Parser (parseCommand)
59import Parser (parseCommand)
58import Types
60import Types
59
61
@@ -240,10 +242,25 @@ importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ
240indexFile :: FilePath
242indexFile :: FilePath
241indexFile = ".psci_modules" ++ pathSeparator : "index.js"
243indexFile = ".psci_modules" ++ pathSeparator : "index.js"
242
244
245+modulesDir :: FilePath
246+modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
247+
248+-- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the
249+-- options and ignores the warning messages.
250+runMake :: P.Make a -> IO (Either P.MultipleErrors a)
251+runMake mk = fmap (fmap fst) $ P.runMake (P.Options False False Nothing False False False Nothing) mk
252+
253+makeIO :: (IOError -> P.ErrorMessage) -> IO a -> P.Make a
254+makeIO f io = do
255+ e <- liftIO $ tryIOError io
256+ either (throwError . P.singleError . f) return e
257+
243−make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> Make P.Environment
258+make :: PSCiState -> [(Either P.RebuildPolicy FilePath, P.Module)] -> P.Make P.Environment
244−make PSCiState{..} ms =
259+make PSCiState{..} ms = P.make actions' (psciLoadedModules ++ ms)
260+ where
245− let filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
261+ filePathMap = M.fromList $ (first P.getModuleName . swap) `map` (psciLoadedModules ++ ms)
246− in P.make (buildMakeActions filePathMap (M.map snd psciForeignFiles)) (psciLoadedModules ++ ms)
262+ actions = P.buildMakeActions modulesDir filePathMap psciForeignFiles False
263+ actions' = actions { P.progress = \s -> unless ("Compiling $PSCI" `isPrefixOf` s) $ liftIO . putStrLn $ s }
247
264
248-- |
265-- |
249-- Takes a value declaration and evaluates it with the current state.
266-- Takes a value declaration and evaluates it with the current state.
purescript.cabal−1
@@ -172,7 +172,6 @@ executable psci
172 Directive
172 Directive
173 Completion
173 Completion
174 PSCi
174 PSCi
175− Make
176 IO
175 IO
177 ghc-options: -Wall -O2
176 ghc-options: -Wall -O2
178
177