module Generics.Deriving.TH.Post4_9 (
deriveMeta
, deriveData
, deriveConstructors
, deriveSelectors
, mkMetaDataType
, mkMetaConsType
, mkMetaSelType
, SelStrictInfo(..)
, reifySelStrictInfo
) where
import Data.Maybe (fromMaybe)
import Generics.Deriving.TH.Internal
import Language.Haskell.TH.Datatype as THAbs
import Language.Haskell.TH.Lib
import Language.Haskell.TH.Syntax
mkMetaDataType :: DatatypeVariant_ -> Name -> Q Type
mkMetaDataType :: DatatypeVariant_ -> Name -> Q Type
mkMetaDataType DatatypeVariant_
dv Name
n =
Name -> Q Type
promotedT Name
metaDataDataName
Q Type -> Q Type -> Q Type
`appT` TyLitQ -> Q Type
litT (String -> TyLitQ
strTyLit (Name -> String
nameBase Name
n))
Q Type -> Q Type -> Q Type
`appT` TyLitQ -> Q Type
litT (String -> TyLitQ
strTyLit String
m)
Q Type -> Q Type -> Q Type
`appT` TyLitQ -> Q Type
litT (String -> TyLitQ
strTyLit String
pkg)
Q Type -> Q Type -> Q Type
`appT` Bool -> Q Type
promoteBool (DatatypeVariant_ -> Bool
isNewtypeVariant DatatypeVariant_
dv)
where
m, pkg :: String
m :: String
m = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
forall a. HasCallStack => String -> a
error String
"Cannot fetch module name!") (Name -> Maybe String
nameModule Name
n)
pkg :: String
pkg = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
forall a. HasCallStack => String -> a
error String
"Cannot fetch package name!") (Name -> Maybe String
namePackage Name
n)
mkMetaConsType :: DatatypeVariant_ -> Name -> Name -> Bool -> Bool -> Q Type
mkMetaConsType :: DatatypeVariant_ -> Name -> Name -> Bool -> Bool -> Q Type
mkMetaConsType DatatypeVariant_
_ Name
_ Name
n Bool
conIsRecord Bool
conIsInfix = do
Maybe Fixity
mbFi <- Name -> Q (Maybe Fixity)
reifyFixity Name
n
Name -> Q Type
promotedT Name
metaConsDataName
Q Type -> Q Type -> Q Type
`appT` TyLitQ -> Q Type
litT (String -> TyLitQ
strTyLit (Name -> String
nameBase Name
n))
Q Type -> Q Type -> Q Type
`appT` Maybe Fixity -> Bool -> Q Type
fixityIPromotedType Maybe Fixity
mbFi Bool
conIsInfix
Q Type -> Q Type -> Q Type
`appT` Bool -> Q Type
promoteBool Bool
conIsRecord
promoteBool :: Bool -> Q Type
promoteBool :: Bool -> Q Type
promoteBool Bool
True = Name -> Q Type
promotedT Name
trueDataName
promoteBool Bool
False = Name -> Q Type
promotedT Name
falseDataName
fixityIPromotedType :: Maybe Fixity -> Bool -> Q Type
fixityIPromotedType :: Maybe Fixity -> Bool -> Q Type
fixityIPromotedType Maybe Fixity
mbFi Bool
True =
Name -> Q Type
promotedT Name
infixIDataName
Q Type -> Q Type -> Q Type
`appT` FixityDirection -> Q Type
promoteAssociativity FixityDirection
a
Q Type -> Q Type -> Q Type
`appT` TyLitQ -> Q Type
litT (Integer -> TyLitQ
numTyLit (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
n))
where
Fixity Int
n FixityDirection
a = Fixity -> Maybe Fixity -> Fixity
forall a. a -> Maybe a -> a
fromMaybe Fixity
defaultFixity Maybe Fixity
mbFi
fixityIPromotedType Maybe Fixity
_ Bool
False = Name -> Q Type
promotedT Name
prefixIDataName
promoteAssociativity :: FixityDirection -> Q Type
promoteAssociativity :: FixityDirection -> Q Type
promoteAssociativity FixityDirection
InfixL = Name -> Q Type
promotedT Name
leftAssociativeDataName
promoteAssociativity FixityDirection
InfixR = Name -> Q Type
promotedT Name
rightAssociativeDataName
promoteAssociativity FixityDirection
InfixN = Name -> Q Type
promotedT Name
notAssociativeDataName
mkMetaSelType :: DatatypeVariant_ -> Name -> Name -> Maybe Name
-> SelStrictInfo -> Q Type
mkMetaSelType :: DatatypeVariant_
-> Name -> Name -> Maybe Name -> SelStrictInfo -> Q Type
mkMetaSelType DatatypeVariant_
_ Name
_ Name
_ Maybe Name
mbF (SelStrictInfo Unpackedness
su Strictness
ss DecidedStrictness
ds) =
let mbSelNameT :: Q Type
mbSelNameT = case Maybe Name
mbF of
Just Name
f -> Name -> Q Type
promotedT Name
justDataName Q Type -> Q Type -> Q Type
`appT` TyLitQ -> Q Type
litT (String -> TyLitQ
strTyLit (Name -> String
nameBase Name
f))
Maybe Name
Nothing -> Name -> Q Type
promotedT Name
nothingDataName
in Name -> Q Type
promotedT Name
metaSelDataName
Q Type -> Q Type -> Q Type
`appT` Q Type
mbSelNameT
Q Type -> Q Type -> Q Type
`appT` Unpackedness -> Q Type
promoteUnpackedness Unpackedness
su
Q Type -> Q Type -> Q Type
`appT` Strictness -> Q Type
promoteStrictness Strictness
ss
Q Type -> Q Type -> Q Type
`appT` DecidedStrictness -> Q Type
promoteDecidedStrictness DecidedStrictness
ds
data SelStrictInfo = SelStrictInfo Unpackedness Strictness DecidedStrictness
promoteUnpackedness :: Unpackedness -> Q Type
promoteUnpackedness :: Unpackedness -> Q Type
promoteUnpackedness Unpackedness
UnspecifiedUnpackedness = Name -> Q Type
promotedT Name
noSourceUnpackednessDataName
promoteUnpackedness Unpackedness
NoUnpack = Name -> Q Type
promotedT Name
sourceNoUnpackDataName
promoteUnpackedness Unpackedness
Unpack = Name -> Q Type
promotedT Name
sourceUnpackDataName
promoteStrictness :: Strictness -> Q Type
promoteStrictness :: Strictness -> Q Type
promoteStrictness Strictness
UnspecifiedStrictness = Name -> Q Type
promotedT Name
noSourceStrictnessDataName
promoteStrictness Strictness
Lazy = Name -> Q Type
promotedT Name
sourceLazyDataName
promoteStrictness Strictness
THAbs.Strict = Name -> Q Type
promotedT Name
sourceStrictDataName
promoteDecidedStrictness :: DecidedStrictness -> Q Type
promoteDecidedStrictness :: DecidedStrictness -> Q Type
promoteDecidedStrictness DecidedStrictness
DecidedLazy = Name -> Q Type
promotedT Name
decidedLazyDataName
promoteDecidedStrictness DecidedStrictness
DecidedStrict = Name -> Q Type
promotedT Name
decidedStrictDataName
promoteDecidedStrictness DecidedStrictness
DecidedUnpack = Name -> Q Type
promotedT Name
decidedUnpackDataName
reifySelStrictInfo :: Name -> [FieldStrictness] -> Q [SelStrictInfo]
reifySelStrictInfo :: Name -> [FieldStrictness] -> Q [SelStrictInfo]
reifySelStrictInfo Name
conName [FieldStrictness]
fs = do
[DecidedStrictness]
dcdStrs <- Name -> Q [DecidedStrictness]
reifyConStrictness Name
conName
let srcUnpks :: [Unpackedness]
srcUnpks = (FieldStrictness -> Unpackedness)
-> [FieldStrictness] -> [Unpackedness]
forall a b. (a -> b) -> [a] -> [b]
map FieldStrictness -> Unpackedness
fieldUnpackedness [FieldStrictness]
fs
srcStrs :: [Strictness]
srcStrs = (FieldStrictness -> Strictness)
-> [FieldStrictness] -> [Strictness]
forall a b. (a -> b) -> [a] -> [b]
map FieldStrictness -> Strictness
fieldStrictness [FieldStrictness]
fs
[SelStrictInfo] -> Q [SelStrictInfo]
forall (m :: * -> *) a. Monad m => a -> m a
return ([SelStrictInfo] -> Q [SelStrictInfo])
-> [SelStrictInfo] -> Q [SelStrictInfo]
forall a b. (a -> b) -> a -> b
$ (Unpackedness -> Strictness -> DecidedStrictness -> SelStrictInfo)
-> [Unpackedness]
-> [Strictness]
-> [DecidedStrictness]
-> [SelStrictInfo]
forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 Unpackedness -> Strictness -> DecidedStrictness -> SelStrictInfo
SelStrictInfo [Unpackedness]
srcUnpks [Strictness]
srcStrs [DecidedStrictness]
dcdStrs
deriveMeta :: Name -> Q [Dec]
deriveMeta :: Name -> Q [Dec]
deriveMeta Name
_ = [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []
deriveData :: Name -> Q [Dec]
deriveData :: Name -> Q [Dec]
deriveData Name
_ = [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []
deriveConstructors :: Name -> Q [Dec]
deriveConstructors :: Name -> Q [Dec]
deriveConstructors Name
_ = [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []
deriveSelectors :: Name -> Q [Dec]
deriveSelectors :: Name -> Q [Dec]
deriveSelectors Name
_ = [Dec] -> Q [Dec]
forall (m :: * -> *) a. Monad m => a -> m a
return []