-- | Metaprogramming types
module GHC.Types.Meta
   ( MetaRequest(..)
   , MetaHook
   , MetaResult -- data constructors not exported to ensure correct response type
   , metaRequestE
   , metaRequestP
   , metaRequestT
   , metaRequestD
   , metaRequestAW
   )
where

import GHC.Prelude

import GHC.Serialized   ( Serialized )

import GHC.Hs


-- | The supported metaprogramming result types
data MetaRequest
  = MetaE  (LHsExpr GhcPs   -> MetaResult)
  | MetaP  (LPat GhcPs      -> MetaResult)
  | MetaT  (LHsType GhcPs   -> MetaResult)
  | MetaD  ([LHsDecl GhcPs] -> MetaResult)
  | MetaAW (Serialized     -> MetaResult)

-- | data constructors not exported to ensure correct result type
data MetaResult
  = MetaResE  { MetaResult -> LHsExpr GhcPs
unMetaResE  :: LHsExpr GhcPs   }
  | MetaResP  { MetaResult -> LPat GhcPs
unMetaResP  :: LPat GhcPs      }
  | MetaResT  { MetaResult -> LHsType GhcPs
unMetaResT  :: LHsType GhcPs   }
  | MetaResD  { MetaResult -> [LHsDecl GhcPs]
unMetaResD  :: [LHsDecl GhcPs] }
  | MetaResAW { MetaResult -> Serialized
unMetaResAW :: Serialized      }

type MetaHook f = MetaRequest -> LHsExpr GhcTc -> f MetaResult

metaRequestE :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LHsExpr GhcPs)
metaRequestE :: forall (f :: * -> *).
Functor f =>
MetaHook f -> LHsExpr GhcTc -> f (LHsExpr GhcPs)
metaRequestE MetaHook f
h = (MetaResult -> GenLocated SrcSpanAnnA (HsExpr GhcPs))
-> f MetaResult -> f (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaResult -> LHsExpr GhcPs
MetaResult -> GenLocated SrcSpanAnnA (HsExpr GhcPs)
unMetaResE (f MetaResult -> f (GenLocated SrcSpanAnnA (HsExpr GhcPs)))
-> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
-> GenLocated SrcSpanAnnA (HsExpr GhcTc)
-> f (GenLocated SrcSpanAnnA (HsExpr GhcPs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MetaHook f
h ((LHsExpr GhcPs -> MetaResult) -> MetaRequest
MetaE LHsExpr GhcPs -> MetaResult
MetaResE)

metaRequestP :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LPat GhcPs)
metaRequestP :: forall (f :: * -> *).
Functor f =>
MetaHook f -> LHsExpr GhcTc -> f (LPat GhcPs)
metaRequestP MetaHook f
h = (MetaResult -> GenLocated SrcSpanAnnA (Pat GhcPs))
-> f MetaResult -> f (GenLocated SrcSpanAnnA (Pat GhcPs))
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaResult -> LPat GhcPs
MetaResult -> GenLocated SrcSpanAnnA (Pat GhcPs)
unMetaResP (f MetaResult -> f (GenLocated SrcSpanAnnA (Pat GhcPs)))
-> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
-> GenLocated SrcSpanAnnA (HsExpr GhcTc)
-> f (GenLocated SrcSpanAnnA (Pat GhcPs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MetaHook f
h ((LPat GhcPs -> MetaResult) -> MetaRequest
MetaP LPat GhcPs -> MetaResult
MetaResP)

metaRequestT :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LHsType GhcPs)
metaRequestT :: forall (f :: * -> *).
Functor f =>
MetaHook f -> LHsExpr GhcTc -> f (LHsType GhcPs)
metaRequestT MetaHook f
h = (MetaResult -> GenLocated SrcSpanAnnA (HsType GhcPs))
-> f MetaResult -> f (GenLocated SrcSpanAnnA (HsType GhcPs))
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaResult -> LHsType GhcPs
MetaResult -> GenLocated SrcSpanAnnA (HsType GhcPs)
unMetaResT (f MetaResult -> f (GenLocated SrcSpanAnnA (HsType GhcPs)))
-> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
-> GenLocated SrcSpanAnnA (HsExpr GhcTc)
-> f (GenLocated SrcSpanAnnA (HsType GhcPs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MetaHook f
h ((LHsType GhcPs -> MetaResult) -> MetaRequest
MetaT LHsType GhcPs -> MetaResult
MetaResT)

metaRequestD :: Functor f => MetaHook f -> LHsExpr GhcTc -> f [LHsDecl GhcPs]
metaRequestD :: forall (f :: * -> *).
Functor f =>
MetaHook f -> LHsExpr GhcTc -> f [LHsDecl GhcPs]
metaRequestD MetaHook f
h = (MetaResult -> [GenLocated SrcSpanAnnA (HsDecl GhcPs)])
-> f MetaResult -> f [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaResult -> [LHsDecl GhcPs]
MetaResult -> [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
unMetaResD (f MetaResult -> f [GenLocated SrcSpanAnnA (HsDecl GhcPs)])
-> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
-> GenLocated SrcSpanAnnA (HsExpr GhcTc)
-> f [GenLocated SrcSpanAnnA (HsDecl GhcPs)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MetaHook f
h (([LHsDecl GhcPs] -> MetaResult) -> MetaRequest
MetaD [LHsDecl GhcPs] -> MetaResult
MetaResD)

metaRequestAW :: Functor f => MetaHook f -> LHsExpr GhcTc -> f Serialized
metaRequestAW :: forall (f :: * -> *).
Functor f =>
MetaHook f -> LHsExpr GhcTc -> f Serialized
metaRequestAW MetaHook f
h = (MetaResult -> Serialized) -> f MetaResult -> f Serialized
forall a b. (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MetaResult -> Serialized
unMetaResAW (f MetaResult -> f Serialized)
-> (GenLocated SrcSpanAnnA (HsExpr GhcTc) -> f MetaResult)
-> GenLocated SrcSpanAnnA (HsExpr GhcTc)
-> f Serialized
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MetaHook f
h ((Serialized -> MetaResult) -> MetaRequest
MetaAW Serialized -> MetaResult
MetaResAW)