doctest-parallel-0.2: src/Test/DocTest/Internal/GhcUtil.hs
{-# LANGUAGE CPP #-}
module Test.DocTest.Internal.GhcUtil (withGhc) where
import GHC.Paths (libdir)
import GHC
#if __GLASGOW_HASKELL__ < 900
import DynFlags (gopt_set)
#else
import GHC.Driver.Session (gopt_set)
#endif
#if __GLASGOW_HASKELL__ < 900
import Panic (throwGhcException)
#else
import GHC.Utils.Panic (throwGhcException)
#endif
#if __GLASGOW_HASKELL__ < 900
import MonadUtils (liftIO)
#else
import GHC.Utils.Monad (liftIO)
#endif
import System.Exit (exitFailure)
-- Catch GHC source errors, print them and exit.
handleSrcErrors :: Ghc a -> Ghc a
handleSrcErrors action' = flip handleSourceError action' $ \err -> do
printException err
liftIO exitFailure
-- | Run a GHC action in Haddock mode
withGhc :: [String] -> ([String] -> Ghc a) -> IO a
withGhc flags action = do
flags_ <- handleStaticFlags flags
runGhc (Just libdir) $ do
handleDynamicFlags flags_ >>= handleSrcErrors . action
handleStaticFlags :: [String] -> IO [Located String]
handleStaticFlags flags = return $ map noLoc $ flags
handleDynamicFlags :: GhcMonad m => [Located String] -> m [String]
handleDynamicFlags flags = do
#if __GLASGOW_HASKELL__ >= 901
logger <- getLogger
let parseDynamicFlags' = parseDynamicFlags logger
#else
let parseDynamicFlags' = parseDynamicFlags
#endif
dynflags0 <- setHaddockMode <$> getSessionDynFlags
(dynflags1, locSrcs, _) <- parseDynamicFlags' dynflags0 flags
_ <- setSessionDynFlags dynflags1
-- We basically do the same thing as `ghc/Main.hs` to distinguish
-- "unrecognised flags" from source files.
let srcs = map unLoc locSrcs
unknown_opts = [ f | f@('-':_) <- srcs ]
case unknown_opts of
opt : _ -> throwGhcException (UsageError ("unrecognized option `"++ opt ++ "'"))
_ -> return srcs
setHaddockMode :: DynFlags -> DynFlags
setHaddockMode dynflags = (gopt_set dynflags Opt_Haddock) {
#if __GLASGOW_HASKELL__ >= 901
backend = NoBackend
#else
hscTarget = HscNothing
#endif
, ghcMode = CompManager
, ghcLink = NoLink
}