{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveLift #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TemplateHaskell #-}
module Language.Haskell.TH.TestUtils.QState
( QState(..)
, ReifyInfo(..)
, loadNames
, unmockedState
) where
import Language.Haskell.TH
import Language.Haskell.TH.Instances ()
import Language.Haskell.TH.Syntax (Lift)
#if MIN_VERSION_template_haskell(2,16,0)
import qualified Language.Haskell.TH.Syntax as TH
#endif
import Language.Haskell.TH.TestUtils.QMode (MockedMode(..), QMode(..))
data QState (mode :: MockedMode) = QState
{ mode :: QMode mode
, knownNames :: [(String, Name)]
, reifyInfo :: [(Name, ReifyInfo)]
} deriving (Show, Lift)
data ReifyInfo = ReifyInfo
{ reifyInfoInfo :: Info
, reifyInfoFixity :: Maybe Fixity
, reifyInfoRoles :: Maybe [Role]
, reifyInfoType :: Type
} deriving (Show, Lift)
loadNames :: [Name] -> ExpQ
loadNames names = listE $ flip map names $ \name -> do
info <- reify name
fixity <- reifyFixity name
roles <- recover (pure Nothing) $ Just <$> reifyRoles name
#if MIN_VERSION_template_haskell(2,16,0)
let infoType = reifyType name >>= TH.lift
#else
let infoType = [| error "Your version of template-haskell does not have 'reifyType'" |]
#endif
[| (name, ReifyInfo info fixity roles $infoType) |]
unmockedState :: QState 'NotMocked
unmockedState = QState
{ mode = AllowQ
, knownNames = []
, reifyInfo = []
}