mohws-0.1: src/Module/DynHS/GHCUtil.hs
module Module.DynHS.GHCUtil
(Session,
initGHC,
setLogAction,
withCleanUp,
getFileValue,
-- * Error logging
Severity(..), SrcSpan, PprStyle, Message,
mkLocMessage
) where
-- GHC API stuff
import DynFlags
import ErrUtils
import GHC hiding (Module, Session, moduleName)
import qualified GHC (Module, Session)
import HscMain (newHscEnv)
import HscTypes (Session(..))
import Outputable (PprStyle)
import SrcLoc (SrcSpan)
import SysTools (initSysTools)
import Data.Dynamic
import Data.IORef
import System.IO
initGHC :: FilePath -> IO Session
initGHC pkgDir
= do s <- newSession' Interactive (Just pkgDir)
modifySessionDynFlags s (\flags -> flags{ hscTarget = HscInterpreted })
return s
-- Like newSesion, but does not install signal handlers
newSession' :: GhcMode -> Maybe FilePath -> IO Session
newSession' mode mb_top_dir = do
dflags0 <- initSysTools mb_top_dir defaultDynFlags
dflags <- initDynFlags dflags0
env <- newHscEnv dflags{ ghcMode=mode }
ref <- newIORef env
return (Session ref)
setLogAction :: Session -> (String -> IO ()) -> IO ()
setLogAction s f =
modifySessionDynFlags s (\flags -> flags { log_action = mkLogAction f })
mkLogAction :: (String -> IO ())
-> Severity -> SrcSpan -> PprStyle -> Message -> IO ()
mkLogAction f severity srcSpan style msg =
case severity of
SevInfo -> f (show (msg style))
SevFatal -> f (show (msg style))
_ -> f (show ((mkLocMessage srcSpan msg) style))
modifySessionDynFlags :: Session -> (DynFlags -> DynFlags) -> IO ()
modifySessionDynFlags s f =
do flags <- getSessionDynFlags s
setSessionDynFlags s (f flags)
return ()
withCleanUp :: Session -> IO a -> IO a
withCleanUp s f = do flags <- getSessionDynFlags s
defaultCleanupHandler flags f
loadFile :: Session -> FilePath -> IO GHC.Module
loadFile s file =
do let t = Target (TargetFile file Nothing) Nothing
setTargets s [t]
succ <- load s LoadAllTargets
case succ of
Succeeded -> do m <- fileModule s file
setContext s [] [m]
return m
Failed -> fail $ "Failed to load " ++ show file
fileModule :: Session -> FilePath -> IO GHC.Module
fileModule s f =
do gr <- getModuleGraph s
case [ms_mod ms | ms <- gr, ml_hs_file (ms_location ms) == Just f] of
[m] -> return m
_ -> fail $ "File " ++ f ++ " does not correspond to a module"
getValue :: Typeable a => Session -> String -> IO a
getValue s x =
do mdyn <- dynCompileExpr s x
case mdyn of
Nothing -> fail $ "dynCompileExpr " ++ show x ++ " failed"
Just dyn -> case fromDynamic dyn of
Nothing -> fail $ "Type error: " ++ x
++ " is an " ++ show dyn
Just x -> return x
getFileValue :: Typeable a => Session -> FilePath -> String -> IO a
getFileValue s file x =
do m <- loadFile s file
getValue s x