{-# LANGUAGE CPP #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExistentialQuantification #-}
module HIE.Bios.Ghc.Check (
checkSyntax
, check
) where
import GHC (GhcMonad)
import qualified GHC as G
import Control.Exception
import Control.Monad.IO.Class
import Colog.Core (LogAction (..), WithSeverity (..), Severity (..), (<&), cmap)
import Prettyprinter
import HIE.Bios.Ghc.Api
import HIE.Bios.Ghc.Logger
import HIE.Bios.Types hiding (Log (..))
import qualified HIE.Bios.Types as T
import qualified HIE.Bios.Ghc.Load as Load
import HIE.Bios.Environment
data Log =
LoadLog Load.Log
| LogAny T.Log
| forall a . Show a => LogCradle (Cradle a)
instance Pretty Log where
pretty :: forall ann. Log -> Doc ann
pretty (LoadLog Log
l) = Log -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Log -> Doc ann
pretty Log
l
pretty (LogAny Log
l) = Log -> Doc ann
forall a ann. Pretty a => a -> Doc ann
forall ann. Log -> Doc ann
pretty Log
l
pretty (LogCradle Cradle a
c) = Doc ann
"Cradle:" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Cradle a -> Doc ann
forall a ann. Show a => a -> Doc ann
viaShow Cradle a
c
checkSyntax :: Show a
=> LogAction IO (WithSeverity Log)
-> Cradle a
-> [FilePath]
-> IO String
checkSyntax :: forall a.
Show a =>
LogAction IO (WithSeverity Log)
-> Cradle a -> [FilePath] -> IO FilePath
checkSyntax LogAction IO (WithSeverity Log)
_ Cradle a
_ [] = FilePath -> IO FilePath
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return FilePath
""
checkSyntax LogAction IO (WithSeverity Log)
checkLogger Cradle a
cradle files :: [FilePath]
files@(FilePath
file:[FilePath]
_) = do
CradleLoadResult FilePath
libDirRes <- Cradle a -> IO (CradleLoadResult FilePath)
forall a. Cradle a -> IO (CradleLoadResult FilePath)
getRuntimeGhcLibDir Cradle a
cradle
CradleLoadResult FilePath
-> (FilePath -> IO FilePath) -> IO FilePath
forall {m :: * -> *} {a} {t}.
(MonadIO m, IsString a) =>
CradleLoadResult t -> (t -> m a) -> m a
handleRes CradleLoadResult FilePath
libDirRes ((FilePath -> IO FilePath) -> IO FilePath)
-> (FilePath -> IO FilePath) -> IO FilePath
forall a b. (a -> b) -> a -> b
$ \FilePath
libDir ->
Maybe FilePath -> GhcT IO FilePath -> IO FilePath
forall (m :: * -> *) a.
ExceptionMonad m =>
Maybe FilePath -> GhcT m a -> m a
G.runGhcT (FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
libDir) (GhcT IO FilePath -> IO FilePath)
-> GhcT IO FilePath -> IO FilePath
forall a b. (a -> b) -> a -> b
$ do
IO () -> GhcT IO ()
forall a. IO a -> GhcT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> GhcT IO ()) -> IO () -> GhcT IO ()
forall a b. (a -> b) -> a -> b
$ LogAction IO (WithSeverity Log)
checkLogger LogAction IO (WithSeverity Log) -> WithSeverity Log -> IO ()
forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& Cradle a -> Log
forall a. Show a => Cradle a -> Log
LogCradle Cradle a
cradle Log -> Severity -> WithSeverity Log
forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Info
CradleLoadResult (GhcT IO SuccessFlag, ComponentOptions)
res <- FilePath
-> Cradle a
-> GhcT
IO (CradleLoadResult (GhcT IO SuccessFlag, ComponentOptions))
forall (m :: * -> *) a.
GhcMonad m =>
FilePath
-> Cradle a
-> m (CradleLoadResult (m SuccessFlag, ComponentOptions))
initializeFlagsWithCradle FilePath
file Cradle a
cradle
CradleLoadResult (GhcT IO SuccessFlag, ComponentOptions)
-> ((GhcT IO SuccessFlag, ComponentOptions) -> GhcT IO FilePath)
-> GhcT IO FilePath
forall {m :: * -> *} {a} {t}.
(MonadIO m, IsString a) =>
CradleLoadResult t -> (t -> m a) -> m a
handleRes CradleLoadResult (GhcT IO SuccessFlag, ComponentOptions)
res (((GhcT IO SuccessFlag, ComponentOptions) -> GhcT IO FilePath)
-> GhcT IO FilePath)
-> ((GhcT IO SuccessFlag, ComponentOptions) -> GhcT IO FilePath)
-> GhcT IO FilePath
forall a b. (a -> b) -> a -> b
$ \(GhcT IO SuccessFlag
ini, ComponentOptions
_) -> do
SuccessFlag
_sf <- GhcT IO SuccessFlag
ini
(FilePath -> FilePath)
-> (FilePath -> FilePath) -> Either FilePath FilePath -> FilePath
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either FilePath -> FilePath
forall a. a -> a
id FilePath -> FilePath
forall a. a -> a
id (Either FilePath FilePath -> FilePath)
-> GhcT IO (Either FilePath FilePath) -> GhcT IO FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LogAction IO (WithSeverity Log)
-> [FilePath] -> GhcT IO (Either FilePath FilePath)
forall (m :: * -> *).
GhcMonad m =>
LogAction IO (WithSeverity Log)
-> [FilePath] -> m (Either FilePath FilePath)
check LogAction IO (WithSeverity Log)
checkLogger [FilePath]
files
where
handleRes :: CradleLoadResult t -> (t -> m a) -> m a
handleRes (CradleSuccess t
x) t -> m a
f = t -> m a
f t
x
handleRes (CradleFail CradleError
ce) t -> m a
_f = IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ CradleError -> IO a
forall e a. Exception e => e -> IO a
throwIO CradleError
ce
handleRes CradleLoadResult t
CradleNone t -> m a
_f = a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
"None cradle"
check :: (GhcMonad m)
=> LogAction IO (WithSeverity Log)
-> [FilePath]
-> m (Either String String)
check :: forall (m :: * -> *).
GhcMonad m =>
LogAction IO (WithSeverity Log)
-> [FilePath] -> m (Either FilePath FilePath)
check LogAction IO (WithSeverity Log)
logger [FilePath]
fileNames = do
(DynFlags -> DynFlags) -> m () -> m (Either FilePath FilePath)
forall (m :: * -> *).
GhcMonad m =>
(DynFlags -> DynFlags) -> m () -> m (Either FilePath FilePath)
withLogger DynFlags -> DynFlags
forall a. a -> a
id (m () -> m (Either FilePath FilePath))
-> m () -> m (Either FilePath FilePath)
forall a b. (a -> b) -> a -> b
$ LogAction IO (WithSeverity Log) -> [(FilePath, FilePath)] -> m ()
forall (m :: * -> *).
GhcMonad m =>
LogAction IO (WithSeverity Log) -> [(FilePath, FilePath)] -> m ()
Load.setTargetFiles ((WithSeverity Log -> WithSeverity Log)
-> LogAction IO (WithSeverity Log)
-> LogAction IO (WithSeverity Log)
forall a b (m :: * -> *).
(a -> b) -> LogAction m b -> LogAction m a
cmap ((Log -> Log) -> WithSeverity Log -> WithSeverity Log
forall a b. (a -> b) -> WithSeverity a -> WithSeverity b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Log -> Log
LoadLog) LogAction IO (WithSeverity Log)
logger) ((FilePath -> (FilePath, FilePath))
-> [FilePath] -> [(FilePath, FilePath)]
forall a b. (a -> b) -> [a] -> [b]
map FilePath -> (FilePath, FilePath)
forall a. a -> (a, a)
dup [FilePath]
fileNames)
dup :: a -> (a, a)
dup :: forall a. a -> (a, a)
dup a
x = (a
x, a
x)