{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE EmptyCase #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
module Data.Aeson.TH
(
Options(..)
, SumEncoding(..)
, defaultOptions
, defaultTaggedObject
, deriveJSON
, deriveJSON1
, deriveJSON2
, deriveToJSON
, deriveToJSON1
, deriveToJSON2
, deriveFromJSON
, deriveFromJSON1
, deriveFromJSON2
, mkToJSON
, mkLiftToJSON
, mkLiftToJSON2
, mkToEncoding
, mkLiftToEncoding
, mkLiftToEncoding2
, mkParseJSON
, mkLiftParseJSON
, mkLiftParseJSON2
) where
import Prelude.Compat hiding (fail)
import Prelude (fail)
import Control.Applicative ((<|>))
import Data.Char (ord)
import Data.Aeson (Object, (.:), FromJSON(..), FromJSON1(..), FromJSON2(..), ToJSON(..), ToJSON1(..), ToJSON2(..))
import Data.Aeson.Types (Options(..), Parser, SumEncoding(..), Value(..), defaultOptions, defaultTaggedObject)
import Data.Aeson.Types.Internal ((<?>), JSONPathElement(Key))
import Data.Aeson.Types.FromJSON (parseOptionalFieldWith)
import Data.Aeson.Types.ToJSON (fromPairs, pair)
import Data.Aeson.Key (Key)
import qualified Data.Aeson.Key as Key
import qualified Data.Aeson.KeyMap as KM
import Control.Monad (liftM2, unless, when)
import Data.Foldable (foldr')
#if MIN_VERSION_template_haskell(2,8,0) && !MIN_VERSION_template_haskell(2,10,0)
import Data.List (nub)
#endif
import Data.List (foldl', genericLength, intercalate, partition, union)
import Data.List.NonEmpty ((<|), NonEmpty((:|)))
import Data.Map (Map)
import Data.Maybe (catMaybes, fromMaybe, mapMaybe)
import qualified Data.Monoid as Monoid
import Data.Set (Set)
import Language.Haskell.TH hiding (Arity)
import Language.Haskell.TH.Datatype as Datatype
#if MIN_VERSION_template_haskell(2,8,0) && !(MIN_VERSION_template_haskell(2,10,0))
import Language.Haskell.TH.Syntax (mkNameG_tc)
#endif
import Text.Printf (printf)
import qualified Data.Aeson.Encoding.Internal as E
import qualified Data.Foldable as F (all)
import qualified Data.List.NonEmpty as NE (length, reverse)
import qualified Data.Map as M (fromList, keys, lookup , singleton, size)
#if !MIN_VERSION_base(4,16,0)
import qualified Data.Semigroup as Semigroup (Option(..))
#endif
import qualified Data.Set as Set (empty, insert, member)
import qualified Data.Text as T (pack, unpack)
import qualified Data.Vector as V (unsafeIndex, null, length, create, empty)
import qualified Data.Vector.Mutable as VM (unsafeNew, unsafeWrite)
import qualified Data.Text.Short as ST
import Data.ByteString.Short (ShortByteString)
import Data.Aeson.Internal.ByteString
import Data.Aeson.Internal.TH
deriveJSON :: Options
-> Name
-> Q [Dec]
deriveJSON :: Options -> Name -> Q [Dec]
deriveJSON = (Options -> Name -> Q [Dec])
-> (Options -> Name -> Q [Dec]) -> Options -> Name -> Q [Dec]
deriveJSONBoth Options -> Name -> Q [Dec]
deriveToJSON Options -> Name -> Q [Dec]
deriveFromJSON
deriveJSON1 :: Options
-> Name
-> Q [Dec]
deriveJSON1 :: Options -> Name -> Q [Dec]
deriveJSON1 = (Options -> Name -> Q [Dec])
-> (Options -> Name -> Q [Dec]) -> Options -> Name -> Q [Dec]
deriveJSONBoth Options -> Name -> Q [Dec]
deriveToJSON1 Options -> Name -> Q [Dec]
deriveFromJSON1
deriveJSON2 :: Options
-> Name
-> Q [Dec]
deriveJSON2 :: Options -> Name -> Q [Dec]
deriveJSON2 = (Options -> Name -> Q [Dec])
-> (Options -> Name -> Q [Dec]) -> Options -> Name -> Q [Dec]
deriveJSONBoth Options -> Name -> Q [Dec]
deriveToJSON2 Options -> Name -> Q [Dec]
deriveFromJSON2
deriveToJSON :: Options
-> Name
-> Q [Dec]
deriveToJSON :: Options -> Name -> Q [Dec]
deriveToJSON = JSONClass -> Options -> Name -> Q [Dec]
deriveToJSONCommon JSONClass
toJSONClass
deriveToJSON1 :: Options
-> Name
-> Q [Dec]
deriveToJSON1 :: Options -> Name -> Q [Dec]
deriveToJSON1 = JSONClass -> Options -> Name -> Q [Dec]
deriveToJSONCommon JSONClass
toJSON1Class
deriveToJSON2 :: Options
-> Name
-> Q [Dec]
deriveToJSON2 :: Options -> Name -> Q [Dec]
deriveToJSON2 = JSONClass -> Options -> Name -> Q [Dec]
deriveToJSONCommon JSONClass
toJSON2Class
deriveToJSONCommon :: JSONClass
-> Options
-> Name
-> Q [Dec]
deriveToJSONCommon :: JSONClass -> Options -> Name -> Q [Dec]
deriveToJSONCommon = [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
-> JSONClass -> Options -> Name -> Q [Dec]
deriveJSONClass [ (JSONFun
ToJSON, \JSONClass
jc Name
_ -> ToJSONFun
-> JSONClass -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consToValue ToJSONFun
Value JSONClass
jc)
, (JSONFun
ToEncoding, \JSONClass
jc Name
_ -> ToJSONFun
-> JSONClass -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consToValue ToJSONFun
Encoding JSONClass
jc)
]
mkToJSON :: Options
-> Name
-> Q Exp
mkToJSON :: Options -> Name -> Q Exp
mkToJSON = JSONClass -> Options -> Name -> Q Exp
mkToJSONCommon JSONClass
toJSONClass
mkLiftToJSON :: Options
-> Name
-> Q Exp
mkLiftToJSON :: Options -> Name -> Q Exp
mkLiftToJSON = JSONClass -> Options -> Name -> Q Exp
mkToJSONCommon JSONClass
toJSON1Class
mkLiftToJSON2 :: Options
-> Name
-> Q Exp
mkLiftToJSON2 :: Options -> Name -> Q Exp
mkLiftToJSON2 = JSONClass -> Options -> Name -> Q Exp
mkToJSONCommon JSONClass
toJSON2Class
mkToJSONCommon :: JSONClass
-> Options
-> Name
-> Q Exp
mkToJSONCommon :: JSONClass -> Options -> Name -> Q Exp
mkToJSONCommon = (JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> JSONClass -> Options -> Name -> Q Exp
mkFunCommon (\JSONClass
jc Name
_ -> ToJSONFun
-> JSONClass -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consToValue ToJSONFun
Value JSONClass
jc)
mkToEncoding :: Options
-> Name
-> Q Exp
mkToEncoding :: Options -> Name -> Q Exp
mkToEncoding = JSONClass -> Options -> Name -> Q Exp
mkToEncodingCommon JSONClass
toJSONClass
mkLiftToEncoding :: Options
-> Name
-> Q Exp
mkLiftToEncoding :: Options -> Name -> Q Exp
mkLiftToEncoding = JSONClass -> Options -> Name -> Q Exp
mkToEncodingCommon JSONClass
toJSON1Class
mkLiftToEncoding2 :: Options
-> Name
-> Q Exp
mkLiftToEncoding2 :: Options -> Name -> Q Exp
mkLiftToEncoding2 = JSONClass -> Options -> Name -> Q Exp
mkToEncodingCommon JSONClass
toJSON2Class
mkToEncodingCommon :: JSONClass
-> Options
-> Name
-> Q Exp
mkToEncodingCommon :: JSONClass -> Options -> Name -> Q Exp
mkToEncodingCommon = (JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> JSONClass -> Options -> Name -> Q Exp
mkFunCommon (\JSONClass
jc Name
_ -> ToJSONFun
-> JSONClass -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consToValue ToJSONFun
Encoding JSONClass
jc)
type LetInsert = ShortByteString -> ExpQ
consToValue :: ToJSONFun
-> JSONClass
-> Options
-> [Type]
-> [ConstructorInfo]
-> Q Exp
consToValue :: ToJSONFun
-> JSONClass -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consToValue ToJSONFun
_ JSONClass
_ Options
_ [Type]
_ [] =
[| \x -> case x of {} |]
consToValue ToJSONFun
target JSONClass
jc Options
opts [Type]
instTys [ConstructorInfo]
cons = (ShortByteString -> Q Exp)
-> ((ShortByteString -> Q Exp) -> Q Exp) -> Q Exp
forall a. Ord a => (a -> Q Exp) -> ((a -> Q Exp) -> Q Exp) -> Q Exp
autoletE ShortByteString -> Q Exp
liftSBS (((ShortByteString -> Q Exp) -> Q Exp) -> Q Exp)
-> ((ShortByteString -> Q Exp) -> Q Exp) -> Q Exp
forall a b. (a -> b) -> a -> b
$ \ShortByteString -> Q Exp
letInsert -> do
Name
value <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"value"
[Name]
tjs <- String -> Int -> Q [Name]
newNameList String
"_tj" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ JSONClass -> Int
arityInt JSONClass
jc
[Name]
tjls <- String -> Int -> Q [Name]
newNameList String
"_tjl" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ JSONClass -> Int
arityInt JSONClass
jc
let zippedTJs :: [(Name, Name)]
zippedTJs = [Name] -> [Name] -> [(Name, Name)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
tjs [Name]
tjls
interleavedTJs :: [Name]
interleavedTJs = [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
interleave [Name]
tjs [Name]
tjls
lastTyVars :: [Name]
lastTyVars = (Type -> Name) -> [Type] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Name
varTToName ([Type] -> [Name]) -> [Type] -> [Name]
forall a b. (a -> b) -> a -> b
$ Int -> [Type] -> [Type]
forall a. Int -> [a] -> [a]
drop ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
instTys Int -> Int -> Int
forall a. Num a => a -> a -> a
- JSONClass -> Int
arityInt JSONClass
jc) [Type]
instTys
tvMap :: Map Name (Name, Name)
tvMap = [(Name, (Name, Name))] -> Map Name (Name, Name)
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Name, (Name, Name))] -> Map Name (Name, Name))
-> [(Name, (Name, Name))] -> Map Name (Name, Name)
forall a b. (a -> b) -> a -> b
$ [Name] -> [(Name, Name)] -> [(Name, (Name, Name))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
lastTyVars [(Name, Name)]
zippedTJs
[Q Pat] -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => [m Pat] -> m Exp -> m Exp
lamE ((Name -> Q Pat) -> [Name] -> [Q Pat]
forall a b. (a -> b) -> [a] -> [b]
map Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP ([Name] -> [Q Pat]) -> [Name] -> [Q Pat]
forall a b. (a -> b) -> a -> b
$ [Name]
interleavedTJs [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ [Name
value]) (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
value) ((ShortByteString -> Q Exp) -> Map Name (Name, Name) -> [Q Match]
matches ShortByteString -> Q Exp
letInsert Map Name (Name, Name)
tvMap)
where
matches :: (ShortByteString -> Q Exp) -> Map Name (Name, Name) -> [Q Match]
matches ShortByteString -> Q Exp
letInsert Map Name (Name, Name)
tvMap = case [ConstructorInfo]
cons of
[ConstructorInfo
con] | Bool -> Bool
not (Options -> Bool
tagSingleConstructors Options
opts) -> [(ShortByteString -> Q Exp)
-> ToJSONFun
-> JSONClass
-> Map Name (Name, Name)
-> Options
-> Bool
-> ConstructorInfo
-> Q Match
argsToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target JSONClass
jc Map Name (Name, Name)
tvMap Options
opts Bool
False ConstructorInfo
con]
[ConstructorInfo]
_ | Options -> Bool
allNullaryToStringTag Options
opts Bool -> Bool -> Bool
&& (ConstructorInfo -> Bool) -> [ConstructorInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ConstructorInfo -> Bool
isNullary [ConstructorInfo]
cons ->
[ Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP Name
conName []) (Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ ToJSONFun -> Options -> Name -> Q Exp
conStr ToJSONFun
target Options
opts Name
conName) []
| ConstructorInfo
con <- [ConstructorInfo]
cons
, let conName :: Name
conName = ConstructorInfo -> Name
constructorName ConstructorInfo
con
]
| Bool
otherwise -> [(ShortByteString -> Q Exp)
-> ToJSONFun
-> JSONClass
-> Map Name (Name, Name)
-> Options
-> Bool
-> ConstructorInfo
-> Q Match
argsToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target JSONClass
jc Map Name (Name, Name)
tvMap Options
opts Bool
True ConstructorInfo
con | ConstructorInfo
con <- [ConstructorInfo]
cons]
conStr :: ToJSONFun -> Options -> Name -> Q Exp
conStr :: ToJSONFun -> Options -> Name -> Q Exp
conStr ToJSONFun
Value Options
opts = Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|String|] (Q Exp -> Q Exp) -> (Name -> Q Exp) -> Name -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Name -> Q Exp
conTxt Options
opts
conStr ToJSONFun
Encoding Options
opts = Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|E.text|] (Q Exp -> Q Exp) -> (Name -> Q Exp) -> Name -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Name -> Q Exp
conTxt Options
opts
conTxt :: Options -> Name -> Q Exp
conTxt :: Options -> Name -> Q Exp
conTxt Options
opts = Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|T.pack|] (Q Exp -> Q Exp) -> (Name -> Q Exp) -> Name -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Q Exp
forall (m :: * -> *). Quote m => String -> m Exp
stringE (String -> Q Exp) -> (Name -> String) -> Name -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> Name -> String
conString Options
opts
conString :: Options -> Name -> String
conString :: Options -> Name -> String
conString Options
opts = Options -> String -> String
constructorTagModifier Options
opts (String -> String) -> (Name -> String) -> Name -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> String
nameBase
isNullary :: ConstructorInfo -> Bool
isNullary :: ConstructorInfo -> Bool
isNullary ConstructorInfo { constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
tys } = [Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
tys
isNullary ConstructorInfo
_ = Bool
False
opaqueSumToValue :: LetInsert -> ToJSONFun -> Options -> Bool -> Bool -> Name -> ExpQ -> ExpQ
opaqueSumToValue :: (ShortByteString -> Q Exp)
-> ToJSONFun -> Options -> Bool -> Bool -> Name -> Q Exp -> Q Exp
opaqueSumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons Bool
nullary Name
conName Q Exp
value =
(ShortByteString -> Q Exp)
-> ToJSONFun
-> Options
-> Bool
-> Bool
-> Name
-> Q Exp
-> (String -> Q Exp)
-> Q Exp
sumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons Bool
nullary Name
conName
Q Exp
value
String -> Q Exp
pairs
where
pairs :: String -> Q Exp
pairs String
contentsFieldName = (ShortByteString -> Q Exp) -> ToJSONFun -> String -> Q Exp -> Q Exp
pairE ShortByteString -> Q Exp
letInsert ToJSONFun
target String
contentsFieldName Q Exp
value
recordSumToValue :: LetInsert -> ToJSONFun -> Options -> Bool -> Bool -> Name -> ExpQ -> ExpQ
recordSumToValue :: (ShortByteString -> Q Exp)
-> ToJSONFun -> Options -> Bool -> Bool -> Name -> Q Exp -> Q Exp
recordSumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons Bool
nullary Name
conName Q Exp
pairs =
(ShortByteString -> Q Exp)
-> ToJSONFun
-> Options
-> Bool
-> Bool
-> Name
-> Q Exp
-> (String -> Q Exp)
-> Q Exp
sumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons Bool
nullary Name
conName
(ToJSONFun -> Q Exp -> Q Exp
fromPairsE ToJSONFun
target Q Exp
pairs)
(Q Exp -> String -> Q Exp
forall a b. a -> b -> a
const Q Exp
pairs)
sumToValue
:: LetInsert
-> ToJSONFun
-> Options
-> Bool
-> Bool
-> Name
-> ExpQ
-> (String -> ExpQ)
-> ExpQ
sumToValue :: (ShortByteString -> Q Exp)
-> ToJSONFun
-> Options
-> Bool
-> Bool
-> Name
-> Q Exp
-> (String -> Q Exp)
-> Q Exp
sumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons Bool
nullary Name
conName Q Exp
value String -> Q Exp
pairs
| Bool
multiCons =
case Options -> SumEncoding
sumEncoding Options
opts of
SumEncoding
TwoElemArray ->
ToJSONFun -> [Q Exp] -> Q Exp
array ToJSONFun
target [ToJSONFun -> Options -> Name -> Q Exp
conStr ToJSONFun
target Options
opts Name
conName, Q Exp
value]
TaggedObject{String
tagFieldName :: String
tagFieldName :: SumEncoding -> String
tagFieldName, String
contentsFieldName :: String
contentsFieldName :: SumEncoding -> String
contentsFieldName} ->
let tag :: Q Exp
tag = (ShortByteString -> Q Exp) -> ToJSONFun -> String -> Q Exp -> Q Exp
pairE ShortByteString -> Q Exp
letInsert ToJSONFun
target String
tagFieldName (ToJSONFun -> Options -> Name -> Q Exp
conStr ToJSONFun
target Options
opts Name
conName)
content :: Q Exp
content = String -> Q Exp
pairs String
contentsFieldName
in ToJSONFun -> Q Exp -> Q Exp
fromPairsE ToJSONFun
target (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$
if Bool
nullary then Q Exp
tag else Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
tag [|(Monoid.<>)|] Q Exp
content
SumEncoding
ObjectWithSingleField ->
(ShortByteString -> Q Exp)
-> ToJSONFun -> [(String, Q Exp)] -> Q Exp
objectE ShortByteString -> Q Exp
letInsert ToJSONFun
target [(Options -> Name -> String
conString Options
opts Name
conName, Q Exp
value)]
SumEncoding
UntaggedValue | Bool
nullary -> ToJSONFun -> Options -> Name -> Q Exp
conStr ToJSONFun
target Options
opts Name
conName
SumEncoding
UntaggedValue -> Q Exp
value
| Bool
otherwise = Q Exp
value
argsToValue :: LetInsert -> ToJSONFun -> JSONClass -> TyVarMap -> Options -> Bool -> ConstructorInfo -> Q Match
argsToValue :: (ShortByteString -> Q Exp)
-> ToJSONFun
-> JSONClass
-> Map Name (Name, Name)
-> Options
-> Bool
-> ConstructorInfo
-> Q Match
argsToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target JSONClass
jc Map Name (Name, Name)
tvMap Options
opts Bool
multiCons
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys } = do
[Type]
argTys' <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
let len :: Int
len = [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
argTys'
[Name]
args <- String -> Int -> Q [Name]
newNameList String
"arg" Int
len
let js :: Q Exp
js = case [ ToJSONFun
-> JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchToJSON ToJSONFun
target JSONClass
jc Name
conName Map Name (Name, Name)
tvMap Type
argTy
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arg
| (Name
arg, Type
argTy) <- [Name] -> [Type] -> [(Name, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
args [Type]
argTys'
] of
[Q Exp
e] -> Q Exp
e
[Q Exp]
es -> ToJSONFun -> [Q Exp] -> Q Exp
array ToJSONFun
target [Q Exp]
es
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP Name
conName ([Q Pat] -> Q Pat) -> [Q Pat] -> Q Pat
forall a b. (a -> b) -> a -> b
$ (Name -> Q Pat) -> [Name] -> [Q Pat]
forall a b. (a -> b) -> [a] -> [b]
map Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP [Name]
args)
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ (ShortByteString -> Q Exp)
-> ToJSONFun -> Options -> Bool -> Bool -> Name -> Q Exp -> Q Exp
opaqueSumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons ([Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
argTys') Name
conName Q Exp
js)
[]
argsToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target JSONClass
jc Map Name (Name, Name)
tvMap Options
opts Bool
multiCons
info :: ConstructorInfo
info@ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = RecordConstructor [Name]
fields
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys } =
case (Options -> Bool
unwrapUnaryRecords Options
opts, Bool -> Bool
not Bool
multiCons, [Type]
argTys) of
(Bool
True,Bool
True,[Type
_]) -> (ShortByteString -> Q Exp)
-> ToJSONFun
-> JSONClass
-> Map Name (Name, Name)
-> Options
-> Bool
-> ConstructorInfo
-> Q Match
argsToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target JSONClass
jc Map Name (Name, Name)
tvMap Options
opts Bool
multiCons
(ConstructorInfo
info{constructorVariant :: ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor})
(Bool, Bool, [Type])
_ -> do
[Type]
argTys' <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
[Name]
args <- String -> Int -> Q [Name]
newNameList String
"arg" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
argTys'
let pairs :: Q Exp
pairs | Options -> Bool
omitNothingFields Options
opts = Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
maybeFields
[|(Monoid.<>)|]
Q Exp
restFields
| Bool
otherwise = [Q Exp] -> Q Exp
mconcatE (((Q Exp, Type, Name) -> Q Exp) -> [(Q Exp, Type, Name)] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map (Q Exp, Type, Name) -> Q Exp
pureToPair [(Q Exp, Type, Name)]
argCons)
argCons :: [(Q Exp, Type, Name)]
argCons = [Q Exp] -> [Type] -> [Name] -> [(Q Exp, Type, Name)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 ((Name -> Q Exp) -> [Name] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE [Name]
args) [Type]
argTys' [Name]
fields
maybeFields :: Q Exp
maybeFields = [Q Exp] -> Q Exp
mconcatE (((Q Exp, Type, Name) -> Q Exp) -> [(Q Exp, Type, Name)] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map (Q Exp, Type, Name) -> Q Exp
maybeToPair [(Q Exp, Type, Name)]
maybes)
restFields :: Q Exp
restFields = [Q Exp] -> Q Exp
mconcatE (((Q Exp, Type, Name) -> Q Exp) -> [(Q Exp, Type, Name)] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map (Q Exp, Type, Name) -> Q Exp
pureToPair [(Q Exp, Type, Name)]
rest)
([(Q Exp, Type, Name)]
maybes0, [(Q Exp, Type, Name)]
rest0) = ((Q Exp, Type, Name) -> Bool)
-> [(Q Exp, Type, Name)]
-> ([(Q Exp, Type, Name)], [(Q Exp, Type, Name)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (Q Exp, Type, Name) -> Bool
forall a b. (a, Type, b) -> Bool
isMaybe [(Q Exp, Type, Name)]
argCons
#if MIN_VERSION_base(4,16,0)
maybes :: [(Q Exp, Type, Name)]
maybes = [(Q Exp, Type, Name)]
maybes0
rest :: [(Q Exp, Type, Name)]
rest = [(Q Exp, Type, Name)]
rest0
#else
(options, rest) = partition isOption rest0
maybes = maybes0 ++ map optionToMaybe options
#endif
maybeToPair :: (Q Exp, Type, Name) -> Q Exp
maybeToPair = Bool -> (Q Exp, Type, Name) -> Q Exp
toPairLifted Bool
True
pureToPair :: (Q Exp, Type, Name) -> Q Exp
pureToPair = Bool -> (Q Exp, Type, Name) -> Q Exp
toPairLifted Bool
False
toPairLifted :: Bool -> (Q Exp, Type, Name) -> Q Exp
toPairLifted Bool
lifted (Q Exp
arg, Type
argTy, Name
field) =
let toValue :: Q Exp
toValue = ToJSONFun
-> JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchToJSON ToJSONFun
target JSONClass
jc Name
conName Map Name (Name, Name)
tvMap Type
argTy
fieldName :: String
fieldName = Options -> Name -> String
fieldLabel Options
opts Name
field
e :: Q Exp -> Q Exp
e Q Exp
arg' = (ShortByteString -> Q Exp) -> ToJSONFun -> String -> Q Exp -> Q Exp
pairE ShortByteString -> Q Exp
letInsert ToJSONFun
target String
fieldName (Q Exp
toValue Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Q Exp
arg')
in if Bool
lifted
then do
Name
x <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"x"
[|maybe mempty|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Q Pat -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Pat -> m Exp -> m Exp
lam1E (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
x) (Q Exp -> Q Exp
e (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
x)) Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Q Exp
arg
else Q Exp -> Q Exp
e Q Exp
arg
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP Name
conName ([Q Pat] -> Q Pat) -> [Q Pat] -> Q Pat
forall a b. (a -> b) -> a -> b
$ (Name -> Q Pat) -> [Name] -> [Q Pat]
forall a b. (a -> b) -> [a] -> [b]
map Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP [Name]
args)
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ (ShortByteString -> Q Exp)
-> ToJSONFun -> Options -> Bool -> Bool -> Name -> Q Exp -> Q Exp
recordSumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons ([Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
argTys) Name
conName Q Exp
pairs)
[]
argsToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target JSONClass
jc Map Name (Name, Name)
tvMap Options
opts Bool
multiCons
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
InfixConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys } = do
[Type
alTy, Type
arTy] <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
Name
al <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"argL"
Name
ar <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"argR"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Q Pat -> Name -> Q Pat -> Q Pat
forall (m :: * -> *). Quote m => m Pat -> Name -> m Pat -> m Pat
infixP (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
al) Name
conName (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
ar))
( Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB
(Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ (ShortByteString -> Q Exp)
-> ToJSONFun -> Options -> Bool -> Bool -> Name -> Q Exp -> Q Exp
opaqueSumToValue ShortByteString -> Q Exp
letInsert ToJSONFun
target Options
opts Bool
multiCons Bool
False Name
conName
(Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ ToJSONFun -> [Q Exp] -> Q Exp
array ToJSONFun
target
[ ToJSONFun
-> JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchToJSON ToJSONFun
target JSONClass
jc Name
conName Map Name (Name, Name)
tvMap Type
aTy
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
a
| (Name
a, Type
aTy) <- [(Name
al,Type
alTy), (Name
ar,Type
arTy)]
]
)
[]
isMaybe :: (a, Type, b) -> Bool
isMaybe :: forall a b. (a, Type, b) -> Bool
isMaybe (a
_, AppT (ConT Name
t) Type
_, b
_) = Name
t Name -> Name -> Bool
forall a. Eq a => a -> a -> Bool
== ''Maybe
isMaybe (a, Type, b)
_ = Bool
False
#if !MIN_VERSION_base(4,16,0)
isOption :: (a, Type, b) -> Bool
isOption (_, AppT (ConT t) _, _) = t == ''Semigroup.Option
isOption _ = False
optionToMaybe :: (ExpQ, b, c) -> (ExpQ, b, c)
optionToMaybe (a, b, c) = ([|Semigroup.getOption|] `appE` a, b, c)
#endif
(<^>) :: ExpQ -> ExpQ -> ExpQ
<^> :: Q Exp -> Q Exp -> Q Exp
(<^>) Q Exp
a Q Exp
b = Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
a [|(E.><)|] Q Exp
b
infixr 6 <^>
(<%>) :: ExpQ -> ExpQ -> ExpQ
<%> :: Q Exp -> Q Exp -> Q Exp
(<%>) Q Exp
a Q Exp
b = Q Exp
a Q Exp -> Q Exp -> Q Exp
<^> [|E.comma|] Q Exp -> Q Exp -> Q Exp
<^> Q Exp
b
infixr 4 <%>
array :: ToJSONFun -> [ExpQ] -> ExpQ
array :: ToJSONFun -> [Q Exp] -> Q Exp
array ToJSONFun
Encoding [] = [|E.emptyArray_|]
array ToJSONFun
Value [] = [|Array V.empty|]
array ToJSONFun
Encoding [Q Exp]
es = [|E.wrapArray|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` (Q Exp -> Q Exp -> Q Exp) -> [Q Exp] -> Q Exp
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 Q Exp -> Q Exp -> Q Exp
(<%>) [Q Exp]
es
array ToJSONFun
Value [Q Exp]
es = do
Name
mv <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"mv"
let newMV :: Q Stmt
newMV = Q Pat -> Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Pat -> m Exp -> m Stmt
bindS (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
mv)
([|VM.unsafeNew|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Integer -> Lit
integerL (Integer -> Lit) -> Integer -> Lit
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral ([Q Exp] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Q Exp]
es)))
stmts :: [Q Stmt]
stmts = [ Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Exp -> m Stmt
noBindS (Q Exp -> Q Stmt) -> Q Exp -> Q Stmt
forall a b. (a -> b) -> a -> b
$
[|VM.unsafeWrite|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
mv Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Integer -> Lit
integerL Integer
ix) Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Q Exp
e
| (Integer
ix, Q Exp
e) <- [Integer] -> [Q Exp] -> [(Integer, Q Exp)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Integer
0::Integer)..] [Q Exp]
es
]
ret :: Q Stmt
ret = Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Exp -> m Stmt
noBindS (Q Exp -> Q Stmt) -> Q Exp -> Q Stmt
forall a b. (a -> b) -> a -> b
$ [|return|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
mv
[|Array|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
(Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE 'V.create Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
[Q Stmt] -> Q Exp
forall (m :: * -> *). Quote m => [m Stmt] -> m Exp
doE (Q Stmt
newMVQ Stmt -> [Q Stmt] -> [Q Stmt]
forall a. a -> [a] -> [a]
:[Q Stmt]
stmts[Q Stmt] -> [Q Stmt] -> [Q Stmt]
forall a. [a] -> [a] -> [a]
++[Q Stmt
ret]))
objectE :: LetInsert -> ToJSONFun -> [(String, ExpQ)] -> ExpQ
objectE :: (ShortByteString -> Q Exp)
-> ToJSONFun -> [(String, Q Exp)] -> Q Exp
objectE ShortByteString -> Q Exp
letInsert ToJSONFun
target = ToJSONFun -> Q Exp -> Q Exp
fromPairsE ToJSONFun
target (Q Exp -> Q Exp)
-> ([(String, Q Exp)] -> Q Exp) -> [(String, Q Exp)] -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Q Exp] -> Q Exp
mconcatE ([Q Exp] -> Q Exp)
-> ([(String, Q Exp)] -> [Q Exp]) -> [(String, Q Exp)] -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((String, Q Exp) -> Q Exp) -> [(String, Q Exp)] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((String -> Q Exp -> Q Exp) -> (String, Q Exp) -> Q Exp
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((ShortByteString -> Q Exp) -> ToJSONFun -> String -> Q Exp -> Q Exp
pairE ShortByteString -> Q Exp
letInsert ToJSONFun
target))
mconcatE :: [ExpQ] -> ExpQ
mconcatE :: [Q Exp] -> Q Exp
mconcatE [] = [|Monoid.mempty|]
mconcatE [Q Exp
x] = Q Exp
x
mconcatE (Q Exp
x : [Q Exp]
xs) = Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
x [|(Monoid.<>)|] ([Q Exp] -> Q Exp
mconcatE [Q Exp]
xs)
fromPairsE :: ToJSONFun -> ExpQ -> ExpQ
fromPairsE :: ToJSONFun -> Q Exp -> Q Exp
fromPairsE ToJSONFun
_ = ([|fromPairs|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`)
pairE :: LetInsert -> ToJSONFun -> String -> ExpQ -> ExpQ
pairE :: (ShortByteString -> Q Exp) -> ToJSONFun -> String -> Q Exp -> Q Exp
pairE ShortByteString -> Q Exp
letInsert ToJSONFun
Encoding String
k Q Exp
v = [| E.unsafePairSBS |] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ShortByteString -> Q Exp
letInsert ShortByteString
k' Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Q Exp
v
where
k' :: ShortByteString
k' = ShortText -> ShortByteString
ST.toShortByteString (ShortText -> ShortByteString) -> ShortText -> ShortByteString
forall a b. (a -> b) -> a -> b
$ String -> ShortText
ST.pack (String -> ShortText) -> String -> ShortText
forall a b. (a -> b) -> a -> b
$ String
"\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (Char -> String) -> String -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> String
escapeAscii String
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"\":"
escapeAscii :: Char -> String
escapeAscii Char
'\\' = String
"\\\\"
escapeAscii Char
'\"' = String
"\\\""
escapeAscii Char
'\n' = String
"\\n"
escapeAscii Char
'\r' = String
"\\r"
escapeAscii Char
'\t' = String
"\\t"
escapeAscii Char
c
| Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0x20 = String
"\\u" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"%04x" (Char -> Int
ord Char
c)
escapeAscii Char
c = [Char
c]
pairE ShortByteString -> Q Exp
_letInsert ToJSONFun
Value String
k Q Exp
v = [| pair (Key.fromString k) |] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Q Exp
v
deriveFromJSON :: Options
-> Name
-> Q [Dec]
deriveFromJSON :: Options -> Name -> Q [Dec]
deriveFromJSON = JSONClass -> Options -> Name -> Q [Dec]
deriveFromJSONCommon JSONClass
fromJSONClass
deriveFromJSON1 :: Options
-> Name
-> Q [Dec]
deriveFromJSON1 :: Options -> Name -> Q [Dec]
deriveFromJSON1 = JSONClass -> Options -> Name -> Q [Dec]
deriveFromJSONCommon JSONClass
fromJSON1Class
deriveFromJSON2 :: Options
-> Name
-> Q [Dec]
deriveFromJSON2 :: Options -> Name -> Q [Dec]
deriveFromJSON2 = JSONClass -> Options -> Name -> Q [Dec]
deriveFromJSONCommon JSONClass
fromJSON2Class
deriveFromJSONCommon :: JSONClass
-> Options
-> Name
-> Q [Dec]
deriveFromJSONCommon :: JSONClass -> Options -> Name -> Q [Dec]
deriveFromJSONCommon = [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
-> JSONClass -> Options -> Name -> Q [Dec]
deriveJSONClass [(JSONFun
ParseJSON, JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consFromJSON)]
mkParseJSON :: Options
-> Name
-> Q Exp
mkParseJSON :: Options -> Name -> Q Exp
mkParseJSON = JSONClass -> Options -> Name -> Q Exp
mkParseJSONCommon JSONClass
fromJSONClass
mkLiftParseJSON :: Options
-> Name
-> Q Exp
mkLiftParseJSON :: Options -> Name -> Q Exp
mkLiftParseJSON = JSONClass -> Options -> Name -> Q Exp
mkParseJSONCommon JSONClass
fromJSON1Class
mkLiftParseJSON2 :: Options
-> Name
-> Q Exp
mkLiftParseJSON2 :: Options -> Name -> Q Exp
mkLiftParseJSON2 = JSONClass -> Options -> Name -> Q Exp
mkParseJSONCommon JSONClass
fromJSON2Class
mkParseJSONCommon :: JSONClass
-> Options
-> Name
-> Q Exp
mkParseJSONCommon :: JSONClass -> Options -> Name -> Q Exp
mkParseJSONCommon = (JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> JSONClass -> Options -> Name -> Q Exp
mkFunCommon JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consFromJSON
consFromJSON :: JSONClass
-> Name
-> Options
-> [Type]
-> [ConstructorInfo]
-> Q Exp
consFromJSON :: JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consFromJSON JSONClass
_ Name
_ Options
_ [Type]
_ [] =
[| \_ -> fail "Attempted to parse empty type" |]
consFromJSON JSONClass
jc Name
tName Options
opts [Type]
instTys [ConstructorInfo]
cons = do
Name
value <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"value"
[Name]
pjs <- String -> Int -> Q [Name]
newNameList String
"_pj" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ JSONClass -> Int
arityInt JSONClass
jc
[Name]
pjls <- String -> Int -> Q [Name]
newNameList String
"_pjl" (Int -> Q [Name]) -> Int -> Q [Name]
forall a b. (a -> b) -> a -> b
$ JSONClass -> Int
arityInt JSONClass
jc
let zippedPJs :: [(Name, Name)]
zippedPJs = [Name] -> [Name] -> [(Name, Name)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
pjs [Name]
pjls
interleavedPJs :: [Name]
interleavedPJs = [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
interleave [Name]
pjs [Name]
pjls
lastTyVars :: [Name]
lastTyVars = (Type -> Name) -> [Type] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Name
varTToName ([Type] -> [Name]) -> [Type] -> [Name]
forall a b. (a -> b) -> a -> b
$ Int -> [Type] -> [Type]
forall a. Int -> [a] -> [a]
drop ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
instTys Int -> Int -> Int
forall a. Num a => a -> a -> a
- JSONClass -> Int
arityInt JSONClass
jc) [Type]
instTys
tvMap :: Map Name (Name, Name)
tvMap = [(Name, (Name, Name))] -> Map Name (Name, Name)
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([(Name, (Name, Name))] -> Map Name (Name, Name))
-> [(Name, (Name, Name))] -> Map Name (Name, Name)
forall a b. (a -> b) -> a -> b
$ [Name] -> [(Name, Name)] -> [(Name, (Name, Name))]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
lastTyVars [(Name, Name)]
zippedPJs
[Q Pat] -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => [m Pat] -> m Exp -> m Exp
lamE ((Name -> Q Pat) -> [Name] -> [Q Pat]
forall a b. (a -> b) -> [a] -> [b]
map Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP ([Name] -> [Q Pat]) -> [Name] -> [Q Pat]
forall a b. (a -> b) -> a -> b
$ [Name]
interleavedPJs [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ [Name
value]) (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Name -> Map Name (Name, Name) -> Q Exp
lamExpr Name
value Map Name (Name, Name)
tvMap
where
checkExi :: Map Name (Name, Name) -> ConstructorInfo -> Q a -> Q a
checkExi Map Name (Name, Name)
tvMap ConstructorInfo
con = JSONClass -> Map Name (Name, Name) -> [Type] -> Name -> Q a -> Q a
forall a.
JSONClass -> Map Name (Name, Name) -> [Type] -> Name -> Q a -> Q a
checkExistentialContext JSONClass
jc Map Name (Name, Name)
tvMap
(ConstructorInfo -> [Type]
constructorContext ConstructorInfo
con)
(ConstructorInfo -> Name
constructorName ConstructorInfo
con)
lamExpr :: Name -> Map Name (Name, Name) -> Q Exp
lamExpr Name
value Map Name (Name, Name)
tvMap = case [ConstructorInfo]
cons of
[ConstructorInfo
con]
| Bool -> Bool
not (Options -> Bool
tagSingleConstructors Options
opts)
-> Map Name (Name, Name) -> ConstructorInfo -> Q Exp -> Q Exp
forall {a}. Map Name (Name, Name) -> ConstructorInfo -> Q a -> Q a
checkExi Map Name (Name, Name)
tvMap ConstructorInfo
con (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ JSONClass
-> Map Name (Name, Name)
-> Name
-> Options
-> ConstructorInfo
-> Either (String, Name) Name
-> Q Exp
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
opts ConstructorInfo
con (Name -> Either (String, Name) Name
forall a b. b -> Either a b
Right Name
value)
[ConstructorInfo]
_ | Options -> SumEncoding
sumEncoding Options
opts SumEncoding -> SumEncoding -> Bool
forall a. Eq a => a -> a -> Bool
== SumEncoding
UntaggedValue
-> Map Name (Name, Name) -> [ConstructorInfo] -> Name -> Q Exp
parseUntaggedValue Map Name (Name, Name)
tvMap [ConstructorInfo]
cons Name
value
| Bool
otherwise
-> Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
value) ([Q Match] -> Q Exp) -> [Q Match] -> Q Exp
forall a b. (a -> b) -> a -> b
$
if Options -> Bool
allNullaryToStringTag Options
opts Bool -> Bool -> Bool
&& (ConstructorInfo -> Bool) -> [ConstructorInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ConstructorInfo -> Bool
isNullary [ConstructorInfo]
cons
then [Q Match]
allNullaryMatches
else Map Name (Name, Name) -> [Q Match]
mixedMatches Map Name (Name, Name)
tvMap
allNullaryMatches :: [Q Match]
allNullaryMatches =
[ do Name
txt <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"txtX"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'String [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
txt])
([Q (Guard, Exp)] -> Q Body
forall (m :: * -> *). Quote m => [m (Guard, Exp)] -> m Body
guardedB ([Q (Guard, Exp)] -> Q Body) -> [Q (Guard, Exp)] -> Q Body
forall a b. (a -> b) -> a -> b
$
[ (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG (Q Exp -> Q Guard) -> Q Exp -> Q Guard
forall a b. (a -> b) -> a -> b
$
Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
txt)
[|(==)|]
(Options -> Name -> Q Exp
conTxt Options
opts Name
conName)
)
([|pure|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName)
| ConstructorInfo
con <- [ConstructorInfo]
cons
, let conName :: Name
conName = ConstructorInfo -> Name
constructorName ConstructorInfo
con
]
[Q (Guard, Exp)] -> [Q (Guard, Exp)] -> [Q (Guard, Exp)]
forall a. [a] -> [a] -> [a]
++
[ (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,)
(Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG [|otherwise|])
( [|noMatchFail|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|T.unpack|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
txt)
)
]
)
[]
, do Name
other <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"other"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
other)
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ [|noStringFail|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|valueConName|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
other)
)
[]
]
mixedMatches :: Map Name (Name, Name) -> [Q Match]
mixedMatches Map Name (Name, Name)
tvMap =
case Options -> SumEncoding
sumEncoding Options
opts of
TaggedObject {String
tagFieldName :: SumEncoding -> String
tagFieldName :: String
tagFieldName, String
contentsFieldName :: SumEncoding -> String
contentsFieldName :: String
contentsFieldName} ->
(Name -> Q Exp) -> [Q Match]
forall {m :: * -> *}. Quote m => (Name -> m Exp) -> [m Match]
parseObject ((Name -> Q Exp) -> [Q Match]) -> (Name -> Q Exp) -> [Q Match]
forall a b. (a -> b) -> a -> b
$ Map Name (Name, Name) -> String -> String -> Name -> Q Exp
parseTaggedObject Map Name (Name, Name)
tvMap String
tagFieldName String
contentsFieldName
SumEncoding
UntaggedValue -> String -> [Q Match]
forall a. HasCallStack => String -> a
error String
"UntaggedValue: Should be handled already"
SumEncoding
ObjectWithSingleField ->
(Name -> Q Exp) -> [Q Match]
forall {m :: * -> *}. Quote m => (Name -> m Exp) -> [m Match]
parseObject ((Name -> Q Exp) -> [Q Match]) -> (Name -> Q Exp) -> [Q Match]
forall a b. (a -> b) -> a -> b
$ Map Name (Name, Name) -> Name -> Q Exp
parseObjectWithSingleField Map Name (Name, Name)
tvMap
SumEncoding
TwoElemArray ->
[ do Name
arr <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"array"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'Array [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
arr])
([Q (Guard, Exp)] -> Q Body
forall (m :: * -> *). Quote m => [m (Guard, Exp)] -> m Body
guardedB
[ (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG (Q Exp -> Q Guard) -> Q Exp -> Q Guard
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp ([|V.length|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr)
[|(==)|]
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ Integer -> Lit
integerL Integer
2))
(Map Name (Name, Name) -> Name -> Q Exp
parse2ElemArray Map Name (Name, Name)
tvMap Name
arr)
, (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG [|otherwise|])
([|not2ElemArray|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|V.length|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr))
]
)
[]
, do Name
other <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"other"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
other)
( Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB
(Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ [|noArrayFail|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|valueConName|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
other)
)
[]
]
parseObject :: (Name -> m Exp) -> [m Match]
parseObject Name -> m Exp
f =
[ do Name
obj <- String -> m Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"obj"
m Pat -> m Body -> [m Dec] -> m Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [m Pat] -> m Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'Object [Name -> m Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
obj]) (m Exp -> m Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (m Exp -> m Body) -> m Exp -> m Body
forall a b. (a -> b) -> a -> b
$ Name -> m Exp
f Name
obj) []
, do Name
other <- String -> m Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"other"
m Pat -> m Body -> [m Dec] -> m Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> m Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
other)
( m Exp -> m Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB
(m Exp -> m Body) -> m Exp -> m Body
forall a b. (a -> b) -> a -> b
$ [|noObjectFail|]
m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> m Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|valueConName|] m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> m Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
other)
)
[]
]
parseTaggedObject :: Map Name (Name, Name) -> String -> String -> Name -> Q Exp
parseTaggedObject Map Name (Name, Name)
tvMap String
typFieldName String
valFieldName Name
obj = do
Name
conKey <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"conKeyX"
[Q Stmt] -> Q Exp
forall (m :: * -> *). Quote m => [m Stmt] -> m Exp
doE [ Q Pat -> Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Pat -> m Exp -> m Stmt
bindS (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
conKey)
(Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
obj)
[|(.:)|]
([|Key.fromString|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` String -> Q Exp
forall (m :: * -> *). Quote m => String -> m Exp
stringE String
typFieldName))
, Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Exp -> m Stmt
noBindS (Q Exp -> Q Stmt) -> Q Exp -> Q Stmt
forall a b. (a -> b) -> a -> b
$ Map Name (Name, Name)
-> Name
-> Either (String, Name) Name
-> Name
-> Q Exp
-> Q Exp
-> Q Exp
parseContents Map Name (Name, Name)
tvMap Name
conKey ((String, Name) -> Either (String, Name) Name
forall a b. a -> Either a b
Left (String
valFieldName, Name
obj)) 'conNotFoundFailTaggedObject [|Key.fromString|] [|Key.toString|]
]
parseUntaggedValue :: Map Name (Name, Name) -> [ConstructorInfo] -> Name -> Q Exp
parseUntaggedValue Map Name (Name, Name)
tvMap [ConstructorInfo]
cons' Name
conVal =
(Q Exp -> Q Exp -> Q Exp) -> [Q Exp] -> Q Exp
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\Q Exp
e Q Exp
e' -> Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
e [|(<|>)|] Q Exp
e')
((ConstructorInfo -> Q Exp) -> [ConstructorInfo] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map (\ConstructorInfo
x -> Map Name (Name, Name) -> ConstructorInfo -> Name -> Q Exp
parseValue Map Name (Name, Name)
tvMap ConstructorInfo
x Name
conVal) [ConstructorInfo]
cons')
parseValue :: Map Name (Name, Name) -> ConstructorInfo -> Name -> Q Exp
parseValue Map Name (Name, Name)
_tvMap
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [] }
Name
conVal = do
Name
str <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"str"
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
conVal)
[ Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'String [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
str])
([Q (Guard, Exp)] -> Q Body
forall (m :: * -> *). Quote m => [m (Guard, Exp)] -> m Body
guardedB
[ (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG (Q Exp -> Q Guard) -> Q Exp -> Q Guard
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
str) [|(==)|] (Options -> Name -> Q Exp
conTxt Options
opts Name
conName)
)
([|pure|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName)
]
)
[]
, Name -> Name -> String -> Q Match
matchFailed Name
tName Name
conName String
"String"
]
parseValue Map Name (Name, Name)
tvMap ConstructorInfo
con Name
conVal =
Map Name (Name, Name) -> ConstructorInfo -> Q Exp -> Q Exp
forall {a}. Map Name (Name, Name) -> ConstructorInfo -> Q a -> Q a
checkExi Map Name (Name, Name)
tvMap ConstructorInfo
con (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ JSONClass
-> Map Name (Name, Name)
-> Name
-> Options
-> ConstructorInfo
-> Either (String, Name) Name
-> Q Exp
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
opts ConstructorInfo
con (Name -> Either (String, Name) Name
forall a b. b -> Either a b
Right Name
conVal)
parse2ElemArray :: Map Name (Name, Name) -> Name -> Q Exp
parse2ElemArray Map Name (Name, Name)
tvMap Name
arr = do
Name
conKey <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"conKeyY"
Name
conVal <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"conValY"
let letIx :: Name -> Integer -> m Dec
letIx Name
n Integer
ix =
m Pat -> m Body -> [m Dec] -> m Dec
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Dec
valD (Name -> m Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
n)
(m Exp -> m Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB ([|V.unsafeIndex|] m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Name -> m Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr m Exp -> m Exp -> m Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Lit -> m Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Integer -> Lit
integerL Integer
ix)))
[]
[Q Dec] -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => [m Dec] -> m Exp -> m Exp
letE [ Name -> Integer -> Q Dec
forall {m :: * -> *}. Quote m => Name -> Integer -> m Dec
letIx Name
conKey Integer
0
, Name -> Integer -> Q Dec
forall {m :: * -> *}. Quote m => Name -> Integer -> m Dec
letIx Name
conVal Integer
1
]
(Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
conKey)
[ do Name
txt <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"txtY"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'String [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
txt])
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ Map Name (Name, Name)
-> Name
-> Either (String, Name) Name
-> Name
-> Q Exp
-> Q Exp
-> Q Exp
parseContents Map Name (Name, Name)
tvMap
Name
txt
(Name -> Either (String, Name) Name
forall a b. b -> Either a b
Right Name
conVal)
'conNotFoundFail2ElemArray
[|T.pack|] [|T.unpack|]
)
[]
, do Name
other <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"other"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
other)
( Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB
(Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ [|firstElemNoStringFail|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|valueConName|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
other)
)
[]
]
)
parseObjectWithSingleField :: Map Name (Name, Name) -> Name -> Q Exp
parseObjectWithSingleField Map Name (Name, Name)
tvMap Name
obj = do
Name
conKey <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"conKeyZ"
Name
conVal <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"conValZ"
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE ([e|KM.toList|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
obj)
[ Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match ([Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => [m Pat] -> m Pat
listP [[Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => [m Pat] -> m Pat
tupP [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
conKey, Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
conVal]])
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ Map Name (Name, Name)
-> Name
-> Either (String, Name) Name
-> Name
-> Q Exp
-> Q Exp
-> Q Exp
parseContents Map Name (Name, Name)
tvMap Name
conKey (Name -> Either (String, Name) Name
forall a b. b -> Either a b
Right Name
conVal) 'conNotFoundFailObjectSingleField [|Key.fromString|] [|Key.toString|])
[]
, do Name
other <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"other"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
other)
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ [|wrongPairCountFail|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ([|show . length|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
other)
)
[]
]
parseContents :: Map Name (Name, Name)
-> Name
-> Either (String, Name) Name
-> Name
-> Q Exp
-> Q Exp
-> Q Exp
parseContents Map Name (Name, Name)
tvMap Name
conKey Either (String, Name) Name
contents Name
errorFun Q Exp
pack Q Exp
unpack=
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
conKey)
[ Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match Q Pat
forall (m :: * -> *). Quote m => m Pat
wildP
( [Q (Guard, Exp)] -> Q Body
forall (m :: * -> *). Quote m => [m (Guard, Exp)] -> m Body
guardedB ([Q (Guard, Exp)] -> Q Body) -> [Q (Guard, Exp)] -> Q Body
forall a b. (a -> b) -> a -> b
$
[ do Guard
g <- Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG (Q Exp -> Q Guard) -> Q Exp -> Q Guard
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
conKey)
[|(==)|]
(Q Exp
pack Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Options -> ConstructorInfo -> Q Exp
conNameExp Options
opts ConstructorInfo
con)
Exp
e <- Map Name (Name, Name) -> ConstructorInfo -> Q Exp -> Q Exp
forall {a}. Map Name (Name, Name) -> ConstructorInfo -> Q a -> Q a
checkExi Map Name (Name, Name)
tvMap ConstructorInfo
con (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$
JSONClass
-> Map Name (Name, Name)
-> Name
-> Options
-> ConstructorInfo
-> Either (String, Name) Name
-> Q Exp
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
opts ConstructorInfo
con Either (String, Name) Name
contents
(Guard, Exp) -> Q (Guard, Exp)
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return (Guard
g, Exp
e)
| ConstructorInfo
con <- [ConstructorInfo]
cons
]
[Q (Guard, Exp)] -> [Q (Guard, Exp)] -> [Q (Guard, Exp)]
forall a. [a] -> [a] -> [a]
++
[ (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,)
(Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG [e|otherwise|])
( Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
errorFun
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` [Q Exp] -> Q Exp
forall (m :: * -> *). Quote m => [m Exp] -> m Exp
listE ((ConstructorInfo -> Q Exp) -> [ConstructorInfo] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map ( Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE
(Lit -> Q Exp)
-> (ConstructorInfo -> Lit) -> ConstructorInfo -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Lit
stringL
(String -> Lit)
-> (ConstructorInfo -> String) -> ConstructorInfo -> Lit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> String -> String
constructorTagModifier Options
opts
(String -> String)
-> (ConstructorInfo -> String) -> ConstructorInfo -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> String
nameBase
(Name -> String)
-> (ConstructorInfo -> Name) -> ConstructorInfo -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstructorInfo -> Name
constructorName
) [ConstructorInfo]
cons
)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` (Q Exp
unpack Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
conKey)
)
]
)
[]
]
parseNullaryMatches :: Name -> Name -> [Q Match]
parseNullaryMatches :: Name -> Name -> [Q Match]
parseNullaryMatches Name
tName Name
conName =
[ do Name
arr <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"arr"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'Array [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
arr])
([Q (Guard, Exp)] -> Q Body
forall (m :: * -> *). Quote m => [m (Guard, Exp)] -> m Body
guardedB
[ (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG (Q Exp -> Q Guard) -> Q Exp -> Q Guard
forall a b. (a -> b) -> a -> b
$ [|V.null|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr)
([|pure|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName)
, (Guard -> Exp -> (Guard, Exp))
-> Q Guard -> Q Exp -> Q (Guard, Exp)
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 (,) (Q Exp -> Q Guard
forall (m :: * -> *). Quote m => m Exp -> m Guard
normalG [|otherwise|])
(Name -> Name -> Q Exp -> Q Exp -> Q Exp
parseTypeMismatch Name
tName Name
conName
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL String
"an empty Array")
(Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL String
"Array of length ")
[|(++)|]
([|show . V.length|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr)
)
)
]
)
[]
, Name -> Name -> String -> Q Match
matchFailed Name
tName Name
conName String
"Array"
]
parseUnaryMatches :: JSONClass -> TyVarMap -> Type -> Name -> [Q Match]
parseUnaryMatches :: JSONClass -> Map Name (Name, Name) -> Type -> Name -> [Q Match]
parseUnaryMatches JSONClass
jc Map Name (Name, Name)
tvMap Type
argTy Name
conName =
[ do Name
arg <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"arg"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
arg)
( Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName)
[|(<$>)|]
(JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchParseJSON JSONClass
jc Name
conName Map Name (Name, Name)
tvMap Type
argTy
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arg)
)
[]
]
parseRecord :: JSONClass
-> TyVarMap
-> [Type]
-> Options
-> Name
-> Name
-> [Name]
-> Name
-> Bool
-> ExpQ
parseRecord :: JSONClass
-> Map Name (Name, Name)
-> [Type]
-> Options
-> Name
-> Name
-> [Name]
-> Name
-> Bool
-> Q Exp
parseRecord JSONClass
jc Map Name (Name, Name)
tvMap [Type]
argTys Options
opts Name
tName Name
conName [Name]
fields Name
obj Bool
inTaggedObject =
(if Options -> Bool
rejectUnknownFields Options
opts
then Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
checkUnknownRecords [|(>>)|]
else Q Exp -> Q Exp
forall a. a -> a
id) (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$
(Q Exp -> Q Exp -> Q Exp) -> Q Exp -> [Q Exp] -> Q Exp
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Q Exp
a Q Exp
b -> Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
a [|(<*>)|] Q Exp
b)
(Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName) [|(<$>)|] Q Exp
x)
[Q Exp]
xs
where
tagFieldNameAppender :: [String] -> [String]
tagFieldNameAppender =
if Bool
inTaggedObject then (SumEncoding -> String
tagFieldName (Options -> SumEncoding
sumEncoding Options
opts) String -> [String] -> [String]
forall a. a -> [a] -> [a]
:) else [String] -> [String]
forall a. a -> a
id
knownFields :: Q Exp
knownFields = Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|KM.fromList|] (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ [Q Exp] -> Q Exp
forall (m :: * -> *). Quote m => [m Exp] -> m Exp
listE ([Q Exp] -> Q Exp) -> [Q Exp] -> Q Exp
forall a b. (a -> b) -> a -> b
$
(String -> Q Exp) -> [String] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map (\String
knownName -> [Q Exp] -> Q Exp
forall (m :: * -> *). Quote m => [m Exp] -> m Exp
tupE [Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|Key.fromString|] (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL String
knownName, [|()|]]) ([String] -> [Q Exp]) -> [String] -> [Q Exp]
forall a b. (a -> b) -> a -> b
$
[String] -> [String]
tagFieldNameAppender ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ (Name -> String) -> [Name] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Options -> Name -> String
fieldLabel Options
opts) [Name]
fields
checkUnknownRecords :: Q Exp
checkUnknownRecords =
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|KM.keys|] (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
obj) [|KM.difference|] Q Exp
knownFields)
[ Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match ([Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => [m Pat] -> m Pat
listP []) (Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB [|return ()|]) []
, String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"unknownFields" Q Name -> (Name -> Q Match) -> Q Match
forall a b. Q a -> (a -> Q b) -> Q b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
\Name
unknownFields -> Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
unknownFields)
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|fail|] (Q Exp -> Q Exp) -> Q Exp -> Q Exp
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL String
"Unknown fields: "))
[|(++)|]
(Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE [|show|] (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
unknownFields)))
[]
]
Q Exp
x:[Q Exp]
xs = [ [|lookupField|]
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchParseJSON JSONClass
jc Name
conName Map Name (Name, Name)
tvMap Type
argTy
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Options -> String -> String
constructorTagModifier Options
opts (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Name -> String
nameBase Name
conName)
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
obj
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` ( [|Key.fromString|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` String -> Q Exp
forall (m :: * -> *). Quote m => String -> m Exp
stringE (Options -> Name -> String
fieldLabel Options
opts Name
field)
)
| (Name
field, Type
argTy) <- [Name] -> [Type] -> [(Name, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
fields [Type]
argTys
]
getValField :: Name -> String -> [MatchQ] -> Q Exp
getValField :: Name -> String -> [Q Match] -> Q Exp
getValField Name
obj String
valFieldName [Q Match]
matches = do
Name
val <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"val"
[Q Stmt] -> Q Exp
forall (m :: * -> *). Quote m => [m Stmt] -> m Exp
doE [ Q Pat -> Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Pat -> m Exp -> m Stmt
bindS (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
val) (Q Exp -> Q Stmt) -> Q Exp -> Q Stmt
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
obj)
[|(.:)|]
([|Key.fromString|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (String -> Lit
stringL String
valFieldName))
, Q Exp -> Q Stmt
forall (m :: * -> *). Quote m => m Exp -> m Stmt
noBindS (Q Exp -> Q Stmt) -> Q Exp -> Q Stmt
forall a b. (a -> b) -> a -> b
$ Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
val) [Q Match]
matches
]
matchCases :: Either (String, Name) Name -> [MatchQ] -> Q Exp
matchCases :: Either (String, Name) Name -> [Q Match] -> Q Exp
matchCases (Left (String
valFieldName, Name
obj)) = Name -> String -> [Q Match] -> Q Exp
getValField Name
obj String
valFieldName
matchCases (Right Name
valName) = Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
valName)
parseArgs :: JSONClass
-> TyVarMap
-> Name
-> Options
-> ConstructorInfo
-> Either (String, Name) Name
-> Q Exp
parseArgs :: JSONClass
-> Map Name (Name, Name)
-> Name
-> Options
-> ConstructorInfo
-> Either (String, Name) Name
-> Q Exp
parseArgs JSONClass
_ Map Name (Name, Name)
_ Name
_ Options
_
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [] }
(Left (String, Name)
_) =
[|pure|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName
parseArgs JSONClass
_ Map Name (Name, Name)
_ Name
tName Options
_
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [] }
(Right Name
valName) =
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
valName) ([Q Match] -> Q Exp) -> [Q Match] -> Q Exp
forall a b. (a -> b) -> a -> b
$ Name -> Name -> [Q Match]
parseNullaryMatches Name
tName Name
conName
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
_ Options
_
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type
argTy] }
Either (String, Name) Name
contents = do
Type
argTy' <- Type -> Q Type
resolveTypeSynonyms Type
argTy
Either (String, Name) Name -> [Q Match] -> Q Exp
matchCases Either (String, Name) Name
contents ([Q Match] -> Q Exp) -> [Q Match] -> Q Exp
forall a b. (a -> b) -> a -> b
$ JSONClass -> Map Name (Name, Name) -> Type -> Name -> [Q Match]
parseUnaryMatches JSONClass
jc Map Name (Name, Name)
tvMap Type
argTy' Name
conName
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
_
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys }
Either (String, Name) Name
contents = do
[Type]
argTys' <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
let len :: Integer
len = [Type] -> Integer
forall i a. Num i => [a] -> i
genericLength [Type]
argTys'
Either (String, Name) Name -> [Q Match] -> Q Exp
matchCases Either (String, Name) Name
contents ([Q Match] -> Q Exp) -> [Q Match] -> Q Exp
forall a b. (a -> b) -> a -> b
$ JSONClass
-> Map Name (Name, Name)
-> [Type]
-> Name
-> Name
-> Integer
-> [Q Match]
parseProduct JSONClass
jc Map Name (Name, Name)
tvMap [Type]
argTys' Name
tName Name
conName Integer
len
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
opts
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = RecordConstructor [Name]
fields
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys }
(Left (String
_, Name
obj)) = do
[Type]
argTys' <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
JSONClass
-> Map Name (Name, Name)
-> [Type]
-> Options
-> Name
-> Name
-> [Name]
-> Name
-> Bool
-> Q Exp
parseRecord JSONClass
jc Map Name (Name, Name)
tvMap [Type]
argTys' Options
opts Name
tName Name
conName [Name]
fields Name
obj Bool
True
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
opts
info :: ConstructorInfo
info@ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = RecordConstructor [Name]
fields
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys }
(Right Name
valName) =
case (Options -> Bool
unwrapUnaryRecords Options
opts,[Type]
argTys) of
(Bool
True,[Type
_])-> JSONClass
-> Map Name (Name, Name)
-> Name
-> Options
-> ConstructorInfo
-> Either (String, Name) Name
-> Q Exp
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
opts
(ConstructorInfo
info{constructorVariant :: ConstructorVariant
constructorVariant = ConstructorVariant
NormalConstructor})
(Name -> Either (String, Name) Name
forall a b. b -> Either a b
Right Name
valName)
(Bool, [Type])
_ -> do
Name
obj <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"recObj"
[Type]
argTys' <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
Q Exp -> [Q Match] -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> [m Match] -> m Exp
caseE (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
valName)
[ Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'Object [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
obj]) (Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$
JSONClass
-> Map Name (Name, Name)
-> [Type]
-> Options
-> Name
-> Name
-> [Name]
-> Name
-> Bool
-> Q Exp
parseRecord JSONClass
jc Map Name (Name, Name)
tvMap [Type]
argTys' Options
opts Name
tName Name
conName [Name]
fields Name
obj Bool
False) []
, Name -> Name -> String -> Q Match
matchFailed Name
tName Name
conName String
"Object"
]
parseArgs JSONClass
jc Map Name (Name, Name)
tvMap Name
tName Options
_
ConstructorInfo { constructorName :: ConstructorInfo -> Name
constructorName = Name
conName
, constructorVariant :: ConstructorInfo -> ConstructorVariant
constructorVariant = ConstructorVariant
InfixConstructor
, constructorFields :: ConstructorInfo -> [Type]
constructorFields = [Type]
argTys }
Either (String, Name) Name
contents = do
[Type]
argTys' <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
argTys
Either (String, Name) Name -> [Q Match] -> Q Exp
matchCases Either (String, Name) Name
contents ([Q Match] -> Q Exp) -> [Q Match] -> Q Exp
forall a b. (a -> b) -> a -> b
$ JSONClass
-> Map Name (Name, Name)
-> [Type]
-> Name
-> Name
-> Integer
-> [Q Match]
parseProduct JSONClass
jc Map Name (Name, Name)
tvMap [Type]
argTys' Name
tName Name
conName Integer
2
parseProduct :: JSONClass
-> TyVarMap
-> [Type]
-> Name
-> Name
-> Integer
-> [Q Match]
parseProduct :: JSONClass
-> Map Name (Name, Name)
-> [Type]
-> Name
-> Name
-> Integer
-> [Q Match]
parseProduct JSONClass
jc Map Name (Name, Name)
tvMap [Type]
argTys Name
tName Name
conName Integer
numArgs =
[ do Name
arr <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"arr"
let Q Exp
x:[Q Exp]
xs = [ JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchParseJSON JSONClass
jc Name
conName Map Name (Name, Name)
tvMap Type
argTy
Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE`
Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr)
[|V.unsafeIndex|]
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ Integer -> Lit
integerL Integer
ix)
| (Type
argTy, Integer
ix) <- [Type] -> [Integer] -> [(Type, Integer)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Type]
argTys [Integer
0 .. Integer
numArgs Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1]
]
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> [Q Pat] -> Q Pat
forall (m :: * -> *). Quote m => Name -> [m Pat] -> m Pat
conP 'Array [Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
arr])
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
condE ( Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp ([|V.length|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr)
[|(==)|]
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ Integer -> Lit
integerL Integer
numArgs)
)
( (Q Exp -> Q Exp -> Q Exp) -> Q Exp -> [Q Exp] -> Q Exp
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Q Exp
a Q Exp
b -> Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp Q Exp
a [|(<*>)|] Q Exp
b)
(Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
conE Name
conName) [|(<$>)|] Q Exp
x)
[Q Exp]
xs
)
( Name -> Name -> Q Exp -> Q Exp -> Q Exp
parseTypeMismatch Name
tName Name
conName
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ String
"Array of length " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Integer -> String
forall a. Show a => a -> String
show Integer
numArgs)
( Q Exp -> Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp -> m Exp
infixApp (Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL String
"Array of length ")
[|(++)|]
([|show . V.length|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
arr)
)
)
)
[]
, Name -> Name -> String -> Q Match
matchFailed Name
tName Name
conName String
"Array"
]
matchFailed :: Name -> Name -> String -> MatchQ
matchFailed :: Name -> Name -> String -> Q Match
matchFailed Name
tName Name
conName String
expected = do
Name
other <- String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName String
"other"
Q Pat -> Q Body -> [Q Dec] -> Q Match
forall (m :: * -> *).
Quote m =>
m Pat -> m Body -> [m Dec] -> m Match
match (Name -> Q Pat
forall (m :: * -> *). Quote m => Name -> m Pat
varP Name
other)
( Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ Name -> Name -> Q Exp -> Q Exp -> Q Exp
parseTypeMismatch Name
tName Name
conName
(Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL String
expected)
([|valueConName|] Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
`appE` Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE Name
other)
)
[]
parseTypeMismatch :: Name -> Name -> ExpQ -> ExpQ -> ExpQ
parseTypeMismatch :: Name -> Name -> Q Exp -> Q Exp -> Q Exp
parseTypeMismatch Name
tName Name
conName Q Exp
expected Q Exp
actual =
(Q Exp -> Q Exp -> Q Exp) -> Q Exp -> [Q Exp] -> Q Exp
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Q Exp -> Q Exp -> Q Exp
forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
appE
[|parseTypeMismatch'|]
[ Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
nameBase Name
conName
, Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE (Lit -> Q Exp) -> Lit -> Q Exp
forall a b. (a -> b) -> a -> b
$ String -> Lit
stringL (String -> Lit) -> String -> Lit
forall a b. (a -> b) -> a -> b
$ Name -> String
forall a. Show a => a -> String
show Name
tName
, Q Exp
expected
, Q Exp
actual
]
class LookupField a where
lookupField :: (Value -> Parser a) -> String -> String
-> Object -> Key -> Parser a
instance {-# OVERLAPPABLE #-} LookupField a where
lookupField :: (Value -> Parser a)
-> String -> String -> Object -> Key -> Parser a
lookupField = (Value -> Parser a)
-> String -> String -> Object -> Key -> Parser a
forall a.
(Value -> Parser a)
-> String -> String -> Object -> Key -> Parser a
lookupFieldWith
instance {-# INCOHERENT #-} LookupField (Maybe a) where
lookupField :: (Value -> Parser (Maybe a))
-> String -> String -> Object -> Key -> Parser (Maybe a)
lookupField Value -> Parser (Maybe a)
pj String
_ String
_ = (Value -> Parser (Maybe a)) -> Object -> Key -> Parser (Maybe a)
forall a.
(Value -> Parser (Maybe a)) -> Object -> Key -> Parser (Maybe a)
parseOptionalFieldWith Value -> Parser (Maybe a)
pj
#if !MIN_VERSION_base(4,16,0)
instance {-# INCOHERENT #-} LookupField (Semigroup.Option a) where
lookupField pj tName rec obj key =
fmap Semigroup.Option
(lookupField (fmap Semigroup.getOption . pj) tName rec obj key)
#endif
lookupFieldWith :: (Value -> Parser a) -> String -> String
-> Object -> Key -> Parser a
lookupFieldWith :: forall a.
(Value -> Parser a)
-> String -> String -> Object -> Key -> Parser a
lookupFieldWith Value -> Parser a
pj String
tName String
rec Object
obj Key
key =
case Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KM.lookup Key
key Object
obj of
Maybe Value
Nothing -> String -> String -> String -> Parser a
forall fail. String -> String -> String -> Parser fail
unknownFieldFail String
tName String
rec (Key -> String
Key.toString Key
key)
Just Value
v -> Value -> Parser a
pj Value
v Parser a -> JSONPathElement -> Parser a
forall a. Parser a -> JSONPathElement -> Parser a
<?> Key -> JSONPathElement
Key Key
key
unknownFieldFail :: String -> String -> String -> Parser fail
unknownFieldFail :: forall fail. String -> String -> String -> Parser fail
unknownFieldFail String
tName String
rec String
key =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing the record %s of type %s the key %s was not present."
String
rec String
tName String
key
noArrayFail :: String -> String -> Parser fail
noArrayFail :: forall fail. String -> String -> Parser fail
noArrayFail String
t String
o = String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected Array but got %s." String
t String
o
noObjectFail :: String -> String -> Parser fail
noObjectFail :: forall fail. String -> String -> Parser fail
noObjectFail String
t String
o = String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected Object but got %s." String
t String
o
firstElemNoStringFail :: String -> String -> Parser fail
firstElemNoStringFail :: forall fail. String -> String -> Parser fail
firstElemNoStringFail String
t String
o = String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected an Array of 2 elements where the first element is a String but got %s at the first element." String
t String
o
wrongPairCountFail :: String -> String -> Parser fail
wrongPairCountFail :: forall fail. String -> String -> Parser fail
wrongPairCountFail String
t String
n =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected an Object with a single tag/contents pair but got %s pairs."
String
t String
n
noStringFail :: String -> String -> Parser fail
noStringFail :: forall fail. String -> String -> Parser fail
noStringFail String
t String
o = String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected String but got %s." String
t String
o
noMatchFail :: String -> String -> Parser fail
noMatchFail :: forall fail. String -> String -> Parser fail
noMatchFail String
t String
o =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected a String with the tag of a constructor but got %s." String
t String
o
not2ElemArray :: String -> Int -> Parser fail
not2ElemArray :: forall fail. String -> Int -> Parser fail
not2ElemArray String
t Int
i = String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> Int -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected an Array of 2 elements but got %i elements" String
t Int
i
conNotFoundFail2ElemArray :: String -> [String] -> String -> Parser fail
conNotFoundFail2ElemArray :: forall fail. String -> [String] -> String -> Parser fail
conNotFoundFail2ElemArray String
t [String]
cs String
o =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected a 2-element Array with a tag and contents element where the tag is one of [%s], but got %s."
String
t (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
cs) String
o
conNotFoundFailObjectSingleField :: String -> [String] -> String -> Parser fail
conNotFoundFailObjectSingleField :: forall fail. String -> [String] -> String -> Parser fail
conNotFoundFailObjectSingleField String
t [String]
cs String
o =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected an Object with a single tag/contents pair where the tag is one of [%s], but got %s."
String
t (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
cs) String
o
conNotFoundFailTaggedObject :: String -> [String] -> String -> Parser fail
conNotFoundFailTaggedObject :: forall fail. String -> [String] -> String -> Parser fail
conNotFoundFailTaggedObject String
t [String]
cs String
o =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing %s expected an Object with a tag field where the value is one of [%s], but got %s."
String
t (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
cs) String
o
parseTypeMismatch' :: String -> String -> String -> String -> Parser fail
parseTypeMismatch' :: forall fail. String -> String -> String -> String -> Parser fail
parseTypeMismatch' String
conName String
tName String
expected String
actual =
String -> Parser fail
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser fail) -> String -> Parser fail
forall a b. (a -> b) -> a -> b
$ String -> String -> String -> String -> String -> String
forall r. PrintfType r => String -> r
printf String
"When parsing the constructor %s of type %s expected %s but got %s."
String
conName String
tName String
expected String
actual
deriveJSONBoth :: (Options -> Name -> Q [Dec])
-> (Options -> Name -> Q [Dec])
-> Options
-> Name
-> Q [Dec]
deriveJSONBoth :: (Options -> Name -> Q [Dec])
-> (Options -> Name -> Q [Dec]) -> Options -> Name -> Q [Dec]
deriveJSONBoth Options -> Name -> Q [Dec]
dtj Options -> Name -> Q [Dec]
dfj Options
opts Name
name =
([Dec] -> [Dec] -> [Dec]) -> Q [Dec] -> Q [Dec] -> Q [Dec]
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
(++) (Options -> Name -> Q [Dec]
dtj Options
opts Name
name) (Options -> Name -> Q [Dec]
dfj Options
opts Name
name)
deriveJSONClass :: [(JSONFun, JSONClass -> Name -> Options -> [Type]
-> [ConstructorInfo] -> Q Exp)]
-> JSONClass
-> Options
-> Name
-> Q [Dec]
deriveJSONClass :: [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
-> JSONClass -> Options -> Name -> Q [Dec]
deriveJSONClass [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
consFuns JSONClass
jc Options
opts Name
name = do
DatatypeInfo
info <- Name -> Q DatatypeInfo
reifyDatatype Name
name
case DatatypeInfo
info of
DatatypeInfo { datatypeContext :: DatatypeInfo -> [Type]
datatypeContext = [Type]
ctxt
, datatypeName :: DatatypeInfo -> Name
datatypeName = Name
parentName
#if MIN_VERSION_th_abstraction(0,3,0)
, datatypeInstTypes :: DatatypeInfo -> [Type]
datatypeInstTypes = [Type]
instTys
#else
, datatypeVars = instTys
#endif
, datatypeVariant :: DatatypeInfo -> DatatypeVariant
datatypeVariant = DatatypeVariant
variant
, datatypeCons :: DatatypeInfo -> [ConstructorInfo]
datatypeCons = [ConstructorInfo]
cons
} -> do
([Type]
instanceCxt, Type
instanceType)
<- Name
-> JSONClass
-> [Type]
-> [Type]
-> DatatypeVariant
-> Q ([Type], Type)
buildTypeInstance Name
parentName JSONClass
jc [Type]
ctxt [Type]
instTys DatatypeVariant
variant
(Dec -> [Dec] -> [Dec]
forall a. a -> [a] -> [a]
:[]) (Dec -> [Dec]) -> Q Dec -> Q [Dec]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Q [Type] -> Q Type -> [Q Dec] -> Q Dec
forall (m :: * -> *).
Quote m =>
m [Type] -> m Type -> [m Dec] -> m Dec
instanceD ([Type] -> Q [Type]
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return [Type]
instanceCxt)
(Type -> Q Type
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Type
instanceType)
(Name -> [Type] -> [ConstructorInfo] -> [Q Dec]
methodDecs Name
parentName [Type]
instTys [ConstructorInfo]
cons)
where
methodDecs :: Name -> [Type] -> [ConstructorInfo] -> [Q Dec]
methodDecs :: Name -> [Type] -> [ConstructorInfo] -> [Q Dec]
methodDecs Name
parentName [Type]
instTys [ConstructorInfo]
cons = (((JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> Q Dec)
-> [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
-> [Q Dec])
-> [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
-> ((JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> Q Dec)
-> [Q Dec]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> Q Dec)
-> [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
-> [Q Dec]
forall a b. (a -> b) -> [a] -> [b]
map [(JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)]
consFuns (((JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> Q Dec)
-> [Q Dec])
-> ((JSONFun,
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> Q Dec)
-> [Q Dec]
forall a b. (a -> b) -> a -> b
$ \(JSONFun
jf, JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
jfMaker) ->
Name -> [Q Clause] -> Q Dec
forall (m :: * -> *). Quote m => Name -> [m Clause] -> m Dec
funD (JSONFun -> Arity -> Name
jsonFunValName JSONFun
jf (JSONClass -> Arity
arity JSONClass
jc))
[ [Q Pat] -> Q Body -> [Q Dec] -> Q Clause
forall (m :: * -> *).
Quote m =>
[m Pat] -> m Body -> [m Dec] -> m Clause
clause []
(Q Exp -> Q Body
forall (m :: * -> *). Quote m => m Exp -> m Body
normalB (Q Exp -> Q Body) -> Q Exp -> Q Body
forall a b. (a -> b) -> a -> b
$ JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
jfMaker JSONClass
jc Name
parentName Options
opts [Type]
instTys [ConstructorInfo]
cons)
[]
]
mkFunCommon :: (JSONClass -> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> JSONClass
-> Options
-> Name
-> Q Exp
mkFunCommon :: (JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp)
-> JSONClass -> Options -> Name -> Q Exp
mkFunCommon JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consFun JSONClass
jc Options
opts Name
name = do
DatatypeInfo
info <- Name -> Q DatatypeInfo
reifyDatatype Name
name
case DatatypeInfo
info of
DatatypeInfo { datatypeContext :: DatatypeInfo -> [Type]
datatypeContext = [Type]
ctxt
, datatypeName :: DatatypeInfo -> Name
datatypeName = Name
parentName
#if MIN_VERSION_th_abstraction(0,3,0)
, datatypeInstTypes :: DatatypeInfo -> [Type]
datatypeInstTypes = [Type]
instTys
#else
, datatypeVars = instTys
#endif
, datatypeVariant :: DatatypeInfo -> DatatypeVariant
datatypeVariant = DatatypeVariant
variant
, datatypeCons :: DatatypeInfo -> [ConstructorInfo]
datatypeCons = [ConstructorInfo]
cons
} -> do
!([Type], Type)
_ <- Name
-> JSONClass
-> [Type]
-> [Type]
-> DatatypeVariant
-> Q ([Type], Type)
buildTypeInstance Name
parentName JSONClass
jc [Type]
ctxt [Type]
instTys DatatypeVariant
variant
JSONClass
-> Name -> Options -> [Type] -> [ConstructorInfo] -> Q Exp
consFun JSONClass
jc Name
parentName Options
opts [Type]
instTys [ConstructorInfo]
cons
dispatchFunByType :: JSONClass
-> JSONFun
-> Name
-> TyVarMap
-> Bool
-> Type
-> Q Exp
dispatchFunByType :: JSONClass
-> JSONFun
-> Name
-> Map Name (Name, Name)
-> Bool
-> Type
-> Q Exp
dispatchFunByType JSONClass
_ JSONFun
jf Name
_ Map Name (Name, Name)
tvMap Bool
list (VarT Name
tyName) =
Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE (Name -> Q Exp) -> Name -> Q Exp
forall a b. (a -> b) -> a -> b
$ case Name -> Map Name (Name, Name) -> Maybe (Name, Name)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Name
tyName Map Name (Name, Name)
tvMap of
Just (Name
tfjExp, Name
tfjlExp) -> if Bool
list then Name
tfjlExp else Name
tfjExp
Maybe (Name, Name)
Nothing -> Bool -> JSONFun -> Arity -> Name
jsonFunValOrListName Bool
list JSONFun
jf Arity
Arity0
dispatchFunByType JSONClass
jc JSONFun
jf Name
conName Map Name (Name, Name)
tvMap Bool
list (SigT Type
ty Type
_) =
JSONClass
-> JSONFun
-> Name
-> Map Name (Name, Name)
-> Bool
-> Type
-> Q Exp
dispatchFunByType JSONClass
jc JSONFun
jf Name
conName Map Name (Name, Name)
tvMap Bool
list Type
ty
dispatchFunByType JSONClass
jc JSONFun
jf Name
conName Map Name (Name, Name)
tvMap Bool
list (ForallT [TyVarBndr Specificity]
_ [Type]
_ Type
ty) =
JSONClass
-> JSONFun
-> Name
-> Map Name (Name, Name)
-> Bool
-> Type
-> Q Exp
dispatchFunByType JSONClass
jc JSONFun
jf Name
conName Map Name (Name, Name)
tvMap Bool
list Type
ty
dispatchFunByType JSONClass
jc JSONFun
jf Name
conName Map Name (Name, Name)
tvMap Bool
list Type
ty = do
let tyCon :: Type
tyArgs :: [Type]
Type
tyCon :| [Type]
tyArgs = Type -> NonEmpty Type
unapplyTy Type
ty
numLastArgs :: Int
numLastArgs :: Int
numLastArgs = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (JSONClass -> Int
arityInt JSONClass
jc) ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tyArgs)
lhsArgs, rhsArgs :: [Type]
([Type]
lhsArgs, [Type]
rhsArgs) = Int -> [Type] -> ([Type], [Type])
forall a. Int -> [a] -> ([a], [a])
splitAt ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tyArgs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
numLastArgs) [Type]
tyArgs
tyVarNames :: [Name]
tyVarNames :: [Name]
tyVarNames = Map Name (Name, Name) -> [Name]
forall k a. Map k a -> [k]
M.keys Map Name (Name, Name)
tvMap
Bool
itf <- [Name] -> Type -> [Type] -> Q Bool
isInTypeFamilyApp [Name]
tyVarNames Type
tyCon [Type]
tyArgs
if (Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Type -> [Name] -> Bool
`mentionsName` [Name]
tyVarNames) [Type]
lhsArgs Bool -> Bool -> Bool
|| Bool
itf
then JSONClass -> Name -> Q Exp
forall a. JSONClass -> Name -> a
outOfPlaceTyVarError JSONClass
jc Name
conName
else if (Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Type -> [Name] -> Bool
`mentionsName` [Name]
tyVarNames) [Type]
rhsArgs
then [Q Exp] -> Q Exp
forall (m :: * -> *). Quote m => [m Exp] -> m Exp
appsE ([Q Exp] -> Q Exp) -> [Q Exp] -> Q Exp
forall a b. (a -> b) -> a -> b
$ Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE (Bool -> JSONFun -> Arity -> Name
jsonFunValOrListName Bool
list JSONFun
jf (Arity -> Name) -> Arity -> Name
forall a b. (a -> b) -> a -> b
$ Int -> Arity
forall a. Enum a => Int -> a
toEnum Int
numLastArgs)
Q Exp -> [Q Exp] -> [Q Exp]
forall a. a -> [a] -> [a]
: (Bool -> Type -> Q Exp) -> [Bool] -> [Type] -> [Q Exp]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (JSONClass
-> JSONFun
-> Name
-> Map Name (Name, Name)
-> Bool
-> Type
-> Q Exp
dispatchFunByType JSONClass
jc JSONFun
jf Name
conName Map Name (Name, Name)
tvMap)
([Bool] -> [Bool]
forall a. HasCallStack => [a] -> [a]
cycle [Bool
False,Bool
True])
([Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
interleave [Type]
rhsArgs [Type]
rhsArgs)
else Name -> Q Exp
forall (m :: * -> *). Quote m => Name -> m Exp
varE (Name -> Q Exp) -> Name -> Q Exp
forall a b. (a -> b) -> a -> b
$ Bool -> JSONFun -> Arity -> Name
jsonFunValOrListName Bool
list JSONFun
jf Arity
Arity0
dispatchToJSON
:: ToJSONFun -> JSONClass -> Name -> TyVarMap -> Type -> Q Exp
dispatchToJSON :: ToJSONFun
-> JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchToJSON ToJSONFun
target JSONClass
jc Name
n Map Name (Name, Name)
tvMap =
JSONClass
-> JSONFun
-> Name
-> Map Name (Name, Name)
-> Bool
-> Type
-> Q Exp
dispatchFunByType JSONClass
jc (ToJSONFun -> JSONFun
targetToJSONFun ToJSONFun
target) Name
n Map Name (Name, Name)
tvMap Bool
False
dispatchParseJSON
:: JSONClass -> Name -> TyVarMap -> Type -> Q Exp
dispatchParseJSON :: JSONClass -> Name -> Map Name (Name, Name) -> Type -> Q Exp
dispatchParseJSON JSONClass
jc Name
n Map Name (Name, Name)
tvMap = JSONClass
-> JSONFun
-> Name
-> Map Name (Name, Name)
-> Bool
-> Type
-> Q Exp
dispatchFunByType JSONClass
jc JSONFun
ParseJSON Name
n Map Name (Name, Name)
tvMap Bool
False
buildTypeInstance :: Name
-> JSONClass
-> Cxt
-> [Type]
-> DatatypeVariant
-> Q (Cxt, Type)
buildTypeInstance :: Name
-> JSONClass
-> [Type]
-> [Type]
-> DatatypeVariant
-> Q ([Type], Type)
buildTypeInstance Name
tyConName JSONClass
jc [Type]
dataCxt [Type]
varTysOrig DatatypeVariant
variant = do
[Type]
varTysExp <- (Type -> Q Type) -> [Type] -> Q [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Type -> Q Type
resolveTypeSynonyms [Type]
varTysOrig
let remainingLength :: Int
remainingLength :: Int
remainingLength = [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
varTysOrig Int -> Int -> Int
forall a. Num a => a -> a -> a
- JSONClass -> Int
arityInt JSONClass
jc
droppedTysExp :: [Type]
droppedTysExp :: [Type]
droppedTysExp = Int -> [Type] -> [Type]
forall a. Int -> [a] -> [a]
drop Int
remainingLength [Type]
varTysExp
droppedStarKindStati :: [StarKindStatus]
droppedStarKindStati :: [StarKindStatus]
droppedStarKindStati = (Type -> StarKindStatus) -> [Type] -> [StarKindStatus]
forall a b. (a -> b) -> [a] -> [b]
map Type -> StarKindStatus
canRealizeKindStar [Type]
droppedTysExp
Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
remainingLength Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| StarKindStatus -> [StarKindStatus] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem StarKindStatus
NotKindStar [StarKindStatus]
droppedStarKindStati) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
JSONClass -> Name -> Q ()
forall a. JSONClass -> Name -> Q a
derivingKindError JSONClass
jc Name
tyConName
let droppedKindVarNames :: [Name]
droppedKindVarNames :: [Name]
droppedKindVarNames = [StarKindStatus] -> [Name]
catKindVarNames [StarKindStatus]
droppedStarKindStati
varTysExpSubst :: [Type]
varTysExpSubst :: [Type]
varTysExpSubst = (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ([Name] -> Type -> Type
substNamesWithKindStar [Name]
droppedKindVarNames) [Type]
varTysExp
remainingTysExpSubst, droppedTysExpSubst :: [Type]
([Type]
remainingTysExpSubst, [Type]
droppedTysExpSubst) =
Int -> [Type] -> ([Type], [Type])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
remainingLength [Type]
varTysExpSubst
droppedTyVarNames :: [Name]
droppedTyVarNames :: [Name]
droppedTyVarNames = [Type] -> [Name]
forall a. TypeSubstitution a => a -> [Name]
freeVariables [Type]
droppedTysExpSubst
Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
hasKindStar [Type]
droppedTysExpSubst) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
JSONClass -> Name -> Q ()
forall a. JSONClass -> Name -> Q a
derivingKindError JSONClass
jc Name
tyConName
let preds :: [Maybe Pred]
kvNames :: [[Name]]
kvNames' :: [Name]
([Maybe Type]
preds, [[Name]]
kvNames) = [(Maybe Type, [Name])] -> ([Maybe Type], [[Name]])
forall a b. [(a, b)] -> ([a], [b])
unzip ([(Maybe Type, [Name])] -> ([Maybe Type], [[Name]]))
-> [(Maybe Type, [Name])] -> ([Maybe Type], [[Name]])
forall a b. (a -> b) -> a -> b
$ (Type -> (Maybe Type, [Name])) -> [Type] -> [(Maybe Type, [Name])]
forall a b. (a -> b) -> [a] -> [b]
map (JSONClass -> Type -> (Maybe Type, [Name])
deriveConstraint JSONClass
jc) [Type]
remainingTysExpSubst
kvNames' :: [Name]
kvNames' = [[Name]] -> [Name]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Name]]
kvNames
remainingTysExpSubst' :: [Type]
remainingTysExpSubst' :: [Type]
remainingTysExpSubst' =
(Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ([Name] -> Type -> Type
substNamesWithKindStar [Name]
kvNames') [Type]
remainingTysExpSubst
remainingTysOrigSubst :: [Type]
remainingTysOrigSubst :: [Type]
remainingTysOrigSubst =
(Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ([Name] -> Type -> Type
substNamesWithKindStar ([Name]
droppedKindVarNames [Name] -> [Name] -> [Name]
forall a. Eq a => [a] -> [a] -> [a]
`union` [Name]
kvNames'))
([Type] -> [Type]) -> [Type] -> [Type]
forall a b. (a -> b) -> a -> b
$ Int -> [Type] -> [Type]
forall a. Int -> [a] -> [a]
take Int
remainingLength [Type]
varTysOrig
isDataFamily :: Bool
isDataFamily :: Bool
isDataFamily = case DatatypeVariant
variant of
DatatypeVariant
Datatype -> Bool
False
DatatypeVariant
Newtype -> Bool
False
DatatypeVariant
DataInstance -> Bool
True
DatatypeVariant
NewtypeInstance -> Bool
True
#if MIN_VERSION_th_abstraction(0,5,0)
Datatype.TypeData -> False
#endif
remainingTysOrigSubst' :: [Type]
remainingTysOrigSubst' :: [Type]
remainingTysOrigSubst' =
if Bool
isDataFamily
then [Type]
remainingTysOrigSubst
else (Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
unSigT [Type]
remainingTysOrigSubst
instanceCxt :: Cxt
instanceCxt :: [Type]
instanceCxt = [Maybe Type] -> [Type]
forall a. [Maybe a] -> [a]
catMaybes [Maybe Type]
preds
instanceType :: Type
instanceType :: Type
instanceType = Type -> Type -> Type
AppT (Name -> Type
ConT (Name -> Type) -> Name -> Type
forall a b. (a -> b) -> a -> b
$ JSONClass -> Name
jsonClassName JSONClass
jc)
(Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$ Name -> [Type] -> Type
applyTyCon Name
tyConName [Type]
remainingTysOrigSubst'
Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Type -> [Name] -> Bool
`predMentionsName` [Name]
droppedTyVarNames) [Type]
dataCxt) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
Name -> Type -> Q ()
forall a. Name -> Type -> Q a
datatypeContextError Name
tyConName Type
instanceType
Bool -> Q () -> Q ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([Type] -> [Type] -> Bool
canEtaReduce [Type]
remainingTysExpSubst' [Type]
droppedTysExpSubst) (Q () -> Q ()) -> Q () -> Q ()
forall a b. (a -> b) -> a -> b
$
Type -> Q ()
forall a. Type -> Q a
etaReductionError Type
instanceType
([Type], Type) -> Q ([Type], Type)
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Type]
instanceCxt, Type
instanceType)
deriveConstraint :: JSONClass -> Type -> (Maybe Pred, [Name])
deriveConstraint :: JSONClass -> Type -> (Maybe Type, [Name])
deriveConstraint JSONClass
jc Type
t
| Bool -> Bool
not (Type -> Bool
isTyVar Type
t) = (Maybe Type
forall a. Maybe a
Nothing, [])
| Type -> Bool
hasKindStar Type
t = (Type -> Maybe Type
forall a. a -> Maybe a
Just (Name -> Name -> Type
applyCon (Arity -> Name
jcConstraint Arity
Arity0) Name
tName), [])
| Bool
otherwise = case Int -> Type -> Maybe [Name]
hasKindVarChain Int
1 Type
t of
Just [Name]
ns | Arity
jcArity Arity -> Arity -> Bool
forall a. Ord a => a -> a -> Bool
>= Arity
Arity1
-> (Type -> Maybe Type
forall a. a -> Maybe a
Just (Name -> Name -> Type
applyCon (Arity -> Name
jcConstraint Arity
Arity1) Name
tName), [Name]
ns)
Maybe [Name]
_ -> case Int -> Type -> Maybe [Name]
hasKindVarChain Int
2 Type
t of
Just [Name]
ns | Arity
jcArity Arity -> Arity -> Bool
forall a. Eq a => a -> a -> Bool
== Arity
Arity2
-> (Type -> Maybe Type
forall a. a -> Maybe a
Just (Name -> Name -> Type
applyCon (Arity -> Name
jcConstraint Arity
Arity2) Name
tName), [Name]
ns)
Maybe [Name]
_ -> (Maybe Type
forall a. Maybe a
Nothing, [])
where
tName :: Name
tName :: Name
tName = Type -> Name
varTToName Type
t
jcArity :: Arity
jcArity :: Arity
jcArity = JSONClass -> Arity
arity JSONClass
jc
jcConstraint :: Arity -> Name
jcConstraint :: Arity -> Name
jcConstraint = JSONClass -> Name
jsonClassName (JSONClass -> Name) -> (Arity -> JSONClass) -> Arity -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Direction -> Arity -> JSONClass
JSONClass (JSONClass -> Direction
direction JSONClass
jc)
checkExistentialContext :: JSONClass -> TyVarMap -> Cxt -> Name
-> Q a -> Q a
checkExistentialContext :: forall a.
JSONClass -> Map Name (Name, Name) -> [Type] -> Name -> Q a -> Q a
checkExistentialContext JSONClass
jc Map Name (Name, Name)
tvMap [Type]
ctxt Name
conName Q a
q =
if ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Type -> [Name] -> Bool
`predMentionsName` Map Name (Name, Name) -> [Name]
forall k a. Map k a -> [k]
M.keys Map Name (Name, Name)
tvMap) [Type]
ctxt
Bool -> Bool -> Bool
|| Map Name (Name, Name) -> Int
forall k a. Map k a -> Int
M.size Map Name (Name, Name)
tvMap Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< JSONClass -> Int
arityInt JSONClass
jc)
Bool -> Bool -> Bool
&& Bool -> Bool
not (JSONClass -> Bool
allowExQuant JSONClass
jc)
then Name -> Q a
forall a. Name -> a
existentialContextError Name
conName
else Q a
q
type TyVarMap = Map Name (Name, Name)
hasKindStar :: Type -> Bool
hasKindStar :: Type -> Bool
hasKindStar VarT{} = Bool
True
hasKindStar (SigT Type
_ Type
StarT) = Bool
True
hasKindStar Type
_ = Bool
False
isStarOrVar :: Kind -> Bool
isStarOrVar :: Type -> Bool
isStarOrVar Type
StarT = Bool
True
isStarOrVar VarT{} = Bool
True
isStarOrVar Type
_ = Bool
False
newNameList :: String -> Int -> Q [Name]
newNameList :: String -> Int -> Q [Name]
newNameList String
prefix Int
len = (String -> Q Name) -> [String] -> Q [Name]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM String -> Q Name
forall (m :: * -> *). Quote m => String -> m Name
newName [String
prefix String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n | Int
n <- [Int
1..Int
len]]
hasKindVarChain :: Int -> Type -> Maybe [Name]
hasKindVarChain :: Int -> Type -> Maybe [Name]
hasKindVarChain Int
kindArrows Type
t =
let uk :: NonEmpty Type
uk = Type -> NonEmpty Type
uncurryKind (Type -> Type
tyKind Type
t)
in if (NonEmpty Type -> Int
forall a. NonEmpty a -> Int
NE.length NonEmpty Type
uk Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
kindArrows) Bool -> Bool -> Bool
&& (Type -> Bool) -> NonEmpty Type -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
F.all Type -> Bool
isStarOrVar NonEmpty Type
uk
then [Name] -> Maybe [Name]
forall a. a -> Maybe a
Just ((Type -> [Name]) -> NonEmpty Type -> [Name]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Type -> [Name]
forall a. TypeSubstitution a => a -> [Name]
freeVariables NonEmpty Type
uk)
else Maybe [Name]
forall a. Maybe a
Nothing
tyKind :: Type -> Kind
tyKind :: Type -> Type
tyKind (SigT Type
_ Type
k) = Type
k
tyKind Type
_ = Type
starK
varTToNameMaybe :: Type -> Maybe Name
varTToNameMaybe :: Type -> Maybe Name
varTToNameMaybe (VarT Name
n) = Name -> Maybe Name
forall a. a -> Maybe a
Just Name
n
varTToNameMaybe (SigT Type
t Type
_) = Type -> Maybe Name
varTToNameMaybe Type
t
varTToNameMaybe Type
_ = Maybe Name
forall a. Maybe a
Nothing
varTToName :: Type -> Name
varTToName :: Type -> Name
varTToName = Name -> Maybe Name -> Name
forall a. a -> Maybe a -> a
fromMaybe (String -> Name
forall a. HasCallStack => String -> a
error String
"Not a type variable!") (Maybe Name -> Name) -> (Type -> Maybe Name) -> Type -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Maybe Name
varTToNameMaybe
interleave :: [a] -> [a] -> [a]
interleave :: forall a. [a] -> [a] -> [a]
interleave (a
a1:[a]
a1s) (a
a2:[a]
a2s) = a
a1a -> [a] -> [a]
forall a. a -> [a] -> [a]
:a
a2a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
interleave [a]
a1s [a]
a2s
interleave [a]
_ [a]
_ = []
applyTyCon :: Name -> [Type] -> Type
applyTyCon :: Name -> [Type] -> Type
applyTyCon = (Type -> Type -> Type) -> Type -> [Type] -> Type
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Type -> Type -> Type
AppT (Type -> [Type] -> Type)
-> (Name -> Type) -> Name -> [Type] -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Type
ConT
isTyVar :: Type -> Bool
isTyVar :: Type -> Bool
isTyVar (VarT Name
_) = Bool
True
isTyVar (SigT Type
t Type
_) = Type -> Bool
isTyVar Type
t
isTyVar Type
_ = Bool
False
isInTypeFamilyApp :: [Name] -> Type -> [Type] -> Q Bool
isInTypeFamilyApp :: [Name] -> Type -> [Type] -> Q Bool
isInTypeFamilyApp [Name]
names Type
tyFun [Type]
tyArgs =
case Type
tyFun of
ConT Name
tcName -> Name -> Q Bool
go Name
tcName
Type
_ -> Bool -> Q Bool
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
where
go :: Name -> Q Bool
go :: Name -> Q Bool
go Name
tcName = do
Info
info <- Name -> Q Info
reify Name
tcName
case Info
info of
#if MIN_VERSION_template_haskell(2,11,0)
FamilyI (OpenTypeFamilyD (TypeFamilyHead Name
_ [TyVarBndr ()]
bndrs FamilyResultSig
_ Maybe InjectivityAnn
_)) [Dec]
_
-> [TyVarBndr ()] -> Q Bool
forall a. [a] -> Q Bool
withinFirstArgs [TyVarBndr ()]
bndrs
FamilyI (ClosedTypeFamilyD (TypeFamilyHead Name
_ [TyVarBndr ()]
bndrs FamilyResultSig
_ Maybe InjectivityAnn
_) [TySynEqn]
_) [Dec]
_
-> [TyVarBndr ()] -> Q Bool
forall a. [a] -> Q Bool
withinFirstArgs [TyVarBndr ()]
bndrs
#else
FamilyI (FamilyD TypeFam _ bndrs _) _
-> withinFirstArgs bndrs
FamilyI (ClosedTypeFamilyD _ bndrs _ _) _
-> withinFirstArgs bndrs
#endif
Info
_ -> Bool -> Q Bool
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
where
withinFirstArgs :: [a] -> Q Bool
withinFirstArgs :: forall a. [a] -> Q Bool
withinFirstArgs [a]
bndrs =
let firstArgs :: [Type]
firstArgs = Int -> [Type] -> [Type]
forall a. Int -> [a] -> [a]
take ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
bndrs) [Type]
tyArgs
argFVs :: [Name]
argFVs = [Type] -> [Name]
forall a. TypeSubstitution a => a -> [Name]
freeVariables [Type]
firstArgs
in Bool -> Q Bool
forall a. a -> Q a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Q Bool) -> Bool -> Q Bool
forall a b. (a -> b) -> a -> b
$ (Name -> Bool) -> [Name] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Name -> [Name] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Name]
argFVs) [Name]
names
unSigT :: Type -> Type
unSigT :: Type -> Type
unSigT (SigT Type
t Type
_) = Type
t
unSigT Type
t = Type
t
allDistinct :: Ord a => [a] -> Bool
allDistinct :: forall a. Ord a => [a] -> Bool
allDistinct = Set a -> [a] -> Bool
forall a. Ord a => Set a -> [a] -> Bool
allDistinct' Set a
forall a. Set a
Set.empty
where
allDistinct' :: Ord a => Set a -> [a] -> Bool
allDistinct' :: forall a. Ord a => Set a -> [a] -> Bool
allDistinct' Set a
uniqs (a
x:[a]
xs)
| a
x a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
uniqs = Bool
False
| Bool
otherwise = Set a -> [a] -> Bool
forall a. Ord a => Set a -> [a] -> Bool
allDistinct' (a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
Set.insert a
x Set a
uniqs) [a]
xs
allDistinct' Set a
_ [a]
_ = Bool
True
mentionsName :: Type -> [Name] -> Bool
mentionsName :: Type -> [Name] -> Bool
mentionsName = Type -> [Name] -> Bool
go
where
go :: Type -> [Name] -> Bool
go :: Type -> [Name] -> Bool
go (AppT Type
t1 Type
t2) [Name]
names = Type -> [Name] -> Bool
go Type
t1 [Name]
names Bool -> Bool -> Bool
|| Type -> [Name] -> Bool
go Type
t2 [Name]
names
go (SigT Type
t Type
_k) [Name]
names = Type -> [Name] -> Bool
go Type
t [Name]
names
Bool -> Bool -> Bool
|| Type -> [Name] -> Bool
go Type
_k [Name]
names
go (VarT Name
n) [Name]
names = Name
n Name -> [Name] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Name]
names
go Type
_ [Name]
_ = Bool
False
predMentionsName :: Pred -> [Name] -> Bool
#if MIN_VERSION_template_haskell(2,10,0)
predMentionsName :: Type -> [Name] -> Bool
predMentionsName = Type -> [Name] -> Bool
mentionsName
#else
predMentionsName (ClassP n tys) names = n `elem` names || any (`mentionsName` names) tys
predMentionsName (EqualP t1 t2) names = mentionsName t1 names || mentionsName t2 names
#endif
unapplyTy :: Type -> NonEmpty Type
unapplyTy :: Type -> NonEmpty Type
unapplyTy = NonEmpty Type -> NonEmpty Type
forall a. NonEmpty a -> NonEmpty a
NE.reverse (NonEmpty Type -> NonEmpty Type)
-> (Type -> NonEmpty Type) -> Type -> NonEmpty Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> NonEmpty Type
go
where
go :: Type -> NonEmpty Type
go :: Type -> NonEmpty Type
go (AppT Type
t1 Type
t2) = Type
t2 Type -> NonEmpty Type -> NonEmpty Type
forall a. a -> NonEmpty a -> NonEmpty a
<| Type -> NonEmpty Type
go Type
t1
go (SigT Type
t Type
_) = Type -> NonEmpty Type
go Type
t
go (ForallT [TyVarBndr Specificity]
_ [Type]
_ Type
t) = Type -> NonEmpty Type
go Type
t
go Type
t = Type
t Type -> [Type] -> NonEmpty Type
forall a. a -> [a] -> NonEmpty a
:| []
uncurryTy :: Type -> (Cxt, NonEmpty Type)
uncurryTy :: Type -> ([Type], NonEmpty Type)
uncurryTy (AppT (AppT Type
ArrowT Type
t1) Type
t2) =
let ([Type]
ctxt, NonEmpty Type
tys) = Type -> ([Type], NonEmpty Type)
uncurryTy Type
t2
in ([Type]
ctxt, Type
t1 Type -> NonEmpty Type -> NonEmpty Type
forall a. a -> NonEmpty a -> NonEmpty a
<| NonEmpty Type
tys)
uncurryTy (SigT Type
t Type
_) = Type -> ([Type], NonEmpty Type)
uncurryTy Type
t
uncurryTy (ForallT [TyVarBndr Specificity]
_ [Type]
ctxt Type
t) =
let ([Type]
ctxt', NonEmpty Type
tys) = Type -> ([Type], NonEmpty Type)
uncurryTy Type
t
in ([Type]
ctxt [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type]
ctxt', NonEmpty Type
tys)
uncurryTy Type
t = ([], Type
t Type -> [Type] -> NonEmpty Type
forall a. a -> [a] -> NonEmpty a
:| [])
uncurryKind :: Kind -> NonEmpty Kind
uncurryKind :: Type -> NonEmpty Type
uncurryKind = ([Type], NonEmpty Type) -> NonEmpty Type
forall a b. (a, b) -> b
snd (([Type], NonEmpty Type) -> NonEmpty Type)
-> (Type -> ([Type], NonEmpty Type)) -> Type -> NonEmpty Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> ([Type], NonEmpty Type)
uncurryTy
createKindChain :: Int -> Kind
createKindChain :: Int -> Type
createKindChain = Type -> Int -> Type
go Type
starK
where
go :: Kind -> Int -> Kind
go :: Type -> Int -> Type
go Type
k Int
0 = Type
k
go Type
k !Int
n = Type -> Int -> Type
go (Type -> Type -> Type
AppT (Type -> Type -> Type
AppT Type
ArrowT Type
StarT) Type
k) (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
conNameExp :: Options -> ConstructorInfo -> Q Exp
conNameExp :: Options -> ConstructorInfo -> Q Exp
conNameExp Options
opts = Lit -> Q Exp
forall (m :: * -> *). Quote m => Lit -> m Exp
litE
(Lit -> Q Exp)
-> (ConstructorInfo -> Lit) -> ConstructorInfo -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Lit
stringL
(String -> Lit)
-> (ConstructorInfo -> String) -> ConstructorInfo -> Lit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Options -> String -> String
constructorTagModifier Options
opts
(String -> String)
-> (ConstructorInfo -> String) -> ConstructorInfo -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> String
nameBase
(Name -> String)
-> (ConstructorInfo -> Name) -> ConstructorInfo -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConstructorInfo -> Name
constructorName
fieldLabel :: Options
-> Name
-> String
fieldLabel :: Options -> Name -> String
fieldLabel Options
opts = Options -> String -> String
fieldLabelModifier Options
opts (String -> String) -> (Name -> String) -> Name -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> String
nameBase
valueConName :: Value -> String
valueConName :: Value -> String
valueConName (Object Object
_) = String
"Object"
valueConName (Array Array
_) = String
"Array"
valueConName (String Text
_) = String
"String"
valueConName (Number Scientific
_) = String
"Number"
valueConName (Bool Bool
_) = String
"Boolean"
valueConName Value
Null = String
"Null"
applyCon :: Name -> Name -> Pred
applyCon :: Name -> Name -> Type
applyCon Name
con Name
t =
#if MIN_VERSION_template_haskell(2,10,0)
Type -> Type -> Type
AppT (Name -> Type
ConT Name
con) (Name -> Type
VarT Name
t)
#else
ClassP con [VarT t]
#endif
canEtaReduce :: [Type] -> [Type] -> Bool
canEtaReduce :: [Type] -> [Type] -> Bool
canEtaReduce [Type]
remaining [Type]
dropped =
(Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Type -> Bool
isTyVar [Type]
dropped
Bool -> Bool -> Bool
&& [Name] -> Bool
forall a. Ord a => [a] -> Bool
allDistinct [Name]
droppedNames
Bool -> Bool -> Bool
&& Bool -> Bool
not ((Type -> Bool) -> [Type] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Type -> [Name] -> Bool
`mentionsName` [Name]
droppedNames) [Type]
remaining)
where
droppedNames :: [Name]
droppedNames :: [Name]
droppedNames = (Type -> Name) -> [Type] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Name
varTToName [Type]
dropped
applySubstitutionKind :: Map Name Kind -> Type -> Type
applySubstitutionKind :: Map Name Type -> Type -> Type
applySubstitutionKind = Map Name Type -> Type -> Type
forall a. TypeSubstitution a => Map Name Type -> a -> a
applySubstitution
substNameWithKind :: Name -> Kind -> Type -> Type
substNameWithKind :: Name -> Type -> Type -> Type
substNameWithKind Name
n Type
k = Map Name Type -> Type -> Type
applySubstitutionKind (Name -> Type -> Map Name Type
forall k a. k -> a -> Map k a
M.singleton Name
n Type
k)
substNamesWithKindStar :: [Name] -> Type -> Type
substNamesWithKindStar :: [Name] -> Type -> Type
substNamesWithKindStar [Name]
ns Type
t = (Name -> Type -> Type) -> Type -> [Name] -> Type
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr' (Name -> Type -> Type -> Type
`substNameWithKind` Type
starK) Type
t [Name]
ns
derivingKindError :: JSONClass -> Name -> Q a
derivingKindError :: forall a. JSONClass -> Name -> Q a
derivingKindError JSONClass
jc Name
tyConName = String -> Q a
forall a. String -> Q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail
(String -> Q a) -> (String -> String) -> String -> Q a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"Cannot derive well-kinded instance of form ‘"
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
className
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> String -> String
showChar Char
' '
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> (String -> String) -> String -> String
showParen Bool
True
( String -> String -> String
showString (Name -> String
nameBase Name
tyConName)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" ..."
)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"‘\n\tClass "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
className
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" expects an argument of kind "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (Type -> String
forall a. Ppr a => a -> String
pprint (Type -> String) -> (Int -> Type) -> Int -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Type
createKindChain (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ JSONClass -> Int
arityInt JSONClass
jc)
(String -> Q a) -> String -> Q a
forall a b. (a -> b) -> a -> b
$ String
""
where
className :: String
className :: String
className = Name -> String
nameBase (Name -> String) -> Name -> String
forall a b. (a -> b) -> a -> b
$ JSONClass -> Name
jsonClassName JSONClass
jc
etaReductionError :: Type -> Q a
etaReductionError :: forall a. Type -> Q a
etaReductionError Type
instanceType = String -> Q a
forall a. String -> Q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Q a) -> String -> Q a
forall a b. (a -> b) -> a -> b
$
String
"Cannot eta-reduce to an instance of form \n\tinstance (...) => "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ Type -> String
forall a. Ppr a => a -> String
pprint Type
instanceType
datatypeContextError :: Name -> Type -> Q a
datatypeContextError :: forall a. Name -> Type -> Q a
datatypeContextError Name
dataName Type
instanceType = String -> Q a
forall a. String -> Q a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail
(String -> Q a) -> (String -> String) -> String -> Q a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"Can't make a derived instance of ‘"
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (Type -> String
forall a. Ppr a => a -> String
pprint Type
instanceType)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"‘:\n\tData type ‘"
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (Name -> String
nameBase Name
dataName)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"‘ must not have a class context involving the last type argument(s)"
(String -> Q a) -> String -> Q a
forall a b. (a -> b) -> a -> b
$ String
""
outOfPlaceTyVarError :: JSONClass -> Name -> a
outOfPlaceTyVarError :: forall a. JSONClass -> Name -> a
outOfPlaceTyVarError JSONClass
jc Name
conName = String -> a
forall a. HasCallStack => String -> a
error
(String -> a) -> (String -> String) -> String -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"Constructor ‘"
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (Name -> String
nameBase Name
conName)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"‘ must only use its last "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Show a => a -> String -> String
shows Int
n
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" type variable(s) within the last "
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Show a => a -> String -> String
shows Int
n
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
" argument(s) of a data type"
(String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
""
where
n :: Int
n :: Int
n = JSONClass -> Int
arityInt JSONClass
jc
existentialContextError :: Name -> a
existentialContextError :: forall a. Name -> a
existentialContextError Name
conName = String -> a
forall a. HasCallStack => String -> a
error
(String -> a) -> (String -> String) -> String -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"Constructor ‘"
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString (Name -> String
nameBase Name
conName)
(String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> String
showString String
"‘ must be truly polymorphic in the last argument(s) of the data type"
(String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
""
data Arity = Arity0 | Arity1 | Arity2
deriving (Int -> Arity
Arity -> Int
Arity -> [Arity]
Arity -> Arity
Arity -> Arity -> [Arity]
Arity -> Arity -> Arity -> [Arity]
(Arity -> Arity)
-> (Arity -> Arity)
-> (Int -> Arity)
-> (Arity -> Int)
-> (Arity -> [Arity])
-> (Arity -> Arity -> [Arity])
-> (Arity -> Arity -> [Arity])
-> (Arity -> Arity -> Arity -> [Arity])
-> Enum Arity
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Arity -> Arity
succ :: Arity -> Arity
$cpred :: Arity -> Arity
pred :: Arity -> Arity
$ctoEnum :: Int -> Arity
toEnum :: Int -> Arity
$cfromEnum :: Arity -> Int
fromEnum :: Arity -> Int
$cenumFrom :: Arity -> [Arity]
enumFrom :: Arity -> [Arity]
$cenumFromThen :: Arity -> Arity -> [Arity]
enumFromThen :: Arity -> Arity -> [Arity]
$cenumFromTo :: Arity -> Arity -> [Arity]
enumFromTo :: Arity -> Arity -> [Arity]
$cenumFromThenTo :: Arity -> Arity -> Arity -> [Arity]
enumFromThenTo :: Arity -> Arity -> Arity -> [Arity]
Enum, Arity -> Arity -> Bool
(Arity -> Arity -> Bool) -> (Arity -> Arity -> Bool) -> Eq Arity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Arity -> Arity -> Bool
== :: Arity -> Arity -> Bool
$c/= :: Arity -> Arity -> Bool
/= :: Arity -> Arity -> Bool
Eq, Eq Arity
Eq Arity
-> (Arity -> Arity -> Ordering)
-> (Arity -> Arity -> Bool)
-> (Arity -> Arity -> Bool)
-> (Arity -> Arity -> Bool)
-> (Arity -> Arity -> Bool)
-> (Arity -> Arity -> Arity)
-> (Arity -> Arity -> Arity)
-> Ord Arity
Arity -> Arity -> Bool
Arity -> Arity -> Ordering
Arity -> Arity -> Arity
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Arity -> Arity -> Ordering
compare :: Arity -> Arity -> Ordering
$c< :: Arity -> Arity -> Bool
< :: Arity -> Arity -> Bool
$c<= :: Arity -> Arity -> Bool
<= :: Arity -> Arity -> Bool
$c> :: Arity -> Arity -> Bool
> :: Arity -> Arity -> Bool
$c>= :: Arity -> Arity -> Bool
>= :: Arity -> Arity -> Bool
$cmax :: Arity -> Arity -> Arity
max :: Arity -> Arity -> Arity
$cmin :: Arity -> Arity -> Arity
min :: Arity -> Arity -> Arity
Ord)
data Direction = To | From
data JSONFun = ToJSON | ToEncoding | ParseJSON
data ToJSONFun = Value | Encoding
targetToJSONFun :: ToJSONFun -> JSONFun
targetToJSONFun :: ToJSONFun -> JSONFun
targetToJSONFun ToJSONFun
Value = JSONFun
ToJSON
targetToJSONFun ToJSONFun
Encoding = JSONFun
ToEncoding
data JSONClass = JSONClass { JSONClass -> Direction
direction :: Direction, JSONClass -> Arity
arity :: Arity }
toJSONClass, toJSON1Class, toJSON2Class,
fromJSONClass, fromJSON1Class, fromJSON2Class :: JSONClass
toJSONClass :: JSONClass
toJSONClass = Direction -> Arity -> JSONClass
JSONClass Direction
To Arity
Arity0
toJSON1Class :: JSONClass
toJSON1Class = Direction -> Arity -> JSONClass
JSONClass Direction
To Arity
Arity1
toJSON2Class :: JSONClass
toJSON2Class = Direction -> Arity -> JSONClass
JSONClass Direction
To Arity
Arity2
fromJSONClass :: JSONClass
fromJSONClass = Direction -> Arity -> JSONClass
JSONClass Direction
From Arity
Arity0
fromJSON1Class :: JSONClass
fromJSON1Class = Direction -> Arity -> JSONClass
JSONClass Direction
From Arity
Arity1
fromJSON2Class :: JSONClass
fromJSON2Class = Direction -> Arity -> JSONClass
JSONClass Direction
From Arity
Arity2
jsonClassName :: JSONClass -> Name
jsonClassName :: JSONClass -> Name
jsonClassName (JSONClass Direction
To Arity
Arity0) = ''ToJSON
jsonClassName (JSONClass Direction
To Arity
Arity1) = ''ToJSON1
jsonClassName (JSONClass Direction
To Arity
Arity2) = ''ToJSON2
jsonClassName (JSONClass Direction
From Arity
Arity0) = ''FromJSON
jsonClassName (JSONClass Direction
From Arity
Arity1) = ''FromJSON1
jsonClassName (JSONClass Direction
From Arity
Arity2) = ''FromJSON2
jsonFunValName :: JSONFun -> Arity -> Name
jsonFunValName :: JSONFun -> Arity -> Name
jsonFunValName JSONFun
ToJSON Arity
Arity0 = 'toJSON
jsonFunValName JSONFun
ToJSON Arity
Arity1 = 'liftToJSON
jsonFunValName JSONFun
ToJSON Arity
Arity2 = 'liftToJSON2
jsonFunValName JSONFun
ToEncoding Arity
Arity0 = 'toEncoding
jsonFunValName JSONFun
ToEncoding Arity
Arity1 = 'liftToEncoding
jsonFunValName JSONFun
ToEncoding Arity
Arity2 = 'liftToEncoding2
jsonFunValName JSONFun
ParseJSON Arity
Arity0 = 'parseJSON
jsonFunValName JSONFun
ParseJSON Arity
Arity1 = 'liftParseJSON
jsonFunValName JSONFun
ParseJSON Arity
Arity2 = 'liftParseJSON2
jsonFunListName :: JSONFun -> Arity -> Name
jsonFunListName :: JSONFun -> Arity -> Name
jsonFunListName JSONFun
ToJSON Arity
Arity0 = 'toJSONList
jsonFunListName JSONFun
ToJSON Arity
Arity1 = 'liftToJSONList
jsonFunListName JSONFun
ToJSON Arity
Arity2 = 'liftToJSONList2
jsonFunListName JSONFun
ToEncoding Arity
Arity0 = 'toEncodingList
jsonFunListName JSONFun
ToEncoding Arity
Arity1 = 'liftToEncodingList
jsonFunListName JSONFun
ToEncoding Arity
Arity2 = 'liftToEncodingList2
jsonFunListName JSONFun
ParseJSON Arity
Arity0 = 'parseJSONList
jsonFunListName JSONFun
ParseJSON Arity
Arity1 = 'liftParseJSONList
jsonFunListName JSONFun
ParseJSON Arity
Arity2 = 'liftParseJSONList2
jsonFunValOrListName :: Bool
-> JSONFun -> Arity -> Name
jsonFunValOrListName :: Bool -> JSONFun -> Arity -> Name
jsonFunValOrListName Bool
False = JSONFun -> Arity -> Name
jsonFunValName
jsonFunValOrListName Bool
True = JSONFun -> Arity -> Name
jsonFunListName
arityInt :: JSONClass -> Int
arityInt :: JSONClass -> Int
arityInt = Arity -> Int
forall a. Enum a => a -> Int
fromEnum (Arity -> Int) -> (JSONClass -> Arity) -> JSONClass -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JSONClass -> Arity
arity
allowExQuant :: JSONClass -> Bool
allowExQuant :: JSONClass -> Bool
allowExQuant (JSONClass Direction
To Arity
_) = Bool
True
allowExQuant JSONClass
_ = Bool
False
data StarKindStatus = NotKindStar
| KindStar
| IsKindVar Name
deriving StarKindStatus -> StarKindStatus -> Bool
(StarKindStatus -> StarKindStatus -> Bool)
-> (StarKindStatus -> StarKindStatus -> Bool) -> Eq StarKindStatus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StarKindStatus -> StarKindStatus -> Bool
== :: StarKindStatus -> StarKindStatus -> Bool
$c/= :: StarKindStatus -> StarKindStatus -> Bool
/= :: StarKindStatus -> StarKindStatus -> Bool
Eq
canRealizeKindStar :: Type -> StarKindStatus
canRealizeKindStar :: Type -> StarKindStatus
canRealizeKindStar Type
t = case Type
t of
Type
_ | Type -> Bool
hasKindStar Type
t -> StarKindStatus
KindStar
SigT Type
_ (VarT Name
k) -> Name -> StarKindStatus
IsKindVar Name
k
Type
_ -> StarKindStatus
NotKindStar
starKindStatusToName :: StarKindStatus -> Maybe Name
starKindStatusToName :: StarKindStatus -> Maybe Name
starKindStatusToName (IsKindVar Name
n) = Name -> Maybe Name
forall a. a -> Maybe a
Just Name
n
starKindStatusToName StarKindStatus
_ = Maybe Name
forall a. Maybe a
Nothing
catKindVarNames :: [StarKindStatus] -> [Name]
catKindVarNames :: [StarKindStatus] -> [Name]
catKindVarNames = (StarKindStatus -> Maybe Name) -> [StarKindStatus] -> [Name]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe StarKindStatus -> Maybe Name
starKindStatusToName