ghc-mod/GHCApi.hs

111 lines
3.6 KiB
Haskell

module GHCApi where
import Cabal
import Control.Applicative
import Control.Exception
import CoreMonad
import DynFlags
import ErrMsg
import Exception
import GHC
import GHC.Paths (libdir)
import GHCChoice
import HeaderInfo
import System.Exit
import System.IO
import Types
----------------------------------------------------------------
withGHC :: Alternative m => Ghc (m a) -> IO (m a)
withGHC = withGHC' "Dummy"
withGHC' :: Alternative m => FilePath -> Ghc (m a) -> IO (m a)
withGHC' file body = ghandle ignore $ runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
defaultCleanupHandler dflags body
where
ignore :: Alternative m => SomeException -> IO (m a)
ignore e = do
hPutStr stderr $ file ++ ":0:0:Error:"
hPrint stderr e
exitSuccess
----------------------------------------------------------------
initSession0 :: Options -> Ghc [PackageId]
initSession0 opt = getSessionDynFlags >>=
(>>= setSessionDynFlags) . setGhcFlags opt
----------------------------------------------------------------
importDirs :: [IncludeDir]
importDirs = [".","..","../..","../../..","../../../..","../../../../.."]
initializeGHC :: Options -> FilePath -> [GHCOption] -> Bool -> Ghc LogReader
initializeGHC opt fileName ghcOptions logging = withCabal ||> withoutCabal
where
withoutCabal = initSession opt ghcOptions importDirs Nothing Nothing logging fileName
withCabal = do
(gopts,idirs,depPkgs,hdrExts) <- liftIO $ fromCabal ghcOptions
initSession opt gopts idirs (Just depPkgs) (Just hdrExts) logging fileName
initSession :: Options
-> [GHCOption]
-> [IncludeDir]
-> Maybe [Package]
-> Maybe [LangExt]
-> Bool
-> FilePath
-> Ghc LogReader
initSession opt cmdOpts idirs mDepPkgs mLangExts logging file = do
dflags <- getSessionDynFlags
hdrExts <- liftIO $ map unLoc <$> getOptionsFromFile dflags file
let th = useTemplateHaskell mLangExts hdrExts
opts = map noLoc cmdOpts
(dflags',_,_) <- parseDynamicFlags dflags opts
(dflags'',readLog) <- liftIO . (>>= setLogger logging)
. setGhcFlags opt . setFlags opt dflags' idirs mDepPkgs $ th
_ <- setSessionDynFlags dflags''
return readLog
useTemplateHaskell :: Maybe [LangExt] -> [HeaderExt] -> Bool
useTemplateHaskell mLangExts hdrExts = th1 || th2
where
th1 = "-XTemplateHaskell" `elem` hdrExts
th2 = maybe False ("TemplateHaskell" `elem`) mLangExts
----------------------------------------------------------------
setFlags :: Options -> DynFlags -> [IncludeDir] -> Maybe [Package] -> Bool -> DynFlags
setFlags opt d idirs mDepPkgs th
| expandSplice opt = dopt_set d' Opt_D_dump_splices
| otherwise = d'
where
d' = addDevPkgs mDepPkgs $ d {
importPaths = idirs
, ghcLink = if th then LinkInMemory else NoLink
, hscTarget = if th then HscInterpreted else HscNothing
, flags = flags d
}
addDevPkgs :: Maybe [Package] -> DynFlags -> DynFlags
addDevPkgs Nothing df = df
addDevPkgs (Just pkgs) df = df' {
packageFlags = map ExposePackage pkgs ++ packageFlags df
}
where
df' = dopt_set df Opt_HideAllPackages
setGhcFlags :: Monad m => Options -> DynFlags -> m DynFlags
setGhcFlags opt flagset =
do (flagset',_,_) <- parseDynamicFlags flagset (map noLoc (ghcOpts opt))
return flagset'
----------------------------------------------------------------
setTargetFile :: (GhcMonad m) => String -> m ()
setTargetFile file = do
target <- guessTarget file Nothing
setTargets [target]