-- | 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 import GHC.Utils.Outputable import GHC.Utils.Panic -- | 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 (LHsExpr GhcPs) | MetaResP (LPat GhcPs) | MetaResT (LHsType GhcPs) | MetaResD [LHsDecl GhcPs] | MetaResAW Serialized instance Outputable MetaResult where ppr (MetaResE e) = text "MetaResE" <> braces (ppr e) ppr (MetaResP p) = text "MetaResP" <> braces (ppr p) ppr (MetaResT t) = text "MetaResT" <> braces (ppr t) ppr (MetaResD d) = text "MetaResD" <> braces (ppr d) ppr (MetaResAW aw) = text "MetaResAW" <> braces (ppr aw) -- These unMetaResE ext panics will triger if the MetaHook doesn't -- take an expression to an expression, pattern to pattern etc. -- -- ToDo: surely this could be expressed in the type system? unMetaResE :: MetaResult -> LHsExpr GhcPs unMetaResE (MetaResE e) = e unMetaResE mr = pprPanic "unMetaResE" (ppr mr) unMetaResP :: MetaResult -> LPat GhcPs unMetaResP (MetaResP p) = p unMetaResP mr = pprPanic "unMetaResP" (ppr mr) unMetaResT :: MetaResult -> LHsType GhcPs unMetaResT (MetaResT t) = t unMetaResT mr = pprPanic "unMetaResT" (ppr mr) unMetaResD :: MetaResult -> [LHsDecl GhcPs] unMetaResD (MetaResD d) = d unMetaResD mr = pprPanic "unMetaResD" (ppr mr) unMetaResAW :: MetaResult -> Serialized unMetaResAW (MetaResAW aw) = aw unMetaResAW mr = pprPanic "unMetaResAW" (ppr mr) type MetaHook f = MetaRequest -> LHsExpr GhcTc -> f MetaResult metaRequestE :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LHsExpr GhcPs) metaRequestE h = fmap unMetaResE . h (MetaE MetaResE) metaRequestP :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LPat GhcPs) metaRequestP h = fmap unMetaResP . h (MetaP MetaResP) metaRequestT :: Functor f => MetaHook f -> LHsExpr GhcTc -> f (LHsType GhcPs) metaRequestT h = fmap unMetaResT . h (MetaT MetaResT) metaRequestD :: Functor f => MetaHook f -> LHsExpr GhcTc -> f [LHsDecl GhcPs] metaRequestD h = fmap unMetaResD . h (MetaD MetaResD) metaRequestAW :: Functor f => MetaHook f -> LHsExpr GhcTc -> f Serialized metaRequestAW h = fmap unMetaResAW . h (MetaAW MetaResAW)