-- \section[Hooks]{Low level API hooks} -- NB: this module is SOURCE-imported by DynFlags, and should primarily -- refer to *types*, rather than *code* {-# LANGUAGE CPP #-} module Hooks ( Hooks , emptyHooks , lookupHook , getHooked -- the hooks: , dsForeignsHook , tcForeignImportsHook , tcForeignExportsHook , hscFrontendHook , hscCompileCoreExprHook , ghcPrimIfaceHook , runPhaseHook , runMetaHook , linkHook , runRnSpliceHook , getValueSafelyHook , createIservProcessHook ) where import GhcPrelude import DynFlags import PipelineMonad import HscTypes import HsDecls import HsBinds import HsExpr import OrdList import TcRnTypes import Bag import RdrName import Name import Id import CoreSyn import GHCi.RemoteTypes import SrcLoc import Type import System.Process import BasicTypes import HsExtension import Data.Maybe {- ************************************************************************ * * \subsection{Hooks} * * ************************************************************************ -} -- | Hooks can be used by GHC API clients to replace parts of -- the compiler pipeline. If a hook is not installed, GHC -- uses the default built-in behaviour emptyHooks :: Hooks emptyHooks = Hooks { dsForeignsHook = Nothing , tcForeignImportsHook = Nothing , tcForeignExportsHook = Nothing , hscFrontendHook = Nothing , hscCompileCoreExprHook = Nothing , ghcPrimIfaceHook = Nothing , runPhaseHook = Nothing , runMetaHook = Nothing , linkHook = Nothing , runRnSpliceHook = Nothing , getValueSafelyHook = Nothing , createIservProcessHook = Nothing } data Hooks = Hooks { dsForeignsHook :: Maybe ([LForeignDecl GhcTc] -> DsM (ForeignStubs, OrdList (Id, CoreExpr))) , tcForeignImportsHook :: Maybe ([LForeignDecl GhcRn] -> TcM ([Id], [LForeignDecl GhcTc], Bag GlobalRdrElt)) , tcForeignExportsHook :: Maybe ([LForeignDecl GhcRn] -> TcM (LHsBinds GhcTcId, [LForeignDecl GhcTcId], Bag GlobalRdrElt)) , hscFrontendHook :: Maybe (ModSummary -> Hsc FrontendResult) , hscCompileCoreExprHook :: Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO ForeignHValue) , ghcPrimIfaceHook :: Maybe ModIface , runPhaseHook :: Maybe (PhasePlus -> FilePath -> DynFlags -> CompPipeline (PhasePlus, FilePath)) , runMetaHook :: Maybe (MetaHook TcM) , linkHook :: Maybe (GhcLink -> DynFlags -> Bool -> HomePackageTable -> IO SuccessFlag) , runRnSpliceHook :: Maybe (HsSplice GhcRn -> RnM (HsSplice GhcRn)) , getValueSafelyHook :: Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) } getHooked :: (Functor f, HasDynFlags f) => (Hooks -> Maybe a) -> a -> f a getHooked hook def = fmap (lookupHook hook def) getDynFlags lookupHook :: (Hooks -> Maybe a) -> a -> DynFlags -> a lookupHook hook def = fromMaybe def . hook . hooks