ghc-debugger-0.1.0.0: ghc-debug-adapter/Development/Debug/Adapter/Flags.hs
{-# LANGUAGE CPP, RecordWildCards, LambdaCase #-}
module Development.Debug.Adapter.Flags where
import Data.Maybe
import Data.Function
import System.FilePath
import System.Directory
import Control.Monad.Except
import Control.Monad.IO.Class
import qualified Data.List as L
import qualified HIE.Bios as HIE
import qualified HIE.Bios.Types as HIE
import qualified HIE.Bios.Environment as HIE
-- | Flags inferred by @hie-bios@ to invoke GHC
data HieBiosFlags = HieBiosFlags
{ ghcInvocation :: [String]
, libdir :: FilePath
, units :: [String]
}
-- | Make 'HieBiosFlags' from the given target file
hieBiosFlags :: FilePath {-^ Project root -} -> FilePath {-^ Entry file relative to root -} -> IO (Either String HieBiosFlags)
hieBiosFlags root relTarget = runExceptT $ do
let target = root </> relTarget
explicitCradle <- HIE.findCradle target & liftIO
cradle <- maybe (HIE.loadImplicitCradle mempty target)
(HIE.loadCradle mempty) explicitCradle & liftIO
libdir <- liftIO (HIE.getRuntimeGhcLibDir cradle) >>= unwrapCradleResult "Failed to get runtime GHC libdir"
-- To determine the flags we MUST set the current directory to the root
-- because hie.yaml may invoke programs relative to the root (e.g. GHC's hie.yaml does)
-- (HIE.getCompilerOptions depends on CWD being the proper root dir)
let compilerOpts = liftIO $ withCurrentDirectory root $
#if MIN_VERSION_hie_bios(0,14,0)
HIE.getCompilerOptions target HIE.LoadFile cradle
#else
HIE.getCompilerOptions target [] cradle
#endif
HIE.ComponentOptions {HIE.componentOptions = flags} <- compilerOpts >>= unwrapCradleResult "Failed to get compiler options using hie-bios cradle"
#if __GLASGOW_HASKELL__ >= 913
-- fwrite-if-simplified-core requires a recent bug fix regarding GHCi loading
-- ROMES:TODO: Re-enable as soon as I'm using Matthew's patch.
-- ["-fwrite-if-simplified-core"] ++
#endif
return HieBiosFlags
{ ghcInvocation = [ relTarget | not $ any (`L.isSuffixOf` target) flags ] ++ -- TODO is this correct? else, the debugger won't work on single files.
flags ++ ghcDebuggerFlags
, libdir = libdir
, units = mapMaybe (\case ("-unit", u) -> Just u; _ -> Nothing) $ zip flags (drop 1 flags)
}
where
unwrapCradleResult m = \case
HIE.CradleNone -> throwError $ "HIE.CradleNone\n" ++ m
HIE.CradleFail err -> throwError $ unlines (HIE.cradleErrorStderr err) ++ "\n" ++ m
HIE.CradleSuccess x -> return x
-- | Flags specific to ghc-debugger to append to all GHC invocations.
ghcDebuggerFlags :: [String]
ghcDebuggerFlags =
[ "-fno-it" -- don't introduce @it@ after evaluating something at the prompt
]