237101bce06c01c35b16eb382643c6a370a51e19
[ghc.git] / compiler / main / Hooks.hs
1 -- \section[Hooks]{Low level API hooks}
2
3 -- NB: this module is SOURCE-imported by DynFlags, and should primarily
4 -- refer to *types*, rather than *code*
5 -- If you import too muchhere , then the revolting compiler_stage2_dll0_MODULES
6 -- stuff in compiler/ghc.mk makes DynFlags link to too much stuff
7
8 {-# LANGUAGE CPP #-}
9 module Hooks ( Hooks
10 , emptyHooks
11 , lookupHook
12 , getHooked
13 -- the hooks:
14 , dsForeignsHook
15 , tcForeignImportsHook
16 , tcForeignExportsHook
17 , hscFrontendHook
18 #ifdef GHCI
19 , hscCompileCoreExprHook
20 #endif
21 , ghcPrimIfaceHook
22 , runPhaseHook
23 , runMetaHook
24 , linkHook
25 , runRnSpliceHook
26 #ifdef GHCI
27 , getValueSafelyHook
28 #endif
29 ) where
30
31 import DynFlags
32 import Name
33 import PipelineMonad
34 import HscTypes
35 import HsDecls
36 import HsBinds
37 import HsExpr
38 import OrdList
39 import Id
40 import TcRnTypes
41 import Bag
42 import RdrName
43 import CoreSyn
44 #ifdef GHCI
45 import GHCi.RemoteTypes
46 import SrcLoc
47 import Type
48 #endif
49 import BasicTypes
50
51 import Data.Maybe
52
53 {-
54 ************************************************************************
55 * *
56 \subsection{Hooks}
57 * *
58 ************************************************************************
59 -}
60
61 -- | Hooks can be used by GHC API clients to replace parts of
62 -- the compiler pipeline. If a hook is not installed, GHC
63 -- uses the default built-in behaviour
64
65 emptyHooks :: Hooks
66 emptyHooks = Hooks
67 { dsForeignsHook = Nothing
68 , tcForeignImportsHook = Nothing
69 , tcForeignExportsHook = Nothing
70 , hscFrontendHook = Nothing
71 #ifdef GHCI
72 , hscCompileCoreExprHook = Nothing
73 #endif
74 , ghcPrimIfaceHook = Nothing
75 , runPhaseHook = Nothing
76 , runMetaHook = Nothing
77 , linkHook = Nothing
78 , runRnSpliceHook = Nothing
79 #ifdef GHCI
80 , getValueSafelyHook = Nothing
81 #endif
82 }
83
84 data Hooks = Hooks
85 { dsForeignsHook :: Maybe ([LForeignDecl Id] -> DsM (ForeignStubs, OrdList (Id, CoreExpr)))
86 , tcForeignImportsHook :: Maybe ([LForeignDecl Name] -> TcM ([Id], [LForeignDecl Id], Bag GlobalRdrElt))
87 , tcForeignExportsHook :: Maybe ([LForeignDecl Name] -> TcM (LHsBinds TcId, [LForeignDecl TcId], Bag GlobalRdrElt))
88 , hscFrontendHook :: Maybe (ModSummary -> Hsc FrontendResult)
89 #ifdef GHCI
90 , hscCompileCoreExprHook :: Maybe (HscEnv -> SrcSpan -> CoreExpr -> IO ForeignHValue)
91 #endif
92 , ghcPrimIfaceHook :: Maybe ModIface
93 , runPhaseHook :: Maybe (PhasePlus -> FilePath -> DynFlags -> CompPipeline (PhasePlus, FilePath))
94 , runMetaHook :: Maybe (MetaHook TcM)
95 , linkHook :: Maybe (GhcLink -> DynFlags -> Bool -> HomePackageTable -> IO SuccessFlag)
96 , runRnSpliceHook :: Maybe (HsSplice Name -> RnM (HsSplice Name))
97 #ifdef GHCI
98 , getValueSafelyHook :: Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue))
99 #endif
100 }
101
102 getHooked :: (Functor f, HasDynFlags f) => (Hooks -> Maybe a) -> a -> f a
103 getHooked hook def = fmap (lookupHook hook def) getDynFlags
104
105 lookupHook :: (Hooks -> Maybe a) -> a -> DynFlags -> a
106 lookupHook hook def = fromMaybe def . hook . hooks