@@ -29,6 +29,8 @@ import qualified Data.Map as M
30import Control.Applicative
30import Control.Applicative
31import Control.Monad
31import Control.Monad
32+import Control.Monad.IO.Class (MonadIO, liftIO)
33+import Control.Monad.Error.Class (throwError)
32import Control.Monad.Except (ExceptT(..), MonadError, runExceptT)
34import Control.Monad.Except (ExceptT(..), MonadError, runExceptT)
33import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
35import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
34import Control.Monad.Trans.Class
36import Control.Monad.Trans.Class
@@ -180,24 +182,26 @@ newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Fu
180psciIO :: IO a -> PSCI a
182psciIO :: IO a -> PSCI a
181psciIO io = PSCI . lift $ lift io
183psciIO io = PSCI . lift $ lift io
183−newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT String IO) a }
185+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT P.MultipleErrors IO) a }
184− deriving (Functor, Applicative, Monad, MonadError String, MonadReader (P.Options P.Make))
186+ deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadReader (P.Options P.Make))
186−runMake :: Make a -> IO (Either String a)
188+runMake :: Make a -> IO (Either P.MultipleErrors a)
187runMake = runExceptT . flip runReaderT options . unMake
189runMake = runExceptT . flip runReaderT options . unMake
189−makeIO :: IO a -> Make a
191+makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
190−makeIO = Make . lift . ExceptT . fmap (either (Left . show) Right) . tryIOError
192+makeIO f io = do
193+ e <- liftIO $ tryIOError io
194+ either (throwError . P.errorMessage . f) return e
192instance P.MonadMake Make where
196instance P.MonadMake Make where
193− getTimestamp path = makeIO $ do
197+ getTimestamp path = makeIO (const (P.CannotGetFileInfo path)) $ do
194 exists <- doesFileExist path
198 exists <- doesFileExist path
195 traverse (const $ getModificationTime path) $ guard exists
199 traverse (const $ getModificationTime path) $ guard exists
196− readTextFile path = makeIO $ readFile path
200+ readTextFile path = makeIO (const (P.CannotReadFile path)) $ readFile path
197− writeTextFile path text = makeIO $ do
201+ writeTextFile path text = makeIO (const (P.CannotWriteFile path)) $ do
198 mkdirp path
202 mkdirp path
199 writeFile path text
203 writeFile path text
200− progress s = unless (s == "Compiling $PSCI") $ makeIO . putStrLn $ s
204+ progress s = unless (s == "Compiling $PSCI") $ liftIO . putStrLn $ s
202mkdirp :: FilePath -> IO ()
206mkdirp :: FilePath -> IO ()
203mkdirp = createDirectoryIfMissing True . takeDirectory
207mkdirp = createDirectoryIfMissing True . takeDirectory
@@ -259,7 +263,7 @@ handleDeclaration val = do
259 let nodeArgs = psciNodeFlags st ++ [indexFile]
263 let nodeArgs = psciNodeFlags st ++ [indexFile]
260 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
264 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
261 case e of
265 case e of
262− Left err -> PSCI $ outputStrLn err
266+ Left errs -> printErrors errs
263 Right _ -> do
267 Right _ -> do
264 psciIO $ writeFile indexFile "require('$PSCI').main();"
268 psciIO $ writeFile indexFile "require('$PSCI').main();"
265 process <- psciIO findNodeProcess
269 process <- psciIO findNodeProcess
@@ -280,7 +284,7 @@ handleDecls ds = do
280 let m = createTemporaryModule False st' (P.ObjectLiteral [])
284 let m = createTemporaryModule False st' (P.ObjectLiteral [])
281 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
285 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
282 case e of
286 case e of
283− Left err -> PSCI $ outputStrLn err
287+ Left err -> printErrors err
284 Right _ -> PSCI $ lift (put st')
288 Right _ -> PSCI $ lift (put st')
@@ -333,7 +337,7 @@ handleImport im = do
333 let m = createTemporaryModuleForImports st
337 let m = createTemporaryModuleForImports st
334 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
338 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
335 case e of
339 case e of
336− Left err -> PSCI $ outputStrLn err
340+ Left errs -> printErrors errs
337 Right _ -> do
341 Right _ -> do
338 PSCI $ lift $ put st
342 PSCI $ lift $ put st
339 return ()
343 return ()
@@ -347,7 +351,7 @@ handleTypeOf val = do
347 let m = createTemporaryModule False st val
351 let m = createTemporaryModule False st val
348 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
352 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
349 case e of
353 case e of
350− Left err -> PSCI $ outputStrLn err
354+ Left errs -> printErrors errs
351 Right env' ->
355 Right env' ->
352 case M.lookup (P.ModuleName [P.ProperName "$PSCI"], P.Ident "it") (P.names env') of
356 case M.lookup (P.ModuleName [P.ProperName "$PSCI"], P.Ident "it") (P.names env') of
353 Just (ty, _, _) -> PSCI . outputStrLn . P.prettyPrintType $ ty
357 Just (ty, _, _) -> PSCI . outputStrLn . P.prettyPrintType $ ty
@@ -381,12 +385,16 @@ handleBrowse moduleName = do
381 let loadedModules = psciLoadedModules st
385 let loadedModules = psciLoadedModules st
382 env <- psciIO . runMake $ P.make modulesDir loadedModules []
386 env <- psciIO . runMake $ P.make modulesDir loadedModules []
383 case env of
387 case env of
384− Left err -> PSCI $ outputStrLn err
388+ Left errs -> printErrors errs
385 Right env' ->
389 Right env' ->
386 if moduleName `notElem` (nub . map ((\ (P.Module _ modName _ _ ) -> modName) . snd)) loadedModules
390 if moduleName `notElem` (nub . map ((\ (P.Module _ modName _ _ ) -> modName) . snd)) loadedModules
387 then PSCI $ outputStrLn $ "Module '" ++ N.runModuleName moduleName ++ "' is not valid."
391 then PSCI $ outputStrLn $ "Module '" ++ N.runModuleName moduleName ++ "' is not valid."
388 else printModuleSignatures moduleName env'
392 else printModuleSignatures moduleName env'
394+-- | Pretty-print errors
395+printErrors :: P.MultipleErrors -> PSCI ()
396+printErrors = PSCI . outputStrLn . P.prettyPrintMultipleErrors False
391-- Takes a value and prints its kind
399-- Takes a value and prints its kind
@@ -397,7 +405,7 @@ handleKindOf typ = do
397 mName = P.ModuleName [P.ProperName "$PSCI"]
405 mName = P.ModuleName [P.ProperName "$PSCI"]
398 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
406 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
399 case e of
407 case e of
400− Left err -> PSCI $ outputStrLn err
408+ Left errs -> printErrors errs
401 Right env' ->
409 Right env' ->
402 case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
410 case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
403 Just (_, typ') -> do
411 Just (_, typ') -> do