GHC.Driver.Monad

ghc-lib-parser-9.10.1.20250103: The GHC API, decoupled from GHC versions

Safe Haskell | Ignore
Language | GHC2021

GHC.Driver.Monad

Contents

- `Ghc` monad stuff
- Logger
  - Diagnostics

Synopsis

- class (Functor m, ExceptionMonad m, HasDynFlags m, HasLogger m) => GhcMonad (m :: Type -> Type) where
  - getSession :: m HscEnv
  - setSession :: HscEnv -> m ()
- newtype Ghc a = Ghc {
  - unGhc :: Session -> IO a
  }
- newtype GhcT (m :: Type -> Type) a = GhcT {
  - unGhcT :: Session -> m a
  }
- liftGhcT :: m a -> GhcT m a
- reflectGhc :: Ghc a -> Session -> IO a
- reifyGhc :: (Session -> IO a) -> Ghc a
- getSessionDynFlags :: GhcMonad m => m DynFlags
- liftIO :: MonadIO m => IO a -> m a
- data Session = Session !(IORef HscEnv)
- withSession :: GhcMonad m => (HscEnv -> m a) -> m a
- modifySession :: GhcMonad m => (HscEnv -> HscEnv) -> m ()
- modifySessionM :: GhcMonad m => (HscEnv -> m HscEnv) -> m ()
- withTempSession :: GhcMonad m => (HscEnv -> HscEnv) -> m a -> m a
- modifyLogger :: GhcMonad m => (Logger -> Logger) -> m ()
- pushLogHookM :: GhcMonad m => (LogAction -> LogAction) -> m ()
- popLogHookM :: GhcMonad m => m ()
- pushJsonLogHookM :: GhcMonad m => (LogJsonAction -> LogJsonAction) -> m ()
- popJsonLogHookM :: GhcMonad m => m ()
- putLogMsgM :: GhcMonad m => MessageClass -> SrcSpan -> SDoc -> m ()
- putMsgM :: GhcMonad m => SDoc -> m ()
- withTimingM :: GhcMonad m => SDoc -> (b -> ()) -> m b -> m b
- logDiagnostics :: GhcMonad m => Messages GhcMessage -> m ()
- printException :: (HasLogger m, MonadIO m, HasDynFlags m) => SourceError -> m ()
- type WarnErrLogger = forall (m :: Type -> Type). (HasDynFlags m, MonadIO m, HasLogger m) => Maybe SourceError -> m ()
- defaultWarnErrLogger :: WarnErrLogger

# `Ghc` monad stuff

class (Functor m, ExceptionMonad m, HasDynFlags m, HasLogger m) => GhcMonad (m :: Type -> Type) where #

A monad that has all the features needed by GHC API calls.

In short, a GHC monad

- allows embedding of IO actions,
- can log warnings,
- allows handling of (extensible) exceptions, and
- maintains a current session.

If you do not use `Ghc` or `GhcT`, make sure to call `initGhcMonad` before any call to the GHC API functions can occur.

Methods

getSession :: m HscEnv #

setSession :: HscEnv -> m () #

#### Instances

Instances details

GhcMonad Ghc # |
Instance details Defined in GHC.Driver.Monad Methods getSession :: Ghc HscEnv # setSession :: HscEnv -> Ghc () #
ExceptionMonad m => GhcMonad (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods getSession :: GhcT m HscEnv # setSession :: HscEnv -> GhcT m () #

newtype Ghc a #

A minimal implementation of a `GhcMonad`. If you need a custom monad, e.g., to maintain additional state consider wrapping this monad or using `GhcT`.

Constructors

Ghc |
Fields unGhc :: Session -> IO a

#### Instances

Instances details

MonadIO Ghc # |
Instance details Defined in GHC.Driver.Monad Methods liftIO :: IO a -> Ghc a #
MonadCatch Ghc # |
Instance details Defined in GHC.Driver.Monad Methods catch :: (HasCallStack, Exception e) => Ghc a -> (e -> Ghc a) -> Ghc a #
MonadMask Ghc # |
Instance details Defined in GHC.Driver.Monad Methods mask :: HasCallStack => ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b # uninterruptibleMask :: HasCallStack => ((forall a. Ghc a -> Ghc a) -> Ghc b) -> Ghc b # generalBracket :: HasCallStack => Ghc a -> (a -> ExitCase b -> Ghc c) -> (a -> Ghc b) -> Ghc (b, c) #
MonadThrow Ghc # |
Instance details Defined in GHC.Driver.Monad Methods throwM :: (HasCallStack, Exception e) => e -> Ghc a #
Applicative Ghc # |
Instance details Defined in GHC.Driver.Monad Methods pure :: a -> Ghc a # (<*>) :: Ghc (a -> b) -> Ghc a -> Ghc b # liftA2 :: (a -> b -> c) -> Ghc a -> Ghc b -> Ghc c # (*>) :: Ghc a -> Ghc b -> Ghc b # (<*) :: Ghc a -> Ghc b -> Ghc a #
Functor Ghc # |
Instance details Defined in GHC.Driver.Monad Methods fmap :: (a -> b) -> Ghc a -> Ghc b # (<$) :: a -> Ghc b -> Ghc a #
Monad Ghc # |
Instance details Defined in GHC.Driver.Monad Methods (>>=) :: Ghc a -> (a -> Ghc b) -> Ghc b # (>>) :: Ghc a -> Ghc b -> Ghc b # return :: a -> Ghc a #
MonadFail Ghc # |
Instance details Defined in GHC.Driver.Monad Methods fail :: String -> Ghc a #
MonadFix Ghc # |
Instance details Defined in GHC.Driver.Monad Methods mfix :: (a -> Ghc a) -> Ghc a #
HasDynFlags Ghc # |
Instance details Defined in GHC.Driver.Monad Methods getDynFlags :: Ghc DynFlags #
GhcMonad Ghc # |
Instance details Defined in GHC.Driver.Monad Methods getSession :: Ghc HscEnv # setSession :: HscEnv -> Ghc () #
HasLogger Ghc # |
Instance details Defined in GHC.Driver.Monad Methods getLogger :: Ghc Logger #

newtype GhcT (m :: Type -> Type) a #

A monad transformer to add GHC specific features to another monad.

Note that the wrapped monad must support IO and handling of exceptions.

Constructors

GhcT |
Fields unGhcT :: Session -> m a

#### Instances

Instances details

MonadIO m => MonadIO (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods liftIO :: IO a -> GhcT m a #
MonadCatch m => MonadCatch (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods catch :: (HasCallStack, Exception e) => GhcT m a -> (e -> GhcT m a) -> GhcT m a #
MonadMask m => MonadMask (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods mask :: HasCallStack => ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b # uninterruptibleMask :: HasCallStack => ((forall a. GhcT m a -> GhcT m a) -> GhcT m b) -> GhcT m b # generalBracket :: HasCallStack => GhcT m a -> (a -> ExitCase b -> GhcT m c) -> (a -> GhcT m b) -> GhcT m (b, c) #
MonadThrow m => MonadThrow (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods throwM :: (HasCallStack, Exception e) => e -> GhcT m a #
Applicative m => Applicative (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods pure :: a -> GhcT m a # (<*>) :: GhcT m (a -> b) -> GhcT m a -> GhcT m b # liftA2 :: (a -> b -> c) -> GhcT m a -> GhcT m b -> GhcT m c # (*>) :: GhcT m a -> GhcT m b -> GhcT m b # (<*) :: GhcT m a -> GhcT m b -> GhcT m a #
Functor m => Functor (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods fmap :: (a -> b) -> GhcT m a -> GhcT m b # (<$) :: a -> GhcT m b -> GhcT m a #
Monad m => Monad (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods (>>=) :: GhcT m a -> (a -> GhcT m b) -> GhcT m b # (>>) :: GhcT m a -> GhcT m b -> GhcT m b # return :: a -> GhcT m a #
MonadFail m => MonadFail (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods fail :: String -> GhcT m a #
MonadFix m => MonadFix (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods mfix :: (a -> GhcT m a) -> GhcT m a #
MonadIO m => HasDynFlags (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods getDynFlags :: GhcT m DynFlags #
ExceptionMonad m => GhcMonad (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods getSession :: GhcT m HscEnv # setSession :: HscEnv -> GhcT m () #
MonadIO m => HasLogger (GhcT m) # |
Instance details Defined in GHC.Driver.Monad Methods getLogger :: GhcT m Logger #

liftGhcT :: m a -> GhcT m a #

reflectGhc :: Ghc a -> Session -> IO a #

Reflect a computation in the `Ghc` monad into the `IO` monad.

You can use this to call functions returning an action in the `Ghc` monad inside an `IO` action. This is needed for some (too restrictive) callback arguments of some library functions:

    libFunc :: String -> (Int -> IO a) -> IO a
    ghcFunc :: Int -> Ghc a

    ghcFuncUsingLibFunc :: String -> Ghc a -> Ghc a
    ghcFuncUsingLibFunc str =
      reifyGhc $ \s ->
        libFunc $ \i -> do
          reflectGhc (ghcFunc i) s

reifyGhc :: (Session -> IO a) -> Ghc a #

getSessionDynFlags :: GhcMonad m => m DynFlags #

Grabs the DynFlags from the Session

liftIO :: MonadIO m => IO a -> m a #

Lift a computation from the `IO` monad. This allows us to run IO computations in any monadic stack, so long as it supports these kinds of operations (i.e. `IO` is the base monad for the stack).

### Example

Expand

    import Control.Monad.Trans.State -- from the "transformers" library

    printState :: Show s => StateT s IO ()
    printState = do
      state <- get
      liftIO $ print state

Had we omitted ``liftIO``, we would have ended up with this error:

    • Couldn't match type ‘IO’ with ‘StateT s IO’
     Expected type: StateT s IO ()
       Actual type: IO ()

The important part here is the mismatch between `StateT s IO ()` and ``IO` ()`.

Luckily, we know of a function that takes an ``IO` a` and returns an `(m a)`: ``liftIO``, enabling us to run the program and see the expected results:

    > evalStateT printState "hello"
    "hello"

    > evalStateT printState 3
    3

data Session #

The Session is a handle to the complete state of a compilation session. A compilation session consists of a set of modules constituting the current program or library, the context for interactive evaluation, and various caches.

Constructors

Session !(IORef HscEnv) |

withSession :: GhcMonad m => (HscEnv -> m a) -> m a #

Call the argument with the current session.

modifySession :: GhcMonad m => (HscEnv -> HscEnv) -> m () #

Set the current session to the result of applying the current session to the argument.

modifySessionM :: GhcMonad m => (HscEnv -> m HscEnv) -> m () #

Set the current session to the result of applying the current session to the argument.

withTempSession :: GhcMonad m => (HscEnv -> HscEnv) -> m a -> m a #

Call an action with a temporarily modified Session.

# Logger

modifyLogger :: GhcMonad m => (Logger -> Logger) -> m () #

Modify the logger

pushLogHookM :: GhcMonad m => (LogAction -> LogAction) -> m () #

Push a log hook on the stack

popLogHookM :: GhcMonad m => m () #

Pop a log hook from the stack

pushJsonLogHookM :: GhcMonad m => (LogJsonAction -> LogJsonAction) -> m () #

popJsonLogHookM :: GhcMonad m => m () #

putLogMsgM :: GhcMonad m => MessageClass -> SrcSpan -> SDoc -> m () #

Put a log message

putMsgM :: GhcMonad m => SDoc -> m () #

Put a log message

withTimingM :: GhcMonad m => SDoc -> (b -> ()) -> m b -> m b #

Time an action

## Diagnostics

logDiagnostics :: GhcMonad m => Messages GhcMessage -> m () #

A monad that allows logging of diagnostics.

printException :: (HasLogger m, MonadIO m, HasDynFlags m) => SourceError -> m () #

Print the all diagnostics in a `SourceError`. Useful inside exception handlers.

type WarnErrLogger = forall (m :: Type -> Type). (HasDynFlags m, MonadIO m, HasLogger m) => Maybe SourceError -> m () #

A function called to log warnings and errors.

defaultWarnErrLogger :: WarnErrLogger #