    {-# LINE 1 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    {-# LANGUAGE PatternGuards, DeriveFunctor #-}

    module Data.GI.CodeGen.Conversions
        ( convert
        , genConversion
        , unpackCArray
        , computeArrayLength

        , callableHasClosures

        , hToF
        , fToH
        , transientToH
        , haskellType
        , isoHaskellType
        , foreignType

        , argumentType
        , ExposeClosures(..)
        , elementType
        , elementMap
        , elementTypeAndMap

        , isManaged
        , typeIsNullable
        , typeIsPtr
        , typeIsCallback
        , maybeNullConvert
        , nullPtrForType

        , typeAllocInfo
        , TypeAllocInfo(..)

        , apply
        , mapC
        , literal
        , Constructor(..)
        ) where

    {-# LINE 45 "lib/Data/GI/CodeGen/Conversions.hsc" #-}

    import Control.Monad (when)
    import Data.Maybe (isJust)
    import Data.Text (Text)
    import qualified Data.Text as T
    import GHC.Exts (IsString(..))

    import Foreign.C.Types (CInt, CUInt)
    import Foreign.Storable (sizeOf)

    import Data.GI.CodeGen.API
    import Data.GI.CodeGen.Code
    import Data.GI.CodeGen.GObject
    import Data.GI.CodeGen.SymbolNaming
    import Data.GI.CodeGen.Type
    import Data.GI.CodeGen.Util

    -- | The free monad.
    data Free f r = Free (f (Free f r)) | Pure r

    instance Functor f => Functor (Free f) where
      fmap :: forall a b. (a -> b) -> Free f a -> Free f b
    fmap a -> b
    f = Free f a -> Free f b
    forall {f :: * -> *}. Functor f => Free f a -> Free f b
    go where
        go :: Free f a -> Free f b
    go (Pure a
    a)  = b -> Free f b
    forall (f :: * -> *) r. r -> Free f r
    Pure (a -> b
    f a
    a)
        go (Free f (Free f a)
    fa) = f (Free f b) -> Free f b
    forall (f :: * -> *) r. f (Free f r) -> Free f r
    Free (Free f a -> Free f b
    go (Free f a -> Free f b) -> f (Free f a) -> f (Free f b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (Free f a)
    fa)

    instance (Functor f) => Applicative (Free f) where
        pure :: forall a. a -> Free f a
    pure = a -> Free f a
    forall (f :: * -> *) r. r -> Free f r
    Pure
        Pure a -> b
    a <*> :: forall a b. Free f (a -> b) -> Free f a -> Free f b
    <*> Pure a
    b = b -> Free f b
    forall (f :: * -> *) r. r -> Free f r
    Pure (b -> Free f b) -> b -> Free f b
    forall a b. (a -> b) -> a -> b
    $ a -> b
    a a
    b
        Pure a -> b
    a <*> Free f (Free f a)
    mb = f (Free f b) -> Free f b
    forall (f :: * -> *) r. f (Free f r) -> Free f r
    Free (f (Free f b) -> Free f b) -> f (Free f b) -> Free f b
    forall a b. (a -> b) -> a -> b
    $ (a -> b) -> Free f a -> Free f b
    forall a b. (a -> b) -> Free f a -> Free f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    a (Free f a -> Free f b) -> f (Free f a) -> f (Free f b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (Free f a)
    mb
        Free f (Free f (a -> b))
    ma <*> Free f a
    b = f (Free f b) -> Free f b
    forall (f :: * -> *) r. f (Free f r) -> Free f r
    Free (f (Free f b) -> Free f b) -> f (Free f b) -> Free f b
    forall a b. (a -> b) -> a -> b
    $ (Free f (a -> b) -> Free f a -> Free f b
    forall a b. Free f (a -> b) -> Free f a -> Free f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Free f a
    b) (Free f (a -> b) -> Free f b)
    -> f (Free f (a -> b)) -> f (Free f b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> f (Free f (a -> b))
    ma

    instance (Functor f) => Monad (Free f) where
        (Free f (Free f a)
    x) >>= :: forall a b. Free f a -> (a -> Free f b) -> Free f b
    >>= a -> Free f b
    f = f (Free f b) -> Free f b
    forall (f :: * -> *) r. f (Free f r) -> Free f r
    Free ((Free f a -> Free f b) -> f (Free f a) -> f (Free f b)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Free f a -> (a -> Free f b) -> Free f b
    forall a b. Free f a -> (a -> Free f b) -> Free f b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> Free f b
    f) f (Free f a)
    x)
        (Pure a
    r) >>= a -> Free f b
    f = a -> Free f b
    f a
    r

    -- | Lift some command to the Free monad.
    liftF :: (Functor f) => f r -> Free f r
    liftF :: forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF f r
    command = f (Free f r) -> Free f r
    forall (f :: * -> *) r. f (Free f r) -> Free f r
    Free ((r -> Free f r) -> f r -> f (Free f r)
    forall a b. (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap r -> Free f r
    forall (f :: * -> *) r. r -> Free f r
    Pure f r
    command)

    -- String identifying a constructor in the generated code, which is
    -- either (by default) a pure function (indicated by the P
    -- constructor) or a function returning values on a monad (M
    -- constructor). 'Id' denotes the identity function.
    data Constructor = P Text | M Text | Id
                       deriving (Constructor -> Constructor -> Bool
    (Constructor -> Constructor -> Bool)
    -> (Constructor -> Constructor -> Bool) -> Eq Constructor
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Constructor -> Constructor -> Bool
    == :: Constructor -> Constructor -> Bool
    $c/= :: Constructor -> Constructor -> Bool
    /= :: Constructor -> Constructor -> Bool
    Eq,Int -> Constructor -> ShowS
    [Constructor] -> ShowS
    Constructor -> [Char]
    (Int -> Constructor -> ShowS)
    -> (Constructor -> [Char])
    -> ([Constructor] -> ShowS)
    -> Show Constructor
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Constructor -> ShowS
    showsPrec :: Int -> Constructor -> ShowS
    $cshow :: Constructor -> [Char]
    show :: Constructor -> [Char]
    $cshowList :: [Constructor] -> ShowS
    showList :: [Constructor] -> ShowS
    Show)
    instance IsString Constructor where
        fromString :: [Char] -> Constructor
    fromString = Text -> Constructor
    P (Text -> Constructor) -> ([Char] -> Text) -> [Char] -> Constructor
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Text
    T.pack

    data FExpr next = Apply Constructor next
                    | LambdaConvert Text next
                    | MapC Map Constructor next
                    | Literal Constructor next
                      deriving (Int -> FExpr next -> ShowS
    [FExpr next] -> ShowS
    FExpr next -> [Char]
    (Int -> FExpr next -> ShowS)
    -> (FExpr next -> [Char])
    -> ([FExpr next] -> ShowS)
    -> Show (FExpr next)
    forall next. Show next => Int -> FExpr next -> ShowS
    forall next. Show next => [FExpr next] -> ShowS
    forall next. Show next => FExpr next -> [Char]
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall next. Show next => Int -> FExpr next -> ShowS
    showsPrec :: Int -> FExpr next -> ShowS
    $cshow :: forall next. Show next => FExpr next -> [Char]
    show :: FExpr next -> [Char]
    $cshowList :: forall next. Show next => [FExpr next] -> ShowS
    showList :: [FExpr next] -> ShowS
    Show, (forall a b. (a -> b) -> FExpr a -> FExpr b)
    -> (forall a b. a -> FExpr b -> FExpr a) -> Functor FExpr
    forall a b. a -> FExpr b -> FExpr a
    forall a b. (a -> b) -> FExpr a -> FExpr b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> FExpr a -> FExpr b
    fmap :: forall a b. (a -> b) -> FExpr a -> FExpr b
    $c<$ :: forall a b. a -> FExpr b -> FExpr a
    <$ :: forall a b. a -> FExpr b -> FExpr a
    Functor)

    type Converter = Free FExpr ()

    -- Different available maps.
    data Map = Map | MapFirst | MapSecond
             deriving (Int -> Map -> ShowS
    [Map] -> ShowS
    Map -> [Char]
    (Int -> Map -> ShowS)
    -> (Map -> [Char]) -> ([Map] -> ShowS) -> Show Map
    forall a.
    (Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Map -> ShowS
    showsPrec :: Int -> Map -> ShowS
    $cshow :: Map -> [Char]
    show :: Map -> [Char]
    $cshowList :: [Map] -> ShowS
    showList :: [Map] -> ShowS
    Show)

    -- Naming for the maps.
    mapName :: Map -> Text
    mapName :: Map -> Text
    mapName Map
    Map = Text
    "map"
    mapName Map
    MapFirst = Text
    "mapFirst"
    mapName Map
    MapSecond = Text
    "mapSecond"

    -- Naming for the monadic versions of the maps that we use
    monadicMapName :: Map -> Text
    monadicMapName :: Map -> Text
    monadicMapName Map
    Map = Text
    "mapM"
    monadicMapName Map
    MapFirst = Text
    "mapFirstA"
    monadicMapName Map
    MapSecond = Text
    "mapSecondA"

    apply :: Constructor -> Converter
    apply :: Constructor -> Converter
    apply Constructor
    f = FExpr () -> Converter
    forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF (FExpr () -> Converter) -> FExpr () -> Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> () -> FExpr ()
    forall next. Constructor -> next -> FExpr next
    Apply Constructor
    f ()

    mapC :: Constructor -> Converter
    mapC :: Constructor -> Converter
    mapC Constructor
    f = FExpr () -> Converter
    forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF (FExpr () -> Converter) -> FExpr () -> Converter
    forall a b. (a -> b) -> a -> b
    $ Map -> Constructor -> () -> FExpr ()
    forall next. Map -> Constructor -> next -> FExpr next
    MapC Map
    Map Constructor
    f ()

    mapFirst :: Constructor -> Converter
    mapFirst :: Constructor -> Converter
    mapFirst Constructor
    f = FExpr () -> Converter
    forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF (FExpr () -> Converter) -> FExpr () -> Converter
    forall a b. (a -> b) -> a -> b
    $ Map -> Constructor -> () -> FExpr ()
    forall next. Map -> Constructor -> next -> FExpr next
    MapC Map
    MapFirst Constructor
    f ()

    mapSecond :: Constructor -> Converter
    mapSecond :: Constructor -> Converter
    mapSecond Constructor
    f = FExpr () -> Converter
    forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF (FExpr () -> Converter) -> FExpr () -> Converter
    forall a b. (a -> b) -> a -> b
    $ Map -> Constructor -> () -> FExpr ()
    forall next. Map -> Constructor -> next -> FExpr next
    MapC Map
    MapSecond Constructor
    f ()

    literal :: Constructor -> Converter
    literal :: Constructor -> Converter
    literal Constructor
    f = FExpr () -> Converter
    forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF (FExpr () -> Converter) -> FExpr () -> Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> () -> FExpr ()
    forall next. Constructor -> next -> FExpr next
    Literal Constructor
    f ()

    lambdaConvert :: Text -> Converter
    lambdaConvert :: Text -> Converter
    lambdaConvert Text
    c = FExpr () -> Converter
    forall (f :: * -> *) r. Functor f => f r -> Free f r
    liftF (FExpr () -> Converter) -> FExpr () -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> () -> FExpr ()
    forall next. Text -> next -> FExpr next
    LambdaConvert Text
    c ()

    genConversion :: Text -> Converter -> CodeGen e Text
    genConversion :: forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l (Pure ()) = Text
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    l
    genConversion Text
    l (Free FExpr Converter
    k) = do
      let l' :: Text
    l' = Text -> Text
    prime Text
    l
      case FExpr Converter
    k of
        Apply (P Text
    f) Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    "let " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " = " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    f Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l' Converter
    next
        Apply (M Text
    f) Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    l' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " <- " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    f Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l' Converter
    next
        Apply Constructor
    Id Converter
    next -> Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l Converter
    next

        MapC Map
    m (P Text
    f) Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    "let " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " = " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Map -> Text
    mapName Map
    m Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    f Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l' Converter
    next
        MapC Map
    m (M Text
    f) Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    l' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " <- " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Map -> Text
    monadicMapName Map
    m Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    f Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l' Converter
    next
        MapC Map
    _ Constructor
    Id Converter
    next -> Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l Converter
    next

        LambdaConvert Text
    conv Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    conv Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " $ \\" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l' Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " -> do"
               CodeGen e ()
    forall e. CodeGen e ()
    increaseIndent
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l' Converter
    next

        Literal (P Text
    f) Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    "let " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    l Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " = " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    f
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l Converter
    next
        Literal (M Text
    f) Converter
    next ->
            do Text -> CodeGen e ()
    forall e. Text -> CodeGen e ()
    line (Text -> CodeGen e ()) -> Text -> CodeGen e ()
    forall a b. (a -> b) -> a -> b
    $ Text
    l Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " <- " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    f
               Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l Converter
    next
        Literal Constructor
    Id Converter
    next -> Text
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Text -> Converter -> CodeGen e Text
    genConversion Text
    l Converter
    next

    -- | Given an array, together with its type, return the code for reading
    -- its length.
    computeArrayLength :: Text -> Type -> ExcCodeGen Text
    computeArrayLength :: Text -> Type -> ExcCodeGen Text
    computeArrayLength Text
    array (TCArray Bool
    _ Int
    _ Int
    _ Type
    t) = do
      reader <- ExcCodeGen Text
    findReader
      return $ "fromIntegral $ " <> reader <> " " <> array
        where findReader :: ExcCodeGen Text
    findReader = case Type
    t of
                         TBasicType BasicType
    TUInt8 -> Text -> ExcCodeGen Text
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    "B.length"
                         Type
    _ -> Text -> ExcCodeGen Text
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Text
    "P.length"
    computeArrayLength Text
    _ Type
    t =
        Text -> ExcCodeGen Text
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen Text) -> Text -> ExcCodeGen Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "computeArrayLength called on non-CArray type "
                                Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t

    convert :: Text -> CodeGen e Converter -> CodeGen e Text
    convert :: forall e. Text -> CodeGen e Converter -> CodeGen e Text
    convert Text
    l CodeGen e Converter
    c = do
      c' <- CodeGen e Converter
    c
      genConversion l c'

    hObjectToF :: Type -> Transfer -> ExcCodeGen Constructor
    hObjectToF :: Type -> Transfer -> ExcCodeGen Constructor
    hObjectToF Type
    t Transfer
    transfer =
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then do
        isGO <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    isGObject Type
    t
        if isGO
        then return $ M "B.ManagedPtr.disownObject"
        else return $ M "B.ManagedPtr.disownManagedPtr"
      -- castPtr since we accept any instance of the class associated with
      -- the GObject, not just the precise type of the GObject, while the
      -- foreign function declaration requires a pointer of the precise
      -- type.
      else Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrCastPtr"

    hVariantToF :: Transfer -> CodeGen e Constructor
    hVariantToF :: forall e. Transfer -> CodeGen e Constructor
    hVariantToF Transfer
    transfer =
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "B.GVariant.disownGVariant"
      else Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    hValueToF :: Transfer -> CodeGen e Constructor
    hValueToF :: forall e. Transfer -> CodeGen e Constructor
    hValueToF Transfer
    transfer =
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "B.GValue.disownGValue"
      else Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    hParamSpecToF :: Transfer -> CodeGen e Constructor
    hParamSpecToF :: forall e. Transfer -> CodeGen e Constructor
    hParamSpecToF Transfer
    transfer =
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "B.GParamSpec.disownGParamSpec"
      else Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    hClosureToF :: Transfer -> Maybe Type -> CodeGen e Constructor
    -- Untyped closures
    hClosureToF :: forall e. Transfer -> Maybe Type -> CodeGen e Constructor
    hClosureToF Transfer
    transfer Maybe Type
    Nothing =
      -- We cast the pointer here because the foreign type for untyped
      -- closures is always represented as Ptr (GClosure ()), while the
      -- corresponding Haskell type is the parametric "GClosure a".
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "FP.castPtr <$> B.GClosure.disownGClosure"
      else Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrCastPtr"
    -- Typed closures
    hClosureToF Transfer
    transfer (Just Type
    _) =
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "B.GClosure.disownGClosure"
      else Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    hBoxedToF :: Transfer -> CodeGen e Constructor
    hBoxedToF :: forall e. Transfer -> CodeGen e Constructor
    hBoxedToF Transfer
    transfer =
      if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferEverything
      then Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "B.ManagedPtr.disownBoxed"
      else Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    hStructToF :: Struct -> Transfer -> ExcCodeGen Constructor
    hStructToF :: Struct -> Transfer -> ExcCodeGen Constructor
    hStructToF Struct
    s Transfer
    transfer =
        if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Transfer
    TransferEverything Bool -> Bool -> Bool
    || Struct -> Bool
    structIsBoxed Struct
    s then
            Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    hBoxedToF Transfer
    transfer
        else do
            Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Struct -> Int
    structSize Struct
    s Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0) (ReaderT
       CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ())
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    forall a b. (a -> b) -> a -> b
    $
                 Text
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    forall a. Text -> ExcCodeGen a
    badIntroError Text
    "Transferring a non-boxed struct with unknown size!"
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    hUnionToF :: Union -> Transfer -> ExcCodeGen Constructor
    hUnionToF :: Union -> Transfer -> ExcCodeGen Constructor
    hUnionToF Union
    u Transfer
    transfer =
        if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Transfer
    TransferEverything Bool -> Bool -> Bool
    || Union -> Bool
    unionIsBoxed Union
    u then
            Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    hBoxedToF Transfer
    transfer
        else do
            Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (Union -> Int
    unionSize Union
    u Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0) (ReaderT
       CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ())
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    forall a b. (a -> b) -> a -> b
    $
                 Text
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) ()
    forall a. Text -> ExcCodeGen a
    badIntroError Text
    "Transferring a non-boxed union with unknown size!"
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unsafeManagedPtrGetPtr"

    -- Given the Haskell and Foreign types, returns the name of the
    -- function marshalling between both.
    hToF' :: Type -> Maybe API -> TypeRep -> TypeRep -> Transfer
                -> ExcCodeGen Constructor
    hToF' :: Type
    -> Maybe API
    -> TypeRep
    -> TypeRep
    -> Transfer
    -> ExcCodeGen Constructor
    hToF' Type
    t Maybe API
    a TypeRep
    hType TypeRep
    fType Transfer
    transfer
        | ( TypeRep
    hType TypeRep -> TypeRep -> Bool
    forall a. Eq a => a -> a -> Bool
    == TypeRep
    fType ) = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    Id
        | Type
    TError <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    hBoxedToF Transfer
    transfer
        | Type
    TVariant <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    hVariantToF Transfer
    transfer
        | Type
    TGValue <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    hValueToF Transfer
    transfer
        | Type
    TParamSpec <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    hParamSpecToF Transfer
    transfer
        | TGClosure Maybe Type
    c <- Type
    t = Transfer -> Maybe Type -> ExcCodeGen Constructor
    forall e. Transfer -> Maybe Type -> CodeGen e Constructor
    hClosureToF Transfer
    transfer Maybe Type
    c
        | Just (APIEnum Enumeration
    _) <- Maybe API
    a = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "(fromIntegral . fromEnum)"
        | Just (APIFlags Flags
    _) <- Maybe API
    a = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "gflagsToWord"
        | Just (APIObject Object
    _) <- Maybe API
    a = Type -> Transfer -> ExcCodeGen Constructor
    hObjectToF Type
    t Transfer
    transfer
        | Just (APIInterface Interface
    _) <- Maybe API
    a = Type -> Transfer -> ExcCodeGen Constructor
    hObjectToF Type
    t Transfer
    transfer
        | Just (APIStruct Struct
    s) <- Maybe API
    a = Struct -> Transfer -> ExcCodeGen Constructor
    hStructToF Struct
    s Transfer
    transfer
        | Just (APIUnion Union
    u) <- Maybe API
    a = Union -> Transfer -> ExcCodeGen Constructor
    hUnionToF Union
    u Transfer
    transfer
        -- Converting callback types requires more context, we leave that
        -- as a special case to be implemented by the caller.
        | Just (APICallback Callback
    _) <- Maybe API
    a = [Char] -> ExcCodeGen Constructor
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Cannot handle callback type here!! "
        | Type
    TByteArray <- Type
    t = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packGByteArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TUTF8) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packZeroTerminatedUTF8CArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TFileName) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packZeroTerminatedFileNameArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TPtr) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packZeroTerminatedPtrArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TUInt8) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packZeroTerminatedByteString"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TBoolean) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapZeroTerminatedStorableArray (fromIntegral . fromEnum))"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TGType) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapZeroTerminatedStorableArray gtypeToCGtype)"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    _) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packZeroTerminatedStorableArray"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TUTF8) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packUTF8CArray"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TFileName) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packFileNameArray"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TPtr) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packPtrArray"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TUInt8) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packByteString"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TBoolean) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapStorableArray (P.fromIntegral . P.fromEnum))"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TGType) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapStorableArray gtypeToCGType)"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TFloat) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapStorableArray realToFrac)"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TDouble) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapStorableArray realToFrac)"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    TUniChar) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(packMapStorableArray (P.fromIntegral . SP.ord))"
        | TCArray Bool
    False Int
    _ Int
    _ (TBasicType BasicType
    _) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "packStorableArray"
        | TCArray Bool
    False Int
    _ Int
    _ Type
    TGValue <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "B.GValue.packGValueArray"
        | TCArray{}  <- Type
    t = Text -> ExcCodeGen Constructor
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen Constructor) -> Text -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $
                       Text
    "Don't know how to pack C array of type " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t
        | Bool
    otherwise = case (TypeRep -> Text
    typeShow TypeRep
    hType, TypeRep -> Text
    typeShow TypeRep
    fType) of
                   (Text
    "T.Text", Text
    "CString") -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "textToCString"
                   (Text
    "[Char]", Text
    "CString") -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "stringToCString"
                   (Text
    "Char", Text
    "CInt")      -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "(P.fromIntegral . SP.ord)"
                   (Text
    "Bool", Text
    "CInt")      -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "(P.fromIntegral . P.fromEnum)"
                   (Text
    "Float", Text
    "CFloat")   -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "realToFrac"
                   (Text
    "Double", Text
    "CDouble") -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "realToFrac"
                   (Text
    "GType", Text
    "CGType")   -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "gtypeToCGType"
                   (Text, Text)
    _                     -> Text -> ExcCodeGen Constructor
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen Constructor) -> Text -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $
                                            Text
    "Don't know how to convert "
                                            Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> TypeRep -> Text
    typeShow TypeRep
    hType Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " into "
                                            Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> TypeRep -> Text
    typeShow TypeRep
    fType Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ".\n"
                                            Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "Internal type: "
                                            Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t

    getForeignConstructor :: Type -> Transfer -> ExcCodeGen Constructor
    getForeignConstructor :: Type -> Transfer -> ExcCodeGen Constructor
    getForeignConstructor Type
    t Transfer
    transfer = do
      a <- Type -> CodeGen CGError (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      hType <- haskellType t
      fType <- foreignType t
      hToF' t a hType fType transfer

    hToF_PackedType :: Type -> Text -> Transfer -> ExcCodeGen Converter
    hToF_PackedType :: Type -> Text -> Transfer -> ExcCodeGen Converter
    hToF_PackedType Type
    t Text
    packer Transfer
    transfer = do
      innerConstructor <- Type -> Transfer -> ExcCodeGen Constructor
    getForeignConstructor Type
    t Transfer
    transfer
      return $ do
        mapC innerConstructor
        apply (M packer)

    -- | Try to find the `hash` and `equal` functions appropriate for the
    -- given type, when used as a key in a GHashTable.
    hashTableKeyMappings :: Type -> ExcCodeGen (Text, Text)
    hashTableKeyMappings :: Type -> ExcCodeGen (Text, Text)
    hashTableKeyMappings (TBasicType BasicType
    TPtr) = (Text, Text) -> ExcCodeGen (Text, Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    "gDirectHash", Text
    "gDirectEqual")
    hashTableKeyMappings (TBasicType BasicType
    TUTF8) = (Text, Text) -> ExcCodeGen (Text, Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    "gStrHash", Text
    "gStrEqual")
    hashTableKeyMappings Type
    t =
        Text -> ExcCodeGen (Text, Text)
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen (Text, Text))
    -> Text -> ExcCodeGen (Text, Text)
    forall a b. (a -> b) -> a -> b
    $ Text
    "GHashTable key of type " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " unsupported."

    -- | `GHashTable` tries to fit every type into a pointer, the
    -- following function tries to find the appropriate
    -- (destroy,packer,unpacker) for the given type.
    hashTablePtrPackers :: Type -> ExcCodeGen (Text, Text, Text)
    hashTablePtrPackers :: Type -> ExcCodeGen (Text, Text, Text)
    hashTablePtrPackers (TBasicType BasicType
    TPtr) =
      (Text, Text, Text) -> ExcCodeGen (Text, Text, Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    "Nothing", Text
    "B.GHT.ptrPackPtr", Text
    "B.GHT.ptrUnpackPtr")
    hashTablePtrPackers (TBasicType BasicType
    TUTF8) =
      (Text, Text, Text) -> ExcCodeGen (Text, Text, Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    "(Just ptr_to_g_free)", Text
    "B.GHT.cstringPackPtr", Text
    "B.GHT.cstringUnpackPtr")
    hashTablePtrPackers Type
    TGValue =
      (Text, Text, Text) -> ExcCodeGen (Text, Text, Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    "(Just B.GValue.ptr_to_gvalue_free)", Text
    "B.GHT.gvaluePackPtr",
               Text
    "B.GHT.gvalueUnpackPtr")
    hashTablePtrPackers Type
    t =
      Text -> ExcCodeGen (Text, Text, Text)
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen (Text, Text, Text))
    -> Text -> ExcCodeGen (Text, Text, Text)
    forall a b. (a -> b) -> a -> b
    $ Text
    "GHashTable element of type " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " unsupported."

    hToF_PackGHashTable :: Type -> Type -> ExcCodeGen Converter
    hToF_PackGHashTable :: Type -> Type -> ExcCodeGen Converter
    hToF_PackGHashTable Type
    keys Type
    elems = do
      -- We will be adding elements to the Hash list with appropriate
      -- destructors, so we always want a fresh copy.
      keysConstructor <- Type -> Transfer -> ExcCodeGen Constructor
    getForeignConstructor Type
    keys Transfer
    TransferEverything
      elemsConstructor <- getForeignConstructor elems TransferEverything
      (keyHash, keyEqual) <- hashTableKeyMappings keys
      (keyDestroy, keyPack, _) <- hashTablePtrPackers keys
      (elemDestroy, elemPack, _) <- hashTablePtrPackers elems
      return $ do
        apply (P "Map.toList")
        mapFirst keysConstructor
        mapSecond elemsConstructor
        mapFirst (P keyPack)
        mapSecond (P elemPack)
        apply (M (T.intercalate " " ["packGHashTable", keyHash, keyEqual,
                                     keyDestroy, elemDestroy]))

    hToF :: Type -> Transfer -> ExcCodeGen Converter
    hToF :: Type -> Transfer -> ExcCodeGen Converter
    hToF (TGList Type
    t) Transfer
    transfer = do
      isPtr <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    typeIsPtr Type
    t
      when (not isPtr) $
           badIntroError ("'" <> tshow t <>
                          "' is not a pointer type, cannot pack into a GList.")
      hToF_PackedType t "packGList" transfer
    hToF (TGSList Type
    t) Transfer
    transfer = do
      isPtr <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    typeIsPtr Type
    t
      when (not isPtr) $
           badIntroError ("'" <> tshow t <>
                          "' is not a pointer type, cannot pack into a GSList.")
      hToF_PackedType t "packGSList" transfer
    hToF (TGArray Type
    t) Transfer
    transfer = Type -> Text -> Transfer -> ExcCodeGen Converter
    hToF_PackedType Type
    t Text
    "packGArray" Transfer
    transfer
    hToF (TPtrArray Type
    t) Transfer
    transfer = Type -> Text -> Transfer -> ExcCodeGen Converter
    hToF_PackedType Type
    t Text
    "packGPtrArray" Transfer
    transfer
    hToF (TGHash Type
    ta Type
    tb) Transfer
    _ = Type -> Type -> ExcCodeGen Converter
    hToF_PackGHashTable Type
    ta Type
    tb
    hToF (TCArray Bool
    zt Int
    _ Int
    _ t :: Type
    t@(TCArray{})) Transfer
    transfer = do
      let packer :: Text
    packer = if Bool
    zt
                   then Text
    "packZeroTerminated"
                   else Text
    "pack"
      Type -> Text -> Transfer -> ExcCodeGen Converter
    hToF_PackedType Type
    t (Text
    packer Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "PtrArray") Transfer
    transfer
    hToF (TCArray Bool
    zt Int
    _ Int
    _ t :: Type
    t@(TInterface Name
    _)) Transfer
    transfer = do
      isScalar <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    typeIsEnumOrFlag Type
    t
      let packer = if Bool
    zt
                   then Text
    "packZeroTerminated"
                   else Text
    "pack"
      if isScalar
      then hToF_PackedType t (packer <> "StorableArray") transfer
      else do
        api <- findAPI t
        let size = case Maybe API
    api of
                     Just (APIStruct Struct
    s) -> Struct -> Int
    structSize Struct
    s
                     Just (APIUnion Union
    u) -> Union -> Int
    unionSize Union
    u
                     Maybe API
    _ -> Int
    0
        if size == 0 || zt
        then hToF_PackedType t (packer <> "PtrArray") transfer
        else hToF_PackedType t (packer <> "BlockArray " <> tshow size) transfer

    hToF Type
    t Transfer
    transfer = do
      a <- Type -> CodeGen CGError (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      hType <- haskellType t
      fType <- foreignType t
      constructor <- hToF' t a hType fType transfer
      return $ apply constructor

    boxedForeignPtr :: Text -> Transfer -> CodeGen e Constructor
    boxedForeignPtr :: forall e. Text -> Transfer -> CodeGen e Constructor
    boxedForeignPtr Text
    constructor Transfer
    transfer = Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $
       case Transfer
    transfer of
         Transfer
    TransferEverything -> Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "wrapBoxed " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor
         Transfer
    _ -> Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "newBoxed " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor

    suForeignPtr :: Bool -> TypeRep -> Transfer -> CodeGen e Constructor
    suForeignPtr :: forall e. Bool -> TypeRep -> Transfer -> CodeGen e Constructor
    suForeignPtr Bool
    isBoxed TypeRep
    hType Transfer
    transfer = do
      let constructor :: Text
    constructor = TypeRep -> Text
    typeConName TypeRep
    hType
      if Bool
    isBoxed then
          Text -> Transfer -> CodeGen e Constructor
    forall e. Text -> Transfer -> CodeGen e Constructor
    boxedForeignPtr Text
    constructor Transfer
    transfer
      else Constructor -> CodeGen e Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> CodeGen e Constructor)
    -> Constructor -> CodeGen e Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
           case Transfer
    transfer of
             Transfer
    TransferEverything -> Text
    "wrapPtr " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor
             Transfer
    _ -> Text
    "newPtr " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor

    structForeignPtr :: Struct -> TypeRep -> Transfer -> CodeGen e Constructor
    structForeignPtr :: forall e. Struct -> TypeRep -> Transfer -> CodeGen e Constructor
    structForeignPtr Struct
    s =
        Bool -> TypeRep -> Transfer -> CodeGen e Constructor
    forall e. Bool -> TypeRep -> Transfer -> CodeGen e Constructor
    suForeignPtr (Struct -> Bool
    structIsBoxed Struct
    s)

    unionForeignPtr :: Union -> TypeRep -> Transfer -> CodeGen e Constructor
    unionForeignPtr :: forall e. Union -> TypeRep -> Transfer -> CodeGen e Constructor
    unionForeignPtr Union
    u =
        Bool -> TypeRep -> Transfer -> CodeGen e Constructor
    forall e. Bool -> TypeRep -> Transfer -> CodeGen e Constructor
    suForeignPtr (Union -> Bool
    unionIsBoxed Union
    u)

    fObjectToH :: Type -> TypeRep -> Transfer -> ExcCodeGen Constructor
    fObjectToH :: Type -> TypeRep -> Transfer -> ExcCodeGen Constructor
    fObjectToH Type
    t TypeRep
    hType Transfer
    transfer = do
      let constructor :: Text
    constructor = TypeRep -> Text
    typeConName TypeRep
    hType
      isGO <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    isGObject Type
    t
      return $ M $ parenthesize $
        case transfer of
        Transfer
    TransferEverything ->
            if Bool
    isGO
            then Text
    "wrapObject " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor
            else Text
    "wrapPtr " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor
        Transfer
    _ ->
            if Bool
    isGO
            then Text
    "newObject " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor
            else Text
    "newPtr " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    constructor

    fCallbackToH :: TypeRep -> Transfer -> ExcCodeGen Constructor
    fCallbackToH :: TypeRep -> Transfer -> ExcCodeGen Constructor
    fCallbackToH TypeRep
    hType Transfer
    TransferNothing = do
      let constructor :: Text
    constructor = TypeRep -> Text
    typeConName TypeRep
    hType
      Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> Constructor
    P (Text -> Text
    callbackDynamicWrapper Text
    constructor))
    fCallbackToH TypeRep
    _ Transfer
    transfer =
      Text -> ExcCodeGen Constructor
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text
    "ForeignCallback with unsupported transfer type `"
                           Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Transfer -> Text
    forall a. Show a => a -> Text
    tshow Transfer
    transfer Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "'")

    fVariantToH :: Transfer -> CodeGen e Constructor
    fVariantToH :: forall e. Transfer -> CodeGen e Constructor
    fVariantToH Transfer
    transfer =
      Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ case Transfer
    transfer of
                      Transfer
    TransferEverything -> Text
    "B.GVariant.wrapGVariantPtr"
                      Transfer
    _ -> Text
    "B.GVariant.newGVariantFromPtr"

    fValueToH :: Transfer -> CodeGen e Constructor
    fValueToH :: forall e. Transfer -> CodeGen e Constructor
    fValueToH Transfer
    transfer =
      Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ case Transfer
    transfer of
                      Transfer
    TransferEverything -> Text
    "B.GValue.wrapGValuePtr"
                      Transfer
    _ -> Text
    "B.GValue.newGValueFromPtr"

    fParamSpecToH :: Transfer -> CodeGen e Constructor
    fParamSpecToH :: forall e. Transfer -> CodeGen e Constructor
    fParamSpecToH Transfer
    transfer =
      Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ case Transfer
    transfer of
                      Transfer
    TransferEverything -> Text
    "B.GParamSpec.wrapGParamSpecPtr"
                      Transfer
    _ -> Text
    "B.GParamSpec.newGParamSpecFromPtr"

    fClosureToH :: Transfer -> Maybe Type -> CodeGen e Constructor
    -- Untyped closures
    fClosureToH :: forall e. Transfer -> Maybe Type -> CodeGen e Constructor
    fClosureToH Transfer
    transfer Maybe Type
    Nothing =
      Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ case Transfer
    transfer of
                      Transfer
    TransferEverything ->
                        Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "B.GClosure.wrapGClosurePtr . FP.castPtr"
                      Transfer
    _ -> Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "B.GClosure.newGClosureFromPtr . FP.castPtr"
    -- Typed closures
    fClosureToH Transfer
    transfer (Just Type
    _) =
      Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          Constructor)
    -> Constructor
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ case Transfer
    transfer of
                      Transfer
    TransferEverything -> Text
    "B.GClosure.wrapGClosurePtr"
                      Transfer
    _ -> Text
    "B.GClosure.newGClosureFromPtr"

    fToH' :: Type -> Maybe API -> TypeRep -> TypeRep -> Transfer
             -> ExcCodeGen Constructor
    fToH' :: Type
    -> Maybe API
    -> TypeRep
    -> TypeRep
    -> Transfer
    -> ExcCodeGen Constructor
    fToH' Type
    t Maybe API
    a TypeRep
    hType TypeRep
    fType Transfer
    transfer
        | ( TypeRep
    hType TypeRep -> TypeRep -> Bool
    forall a. Eq a => a -> a -> Bool
    == TypeRep
    fType ) = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    Id
        | Just (APIEnum Enumeration
    _) <- Maybe API
    a = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "(toEnum . fromIntegral)"
        | Just (APIFlags Flags
    _) <- Maybe API
    a = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "wordToGFlags"
        | Type
    TError <- Type
    t = Text -> Transfer -> ExcCodeGen Constructor
    forall e. Text -> Transfer -> CodeGen e Constructor
    boxedForeignPtr Text
    "GError" Transfer
    transfer
        | Type
    TVariant <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    fVariantToH Transfer
    transfer
        | Type
    TGValue <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    fValueToH Transfer
    transfer
        | Type
    TParamSpec <- Type
    t = Transfer -> ExcCodeGen Constructor
    forall e. Transfer -> CodeGen e Constructor
    fParamSpecToH Transfer
    transfer
        | TGClosure Maybe Type
    c <- Type
    t = Transfer -> Maybe Type -> ExcCodeGen Constructor
    forall e. Transfer -> Maybe Type -> CodeGen e Constructor
    fClosureToH Transfer
    transfer Maybe Type
    c
        | Just (APIStruct Struct
    s) <- Maybe API
    a = Struct -> TypeRep -> Transfer -> ExcCodeGen Constructor
    forall e. Struct -> TypeRep -> Transfer -> CodeGen e Constructor
    structForeignPtr Struct
    s TypeRep
    hType Transfer
    transfer
        | Just (APIUnion Union
    u) <- Maybe API
    a = Union -> TypeRep -> Transfer -> ExcCodeGen Constructor
    forall e. Union -> TypeRep -> Transfer -> CodeGen e Constructor
    unionForeignPtr Union
    u TypeRep
    hType Transfer
    transfer
        | Just (APIObject Object
    _) <- Maybe API
    a = Type -> TypeRep -> Transfer -> ExcCodeGen Constructor
    fObjectToH Type
    t TypeRep
    hType Transfer
    transfer
        | Just (APIInterface Interface
    _) <- Maybe API
    a = Type -> TypeRep -> Transfer -> ExcCodeGen Constructor
    fObjectToH Type
    t TypeRep
    hType Transfer
    transfer
        | Just (APICallback Callback
    _) <- Maybe API
    a = TypeRep -> Transfer -> ExcCodeGen Constructor
    fCallbackToH TypeRep
    hType Transfer
    transfer
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TUTF8) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unpackZeroTerminatedUTF8CArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TFileName) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unpackZeroTerminatedFileNameArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TUInt8) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unpackZeroTerminatedByteString"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TPtr) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unpackZeroTerminatedPtrArray"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TBoolean) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(unpackMapZeroTerminatedStorableArray (/= 0))"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TGType) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(unpackMapZeroTerminatedStorableArray GType)"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TFloat) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(unpackMapZeroTerminatedStorableArray realToFrac)"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    TDouble) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "(unpackMapZeroTerminatedStorableArray realToFrac)"
        | TCArray Bool
    True Int
    _ Int
    _ (TBasicType BasicType
    _) <- Type
    t =
            Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unpackZeroTerminatedStorableArray"
        | TCArray{}  <- Type
    t = Text -> ExcCodeGen Constructor
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen Constructor) -> Text -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $
                       Text
    "Don't know how to unpack C array of type " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t
        | Type
    TByteArray <- Type
    t = Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "unpackGByteArray"
        | TGHash Type
    _ Type
    _ <- Type
    t = Text -> ExcCodeGen Constructor
    forall a. Text -> ExcCodeGen a
    notImplementedError Text
    "Foreign Hashes not supported yet"
        | Bool
    otherwise = case (TypeRep -> Text
    typeShow TypeRep
    fType, TypeRep -> Text
    typeShow TypeRep
    hType) of
                   (Text
    "CString", Text
    "T.Text") -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "cstringToText"
                   (Text
    "CString", Text
    "[Char]") -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Constructor -> ExcCodeGen Constructor)
    -> Constructor -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M Text
    "cstringToString"
                   (Text
    "CInt", Text
    "Char")      -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "(chr . fromIntegral)"
                   (Text
    "CInt", Text
    "Bool")      -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "(/= 0)"
                   (Text
    "CFloat", Text
    "Float")   -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "realToFrac"
                   (Text
    "CDouble", Text
    "Double") -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "realToFrac"
                   (Text
    "CGType", Text
    "GType")   -> Constructor -> ExcCodeGen Constructor
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Constructor
    "GType"
                   (Text, Text)
    _                     ->
                       Text -> ExcCodeGen Constructor
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen Constructor) -> Text -> ExcCodeGen Constructor
    forall a b. (a -> b) -> a -> b
    $ Text
    "Don't know how to convert "
                                               Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> TypeRep -> Text
    typeShow TypeRep
    fType Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " into "
                                               Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> TypeRep -> Text
    typeShow TypeRep
    hType Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ".\n"
                                               Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "Internal type: "
                                               Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t

    getHaskellConstructor :: Type -> Transfer -> ExcCodeGen Constructor
    getHaskellConstructor :: Type -> Transfer -> ExcCodeGen Constructor
    getHaskellConstructor Type
    t Transfer
    transfer = do
      a <- Type -> CodeGen CGError (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      hType <- haskellType t
      fType <- foreignType t
      fToH' t a hType fType transfer

    fToH_PackedType :: Type -> Text -> Transfer -> ExcCodeGen Converter
    fToH_PackedType :: Type -> Text -> Transfer -> ExcCodeGen Converter
    fToH_PackedType Type
    t Text
    unpacker Transfer
    transfer = do
      innerConstructor <- Type -> Transfer -> ExcCodeGen Constructor
    getHaskellConstructor Type
    t Transfer
    transfer
      return $ do
        apply (M unpacker)
        mapC innerConstructor

    fToH_UnpackGHashTable :: Type -> Type -> Transfer -> ExcCodeGen Converter
    fToH_UnpackGHashTable :: Type -> Type -> Transfer -> ExcCodeGen Converter
    fToH_UnpackGHashTable Type
    keys Type
    elems Transfer
    transfer = do
      keysConstructor <- Type -> Transfer -> ExcCodeGen Constructor
    getHaskellConstructor Type
    keys Transfer
    transfer
      (_,_,keysUnpack) <- hashTablePtrPackers keys
      elemsConstructor <- getHaskellConstructor elems transfer
      (_,_,elemsUnpack) <- hashTablePtrPackers elems
      return $ do
        apply (M "unpackGHashTable")
        mapFirst (P keysUnpack)
        mapFirst keysConstructor
        mapSecond (P elemsUnpack)
        mapSecond elemsConstructor
        apply (P "Map.fromList")

    fToH :: Type -> Transfer -> ExcCodeGen Converter
    fToH :: Type -> Transfer -> ExcCodeGen Converter
    fToH (TGList Type
    t) Transfer
    transfer = do
      isPtr <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    typeIsPtr Type
    t
      when (not isPtr) $
           badIntroError ("`" <> tshow t <>
                          "' is not a pointer type, cannot unpack from a GList.")
      fToH_PackedType t "unpackGList" transfer
    fToH (TGSList Type
    t) Transfer
    transfer = do
      isPtr <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    typeIsPtr Type
    t
      when (not isPtr) $
           badIntroError ("`" <> tshow t <>
                          "' is not a pointer type, cannot unpack from a GSList.")
      fToH_PackedType t "unpackGSList" transfer
    fToH (TGArray Type
    t) Transfer
    transfer = Type -> Text -> Transfer -> ExcCodeGen Converter
    fToH_PackedType Type
    t Text
    "unpackGArray" Transfer
    transfer
    fToH (TPtrArray Type
    t) Transfer
    transfer = Type -> Text -> Transfer -> ExcCodeGen Converter
    fToH_PackedType Type
    t Text
    "unpackGPtrArray" Transfer
    transfer
    fToH (TGHash Type
    a Type
    b) Transfer
    transfer = Type -> Type -> Transfer -> ExcCodeGen Converter
    fToH_UnpackGHashTable Type
    a Type
    b Transfer
    transfer
    -- We cannot unpack arrays without any kind of length info.
    fToH t :: Type
    t@(TCArray Bool
    False (-1) (-1) Type
    _) Transfer
    _ =
      Text -> ExcCodeGen Converter
    forall a. Text -> ExcCodeGen a
    badIntroError (Text
    "`" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <>
                      Text
    "' is an array type, but contains no length information.")
    fToH (TCArray Bool
    True Int
    _ Int
    _ t :: Type
    t@(TCArray{})) Transfer
    transfer =
      Type -> Text -> Transfer -> ExcCodeGen Converter
    fToH_PackedType Type
    t Text
    "unpackZeroTerminatedPtrArray" Transfer
    transfer
    fToH (TCArray Bool
    True Int
    _ Int
    _ t :: Type
    t@(TInterface Name
    _)) Transfer
    transfer = do
      isScalar <- Type -> CodeGen CGError Bool
    forall e. Type -> CodeGen e Bool
    typeIsEnumOrFlag Type
    t
      if isScalar
      then fToH_PackedType t "unpackZeroTerminatedStorableArray" transfer
      else fToH_PackedType t "unpackZeroTerminatedPtrArray" transfer

    fToH Type
    t Transfer
    transfer = do
      a <- Type -> CodeGen CGError (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      hType <- haskellType t
      fType <- foreignType t
      constructor <- fToH' t a hType fType transfer
      return $ apply constructor

    -- | Somewhat like `fToH`, but with slightly different borrowing
    -- semantics: in the case of `TransferNothing` we wrap incoming
    -- pointers to boxed structs into transient `ManagedPtr`s (every other
    -- case behaves as `fToH`). These are `ManagedPtr`s for which we do
    -- not make a copy, and which will be disowned when the function
    -- exists, instead of making a copy that the GC will collect
    -- eventually.
    --
    -- This is necessary in order to get the semantics of callbacks and
    -- signals right: in some cases making a copy of the object does not
    -- simply increase the refcount, but rather makes a full copy. In this
    -- cases modification of the original object is not possible, but this
    -- is sometimes useful, see for example
    --
    -- https://github.com/haskell-gi/haskell-gi/issues/97
    --
    -- Another situation where making a copy of incoming arguments is
    -- problematic is when the underlying library is not thread-safe. When
    -- running under the threaded GHC runtime it can happen that the GC
    -- runs on a different OS thread than the thread where the object was
    -- created, and this leads to rather mysterious bugs, see for example
    --
    -- https://github.com/haskell-gi/haskell-gi/issues/96
    --
    -- This case is particularly nasty, since it affects `onWidgetDraw`,
    -- which is very common.
    transientToH :: Type -> Transfer -> ExcCodeGen Converter
    transientToH :: Type -> Transfer -> ExcCodeGen Converter
    transientToH t :: Type
    t@(TInterface Name
    _) Transfer
    TransferNothing = do
      a <- Type -> CodeGen CGError (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case a of
        Just (APIStruct Struct
    s) -> if Struct -> Bool
    structIsBoxed Struct
    s
                              then ExcCodeGen Converter
    forall e. CodeGen e Converter
    wrapTransient
                              else Type -> Transfer -> ExcCodeGen Converter
    fToH Type
    t Transfer
    TransferNothing
        Just (APIUnion Union
    u) -> if Union -> Bool
    unionIsBoxed Union
    u
                             then ExcCodeGen Converter
    forall e. CodeGen e Converter
    wrapTransient
                             else Type -> Transfer -> ExcCodeGen Converter
    fToH Type
    t Transfer
    TransferNothing
        Maybe API
    _ -> Type -> Transfer -> ExcCodeGen Converter
    fToH Type
    t Transfer
    TransferNothing
    transientToH Type
    t Transfer
    transfer = Type -> Transfer -> ExcCodeGen Converter
    fToH Type
    t Transfer
    transfer

    -- | Wrap the given transient.
    wrapTransient :: CodeGen e Converter
    wrapTransient :: forall e. CodeGen e Converter
    wrapTransient = Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Converter)
    -> Converter
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Converter
    lambdaConvert (Text -> Converter) -> Text -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text
    "B.ManagedPtr.withTransient "

    unpackCArray :: Text -> Type -> Transfer -> ExcCodeGen Converter
    unpackCArray :: Text -> Type -> Transfer -> ExcCodeGen Converter
    unpackCArray Text
    length (TCArray Bool
    False Int
    _ Int
    _ Type
    t) Transfer
    transfer =
      case Type
    t of
        TBasicType BasicType
    TUTF8 -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackUTF8CArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TFileName -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackFileNameArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TUInt8 -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackByteStringWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TPtr -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackPtrArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TBoolean -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackMapStorableArrayWithLength (/= 0) " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TGType -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackMapStorableArrayWithLength GType " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TFloat -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackMapStorableArrayWithLength realToFrac " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TDouble -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackMapStorableArrayWithLength realToFrac " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    TUniChar -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackMapStorableArrayWithLength (SP.chr . P.fromIntegral) " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TBasicType BasicType
    _ -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "unpackStorableArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        Type
    TGValue -> Converter -> ExcCodeGen Converter
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except CGError)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Converter -> ExcCodeGen Converter)
    -> Converter -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $ Constructor -> Converter
    apply (Constructor -> Converter) -> Constructor -> Converter
    forall a b. (a -> b) -> a -> b
    $ Text -> Constructor
    M (Text -> Constructor) -> Text -> Constructor
    forall a b. (a -> b) -> a -> b
    $ Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $
          Text
    "B.GValue.unpackGValueArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    length
        TInterface Name
    _ -> do
               a <- Type -> CodeGen CGError (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
               isScalar <- typeIsEnumOrFlag t
               hType <- haskellType t
               fType <- foreignType t
               let (boxed, size) = case a of
                            Just (APIStruct Struct
    s) -> (Struct -> Bool
    structIsBoxed Struct
    s, Struct -> Int
    structSize Struct
    s)
                            Just (APIUnion Union
    u) -> (Union -> Bool
    unionIsBoxed Union
    u, Union -> Int
    unionSize Union
    u)
                            Maybe API
    _ -> (Bool
    False, Int
    0)
               let unpacker | Bool
    isScalar    = Text
    "unpackStorableArrayWithLength"
                            | (Int
    size Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0) = Text
    "unpackPtrArrayWithLength"
                            | Bool
    boxed       = Text
    "unpackBoxedArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    size
                            | Bool
    otherwise   = Text
    "unpackBlockArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    size
                   -- We always make a copy of the elements when unpacking
                   -- boxed types.
               let transfer' | Bool
    boxed      = if Transfer
    transfer Transfer -> Transfer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Transfer
    TransferContainer
                                            then Transfer
    TransferEverything
                                            else Transfer
    transfer
                             | Bool
    otherwise  = Transfer
    transfer
               innerConstructor <- fToH' t a hType fType transfer'
               return $ do
                 apply $ M $ parenthesize $ unpacker <> " " <> length
                 mapC innerConstructor
        Type
    _ -> Text -> ExcCodeGen Converter
    forall a. Text -> ExcCodeGen a
    notImplementedError (Text -> ExcCodeGen Converter) -> Text -> ExcCodeGen Converter
    forall a b. (a -> b) -> a -> b
    $
             Text
    "unpackCArray : Don't know how to unpack C Array of type " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Type -> Text
    forall a. Show a => a -> Text
    tshow Type
    t

    unpackCArray Text
    _ Type
    _ Transfer
    _ = Text -> ExcCodeGen Converter
    forall a. Text -> ExcCodeGen a
    notImplementedError Text
    "unpackCArray : unexpected array type."

    -- | Whether to expose closures and the associated destroy notify
    -- handlers in the Haskell wrapper.
    data ExposeClosures = WithClosures
                        | WithoutClosures
      deriving (ExposeClosures -> ExposeClosures -> Bool
    (ExposeClosures -> ExposeClosures -> Bool)
    -> (ExposeClosures -> ExposeClosures -> Bool) -> Eq ExposeClosures
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ExposeClosures -> ExposeClosures -> Bool
    == :: ExposeClosures -> ExposeClosures -> Bool
    $c/= :: ExposeClosures -> ExposeClosures -> Bool
    /= :: ExposeClosures -> ExposeClosures -> Bool
    Eq)

    -- | Given a type find the typeclasses the type belongs to, and return
    -- the representation of the type in the function signature and the
    -- list of typeclass constraints for the type.
    argumentType :: Type -> ExposeClosures -> CodeGen e (Text, [Text])
    argumentType :: forall e. Type -> ExposeClosures -> CodeGen e (Text, [Text])
    argumentType (TGList Type
    a) ExposeClosures
    expose = do
      (name, constraints) <- Type -> ExposeClosures -> CodeGen e (Text, [Text])
    forall e. Type -> ExposeClosures -> CodeGen e (Text, [Text])
    argumentType Type
    a ExposeClosures
    expose
      return ("[" <> name <> "]", constraints)
    argumentType (TGSList Type
    a) ExposeClosures
    expose = do
      (name, constraints) <- Type -> ExposeClosures -> CodeGen e (Text, [Text])
    forall e. Type -> ExposeClosures -> CodeGen e (Text, [Text])
    argumentType Type
    a ExposeClosures
    expose
      return ("[" <> name <> "]", constraints)
    argumentType Type
    t ExposeClosures
    expose = do
      api <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      s <- typeShow <$> haskellType t
      case api of
        -- Instead of restricting to the actual class,
        -- we allow for any object descending from it.
        Just (APIInterface Interface
    _) -> do
          cls <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Type -> CodeGen e Text
    typeConstraint Type
    t
          l <- getFreshTypeVariable
          return (l, [cls <> " " <> l])
        Just (APIObject Object
    _) -> do
          cls <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall e. Type -> CodeGen e Text
    typeConstraint Type
    t
          l <- getFreshTypeVariable
          return (l, [cls <> " " <> l])
        Just (APICallback Callback
    cb) ->
          -- See [Note: Callables that throw]
          if Callable -> Bool
    callableThrows (Callback -> Callable
    cbCallable Callback
    cb)
          then do
            ft <- TypeRep -> Text
    typeShow (TypeRep -> Text)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    t
            return (ft, [])
          else
            case ExposeClosures
    expose of
              ExposeClosures
    WithClosures -> do
                s_withClosures <- TypeRep -> Text
    typeShow (TypeRep -> Text)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    isoHaskellType Type
    t
                return (s_withClosures, [])
              ExposeClosures
    WithoutClosures ->
                (Text, [Text]) -> CodeGen e (Text, [Text])
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    s, [])
        Maybe API
    _ -> (Text, [Text]) -> CodeGen e (Text, [Text])
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text
    s, [])

    haskellBasicType :: BasicType -> TypeRep
    haskellBasicType :: BasicType -> TypeRep
    haskellBasicType BasicType
    TPtr      = TypeRep -> TypeRep
    ptr (TypeRep -> TypeRep) -> TypeRep -> TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text -> TypeRep
    con0 Text
    "()"
    haskellBasicType BasicType
    TBoolean  = Text -> TypeRep
    con0 Text
    "Bool"
    -- For all the platforms that we support (and those supported by glib)
    -- we have gint == gint32. Encoding this assumption in the types saves
    -- conversions.
    haskellBasicType BasicType
    TInt      = case CInt -> Int
    forall a. Storable a => a -> Int
    sizeOf (CInt
    0 :: CInt) of
                                   Int
    4 -> Text -> TypeRep
    con0 Text
    "Int32"
                                   Int
    n -> [Char] -> TypeRep
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "Unsupported `gint' length: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                               Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    n)
    haskellBasicType BasicType
    TUInt     = case CUInt -> Int
    forall a. Storable a => a -> Int
    sizeOf (CUInt
    0 :: CUInt) of
                                   Int
    4 -> Text -> TypeRep
    con0 Text
    "Word32"
                                   Int
    n -> [Char] -> TypeRep
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "Unsupported `guint' length: " [Char] -> ShowS
    forall a. [a] -> [a] -> [a]
    ++
                                               Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    n)
    haskellBasicType BasicType
    TLong     = Text -> TypeRep
    con0 Text
    "FCT.CLong"
    haskellBasicType BasicType
    TULong    = Text -> TypeRep
    con0 Text
    "FCT.CULong"
    haskellBasicType BasicType
    TInt8     = Text -> TypeRep
    con0 Text
    "Int8"
    haskellBasicType BasicType
    TUInt8    = Text -> TypeRep
    con0 Text
    "Word8"
    haskellBasicType BasicType
    TInt16    = Text -> TypeRep
    con0 Text
    "Int16"
    haskellBasicType BasicType
    TUInt16   = Text -> TypeRep
    con0 Text
    "Word16"
    haskellBasicType BasicType
    TInt32    = Text -> TypeRep
    con0 Text
    "Int32"
    haskellBasicType BasicType
    TUInt32   = Text -> TypeRep
    con0 Text
    "Word32"
    haskellBasicType BasicType
    TInt64    = Text -> TypeRep
    con0 Text
    "Int64"
    haskellBasicType BasicType
    TUInt64   = Text -> TypeRep
    con0 Text
    "Word64"
    haskellBasicType BasicType
    TGType    = Text -> TypeRep
    con0 Text
    "GType"
    haskellBasicType BasicType
    TUTF8     = Text -> TypeRep
    con0 Text
    "T.Text"
    haskellBasicType BasicType
    TFloat    = Text -> TypeRep
    con0 Text
    "Float"
    haskellBasicType BasicType
    TDouble   = Text -> TypeRep
    con0 Text
    "Double"
    haskellBasicType BasicType
    TUniChar  = Text -> TypeRep
    con0 Text
    "Char"
    haskellBasicType BasicType
    TFileName = Text -> TypeRep
    con0 Text
    "[Char]"
    haskellBasicType BasicType
    TIntPtr   = Text -> TypeRep
    con0 Text
    "CIntPtr"
    haskellBasicType BasicType
    TUIntPtr  = Text -> TypeRep
    con0 Text
    "CUIntPtr"
    haskellBasicType BasicType
    TShort    = Text -> TypeRep
    con0 Text
    "FCT.CShort"
    haskellBasicType BasicType
    TUShort   = Text -> TypeRep
    con0 Text
    "FCT.CUShort"
    haskellBasicType BasicType
    TSSize    =

    {-# LINE 804 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
        Int -> TypeRep
    int (Int
    8)
    {-# LINE 805 "lib/Data/GI/CodeGen/Conversions.hsc" #-}

    {-# LINE 806 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    haskellBasicType TSize = con0 "FCT.CSize"
    haskellBasicType BasicType
    Ttime_t = Text -> TypeRep
    con0 Text
    "FCT.CTime"
    haskellBasicType BasicType
    Toff_t =

    {-# LINE 812 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      -- If the type is not defined there's not much we can do, other than
      -- guessing. The values below are correct on Linux amd64. In
      -- practice it will hopefully not be much of an issue with newer
      -- versions of GHC, since platforms lacking the definition will
      -- (hopefully) also not have the relevant types in the available
      -- APIs. The same remark applies to the types below.
      Int -> TypeRep
    int Int
    8

    {-# LINE 820 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    haskellBasicType Tdev_t =

    {-# LINE 824 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      uint 8

    {-# LINE 826 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    haskellBasicType Tgid_t =

    {-# LINE 830 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      uint 4

    {-# LINE 832 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    haskellBasicType Tpid_t =

    {-# LINE 836 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      int 4

    {-# LINE 838 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    haskellBasicType Tsocklen_t =

    {-# LINE 842 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      uint 4

    {-# LINE 844 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
    haskellBasicType Tuid_t =

    {-# LINE 848 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      uint 4

    {-# LINE 850 "lib/Data/GI/CodeGen/Conversions.hsc" #-}

    -- | Return the unsigned int type with the given amount of bytes.
    uint :: Int -> TypeRep
    uint :: Int -> TypeRep
    uint Int
    n = Text -> TypeRep
    con0 (Text
    "DW.Word" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    8))

    -- | Return the (signed) int type with the given amount of bytes.
    int :: Int -> TypeRep
    int :: Int -> TypeRep
    int Int
    n = Text -> TypeRep
    con0 (Text
    "DI.Int" Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    *Int
    8))

    -- | This translates GI types to the types used for generated Haskell code.
    haskellType :: Type -> CodeGen e TypeRep
    haskellType :: forall e. Type -> CodeGen e TypeRep
    haskellType (TBasicType BasicType
    bt) = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ BasicType -> TypeRep
    haskellBasicType BasicType
    bt
    -- There is no great choice in this case, so we simply pass the
    -- pointer along. This is useful for GdkPixbufNotify, for example.
    haskellType t :: Type
    t@(TCArray Bool
    False (-1) (-1) (TBasicType BasicType
    TUInt8)) =
      Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    t
    haskellType (TCArray Bool
    _ Int
    _ Int
    _ (TBasicType BasicType
    TUInt8)) =
      TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "ByteString" Text -> [TypeRep] -> TypeRep
    `con` []
    haskellType (TCArray Bool
    _ Int
    _ Int
    _ Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    a
      return $ "[]" `con` [inner]
    haskellType (TGArray Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    a
      return $ "[]" `con` [inner]
    haskellType (TPtrArray Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    a
      return $ "[]" `con` [inner]
    haskellType (Type
    TByteArray) = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "ByteString" Text -> [TypeRep] -> TypeRep
    `con` []
    haskellType (TGList Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    a
      return $ "[]" `con` [inner]
    haskellType (TGSList Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    a
      return $ "[]" `con` [inner]
    haskellType (TGHash Type
    a Type
    b) = do
      innerA <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    a
      innerB <- haskellType b
      return $ "Map.Map" `con` [innerA, innerB]
    haskellType Type
    TError = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "GError" Text -> [TypeRep] -> TypeRep
    `con` []
    haskellType Type
    TVariant = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "GVariant" Text -> [TypeRep] -> TypeRep
    `con` []
    haskellType Type
    TParamSpec = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "GParamSpec" Text -> [TypeRep] -> TypeRep
    `con` []
    haskellType (TGClosure (Just inner :: Type
    inner@(TInterface Name
    n))) = do
      innerAPI <- Type -> CodeGen e API
    forall e. HasCallStack => Type -> CodeGen e API
    getAPI Type
    inner
      case innerAPI of
        APICallback Callback
    _ -> do
          let n' :: Name
    n' = API -> Name -> Name
    normalizedAPIName API
    innerAPI Name
    n
          tname <- Text -> Name -> CodeGen e Text
    forall e. Text -> Name -> CodeGen e Text
    qualifiedSymbol (Text -> Text
    callbackCType (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Name -> Text
    name Name
    n') Name
    n
          return $ "GClosure" `con` [con0 tname]
        -- The given inner type does not make sense, so we treat it as an
        -- untyped closure.
        API
    _ -> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType (Maybe Type -> Type
    TGClosure Maybe Type
    forall a. Maybe a
    Nothing)
    haskellType (TGClosure Maybe Type
    _) = do
      tyvar <- CodeGen e Text
    forall e. CodeGen e Text
    getFreshTypeVariable
      return $ "GClosure" `con` [con0 tyvar]
    haskellType Type
    TGValue = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "GValue" Text -> [TypeRep] -> TypeRep
    `con` []
    haskellType t :: Type
    t@(TInterface Name
    n) = do
      api <- Type -> CodeGen e API
    forall e. HasCallStack => Type -> CodeGen e API
    getAPI Type
    t
      tname <- qualifiedAPI api n
      return $ case api of
                 (APIFlags Flags
    _) -> Text
    "[]" Text -> [TypeRep] -> TypeRep
    `con` [Text
    tname Text -> [TypeRep] -> TypeRep
    `con` []]
                 API
    _ -> Text
    tname Text -> [TypeRep] -> TypeRep
    `con` []

    -- | Whether the callable has closure arguments (i.e. "user_data"
    -- style arguments).
    callableHasClosures :: Callable -> Bool
    callableHasClosures :: Callable -> Bool
    callableHasClosures Callable
    c = [Bool] -> Bool
    forall (t :: * -> *). Foldable t => t Bool -> Bool
    or ([Bool] -> Bool) -> ([Arg] -> [Bool]) -> [Arg] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Arg -> [Bool]) -> [Arg] -> [Bool]
    forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
    concatMap Arg -> [Bool]
    checkArg ([Arg] -> Bool) -> [Arg] -> Bool
    forall a b. (a -> b) -> a -> b
    $ Callable -> [Arg]
    args Callable
    c
      where checkArg :: Arg -> [Bool]
            checkArg :: Arg -> [Bool]
    checkArg Arg
    arg = [Arg -> Int
    argClosure Arg
    arg Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= -Int
    1, Arg -> Bool
    argCallbackUserData Arg
    arg]

    -- | Check whether the given type corresponds to a callback.
    typeIsCallback :: Type -> CodeGen e Bool
    typeIsCallback :: forall e. Type -> CodeGen e Bool
    typeIsCallback t :: Type
    t@(TInterface Name
    _) = do
      api <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case api of
        Just (APICallback Callback
    _) -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        Maybe API
    _ -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
    typeIsCallback Type
    _ = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

    -- | Basically like `haskellType`, but for types which admit a
    -- "isomorphic" version of the Haskell type distinct from the usual
    -- Haskell type.  Generally the Haskell type we expose is isomorphic
    -- to the foreign type, but in some cases, such as callbacks with
    -- closure arguments, this does not hold, as we omit the closure
    -- arguments. This function returns a type which is actually
    -- isomorphic.
    --
    -- There is another case this function deals with: for convenience
    -- untyped `TGClosure` types have a type variable on the Haskell side
    -- when they are arguments to functions, but we do not want this when
    -- they appear as arguments to callbacks/signals, or return types of
    -- properties, as it would force the type synonym/type family to
    -- depend on the type variable.
    isoHaskellType :: Type -> CodeGen e TypeRep
    isoHaskellType :: forall e. Type -> CodeGen e TypeRep
    isoHaskellType (TGClosure Maybe Type
    Nothing) =
      TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ Text
    "GClosure" Text -> [TypeRep] -> TypeRep
    `con` [Text -> TypeRep
    con0 Text
    "()"]
    isoHaskellType t :: Type
    t@(TInterface Name
    n) = do
      api <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case api of
        Just apiCB :: API
    apiCB@(APICallback Callback
    cb) -> do
            tname <- API -> Name -> CodeGen e Text
    forall e. API -> Name -> CodeGen e Text
    qualifiedAPI API
    apiCB Name
    n
            if callableHasClosures (cbCallable cb)
            then return ((callbackHTypeWithClosures tname) `con` [])
            else return (tname `con` [])
        Maybe API
    _ -> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t
    isoHaskellType Type
    t = Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t

    -- | Foreign (C) type associated to one of the basic types.
    foreignBasicType :: BasicType -> TypeRep
    foreignBasicType :: BasicType -> TypeRep
    foreignBasicType BasicType
    TBoolean  = Text
    "CInt" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    TUTF8     = Text
    "CString" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    TFileName = Text
    "CString" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    TUniChar  = Text
    "CInt" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    TFloat    = Text
    "CFloat" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    TDouble   = Text
    "CDouble" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    TGType    = Text
    "CGType" Text -> [TypeRep] -> TypeRep
    `con` []
    foreignBasicType BasicType
    t         = BasicType -> TypeRep
    haskellBasicType BasicType
    t

    -- This translates GI types to the types used in foreign function calls.
    foreignType :: Type -> CodeGen e TypeRep
    foreignType :: forall e. Type -> CodeGen e TypeRep
    foreignType (TBasicType BasicType
    t) = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ BasicType -> TypeRep
    foreignBasicType BasicType
    t
    foreignType (TCArray Bool
    _ Int
    _ Int
    _ Type
    TGValue) = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ TypeRep -> TypeRep
    ptr (Text
    "B.GValue.GValue" Text -> [TypeRep] -> TypeRep
    `con` [])
    foreignType (TCArray Bool
    zt Int
    _ Int
    _ Type
    t) = do
      api <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      let size = case Maybe API
    api of
                   Just (APIStruct Struct
    s) -> Struct -> Int
    structSize Struct
    s
                   Just (APIUnion Union
    u) -> Union -> Int
    unionSize Union
    u
                   Maybe API
    _ -> Int
    0
      if size == 0 || zt
      then ptr <$> foreignType t
      else foreignType t
    foreignType (TGArray Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    a
      return $ ptr ("GArray" `con` [inner])
    foreignType (TPtrArray Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    a
      return $ ptr ("GPtrArray" `con` [inner])
    foreignType (Type
    TByteArray) = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ TypeRep -> TypeRep
    ptr (Text
    "GByteArray" Text -> [TypeRep] -> TypeRep
    `con` [])
    foreignType (TGList Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    a
      return $ ptr ("GList" `con` [inner])
    foreignType (TGSList Type
    a) = do
      inner <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    a
      return $ ptr ("GSList" `con` [inner])
    foreignType (TGHash Type
    a Type
    b) = do
      innerA <- Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    a
      innerB <- foreignType b
      return $ ptr ("GHashTable" `con` [innerA, innerB])
    foreignType t :: Type
    t@Type
    TError = TypeRep -> TypeRep
    ptr (TypeRep -> TypeRep)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t
    foreignType t :: Type
    t@Type
    TVariant = TypeRep -> TypeRep
    ptr (TypeRep -> TypeRep)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t
    foreignType t :: Type
    t@Type
    TParamSpec = TypeRep -> TypeRep
    ptr (TypeRep -> TypeRep)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t
    foreignType (TGClosure Maybe Type
    Nothing) = TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ TypeRep -> TypeRep
    ptr (Text
    "GClosure" Text -> [TypeRep] -> TypeRep
    `con` [Text -> TypeRep
    con0 Text
    "()"])
    foreignType t :: Type
    t@(TGClosure (Just Type
    _)) = TypeRep -> TypeRep
    ptr (TypeRep -> TypeRep)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t
    foreignType t :: Type
    t@(Type
    TGValue) = TypeRep -> TypeRep
    ptr (TypeRep -> TypeRep)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall e. Type -> CodeGen e TypeRep
    haskellType Type
    t
    foreignType t :: Type
    t@(TInterface Name
    n) = do
      api <- Type -> CodeGen e API
    forall e. HasCallStack => Type -> CodeGen e API
    getAPI Type
    t
      let enumIsSigned Enumeration
    e = (Int64 -> Bool) -> [Int64] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Int64 -> Int64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int64
    0) ((EnumerationMember -> Int64) -> [EnumerationMember] -> [Int64]
    forall a b. (a -> b) -> [a] -> [b]
    map EnumerationMember -> Int64
    enumMemberValue (Enumeration -> [EnumerationMember]
    enumMembers Enumeration
    e))
          ctypeForEnum Enumeration
    e = if Enumeration -> Bool
    enumIsSigned Enumeration
    e
                           then a
    "CInt"
                           else a
    "CUInt"
      case api of
        APIEnum Enumeration
    e -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ (Enumeration -> Text
    forall {a}. IsString a => Enumeration -> a
    ctypeForEnum Enumeration
    e) Text -> [TypeRep] -> TypeRep
    `con` []
        APIFlags (Flags Enumeration
    e) -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (TypeRep
     -> ReaderT
          CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep)
    -> TypeRep
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) TypeRep
    forall a b. (a -> b) -> a -> b
    $ (Enumeration -> Text
    forall {a}. IsString a => Enumeration -> a
    ctypeForEnum Enumeration
    e) Text -> [TypeRep] -> TypeRep
    `con` []
        APICallback Callback
    _ -> do
          let n' :: Name
    n' = API -> Name -> Name
    normalizedAPIName API
    api Name
    n
          tname <- Text -> Name -> CodeGen e Text
    forall e. Text -> Name -> CodeGen e Text
    qualifiedSymbol (Text -> Text
    callbackCType (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Name -> Text
    name Name
    n') Name
    n
          return (funptr $ tname `con` [])
        API
    _ -> do
          tname <- API -> Name -> CodeGen e Text
    forall e. API -> Name -> CodeGen e Text
    qualifiedAPI API
    api Name
    n
          return (ptr $ tname `con` [])

    -- | Whether the give type corresponds to an enum or flag.
    typeIsEnumOrFlag :: Type -> CodeGen e Bool
    typeIsEnumOrFlag :: forall e. Type -> CodeGen e Bool
    typeIsEnumOrFlag Type
    t = do
      a <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case a of
        Maybe API
    Nothing -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
        (Just (APIEnum Enumeration
    _)) -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        (Just (APIFlags Flags
    _)) -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        Maybe API
    _ -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

    -- | Information on how to allocate a type: allocator function and
    -- size of the struct.
    data TypeAllocInfo = TypeAlloc Text Int

    -- | Information on how to allocate the given type, if known.
    typeAllocInfo :: Type -> CodeGen e (Maybe TypeAllocInfo)
    typeAllocInfo :: forall e. Type -> CodeGen e (Maybe TypeAllocInfo)
    typeAllocInfo Type
    TGValue =
      let n :: Int
    n = (Int
    24)
    {-# LINE 1038 "lib/Data/GI/CodeGen/Conversions.hsc" #-}
      in return $ Just $ TypeAlloc ("SP.callocBytes " <> tshow n) n
    typeAllocInfo (TGArray Type
    t) = do
      api <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case api of
        Just (APIStruct Struct
    s) -> case Struct -> Int
    structSize Struct
    s of
                                Int
    0 -> Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TypeAllocInfo
    forall a. Maybe a
    Nothing
                                Int
    n -> let allocator :: Text
    allocator = Text
    "B.GArray.allocGArray " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    n
                                     in Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe TypeAllocInfo
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          (Maybe TypeAllocInfo))
    -> Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a b. (a -> b) -> a -> b
    $ TypeAllocInfo -> Maybe TypeAllocInfo
    forall a. a -> Maybe a
    Just (TypeAllocInfo -> Maybe TypeAllocInfo)
    -> TypeAllocInfo -> Maybe TypeAllocInfo
    forall a b. (a -> b) -> a -> b
    $ Text -> Int -> TypeAllocInfo
    TypeAlloc Text
    allocator Int
    n
        Maybe API
    _ -> Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TypeAllocInfo
    forall a. Maybe a
    Nothing
    typeAllocInfo Type
    t = do
      api <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case api of
        Just (APIStruct Struct
    s) ->
          case Struct -> Int
    structSize Struct
    s of
            Int
    0 -> Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TypeAllocInfo
    forall a. Maybe a
    Nothing
            Int
    n -> let allocator :: Text
    allocator = if Struct -> Bool
    structIsBoxed Struct
    s
                                 then Text
    "SP.callocBoxedBytes"
                                 else Text
    "SP.callocBytes"
                 in Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Maybe TypeAllocInfo
     -> ReaderT
          CodeGenConfig
          (StateT (CGState, ModuleInfo) (Except e))
          (Maybe TypeAllocInfo))
    -> Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a b. (a -> b) -> a -> b
    $ TypeAllocInfo -> Maybe TypeAllocInfo
    forall a. a -> Maybe a
    Just (TypeAllocInfo -> Maybe TypeAllocInfo)
    -> TypeAllocInfo -> Maybe TypeAllocInfo
    forall a b. (a -> b) -> a -> b
    $ Text -> Int -> TypeAllocInfo
    TypeAlloc (Text
    allocator Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    n) Int
    n
        Maybe API
    _ -> Maybe TypeAllocInfo
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe TypeAllocInfo)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe TypeAllocInfo
    forall a. Maybe a
    Nothing

    -- | Returns whether the given type corresponds to a `ManagedPtr`
    -- instance (a thin wrapper over a `ForeignPtr`).
    isManaged   :: Type -> CodeGen e Bool
    isManaged :: forall e. Type -> CodeGen e Bool
    isManaged Type
    TError = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
    isManaged Type
    TVariant = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
    isManaged Type
    TGValue = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
    isManaged Type
    TParamSpec = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
    isManaged (TGClosure Maybe Type
    _) = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
    isManaged t :: Type
    t@(TInterface Name
    _) = do
      a <- Type -> CodeGen e (Maybe API)
    forall e. HasCallStack => Type -> CodeGen e (Maybe API)
    findAPI Type
    t
      case a of
        Just (APIObject Object
    _)    -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        Just (APIInterface Interface
    _) -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        Just (APIStruct Struct
    _)    -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        Just (APIUnion Union
    _)     -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    True
        Maybe API
    _                     -> Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False
    isManaged Type
    _ = Bool
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Bool
    False

    -- | Returns whether the given type is represented by a pointer on the
    -- C side.
    typeIsPtr :: Type -> CodeGen e Bool
    typeIsPtr :: forall e. Type -> CodeGen e Bool
    typeIsPtr Type
    t = Maybe FFIPtrType -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe FFIPtrType -> Bool)
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall e. Type -> CodeGen e (Maybe FFIPtrType)
    typePtrType Type
    t

    -- | Distinct types of foreign pointers.
    data FFIPtrType = FFIPtr    -- ^ Ordinary `Ptr`.
                    | FFIFunPtr -- ^ `FunPtr`.

    -- | For those types represented by pointers on the C side, return the
    -- type of pointer which represents them on the Haskell FFI.
    typePtrType :: Type -> CodeGen e (Maybe FFIPtrType)
    typePtrType :: forall e. Type -> CodeGen e (Maybe FFIPtrType)
    typePtrType (TBasicType BasicType
    TPtr) = Maybe FFIPtrType
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FFIPtrType -> Maybe FFIPtrType
    forall a. a -> Maybe a
    Just FFIPtrType
    FFIPtr)
    typePtrType (TBasicType BasicType
    TUTF8) = Maybe FFIPtrType
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FFIPtrType -> Maybe FFIPtrType
    forall a. a -> Maybe a
    Just FFIPtrType
    FFIPtr)
    typePtrType (TBasicType BasicType
    TFileName) = Maybe FFIPtrType
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FFIPtrType -> Maybe FFIPtrType
    forall a. a -> Maybe a
    Just FFIPtrType
    FFIPtr)
    typePtrType Type
    t = do
      ft <- Type -> CodeGen e TypeRep
    forall e. Type -> CodeGen e TypeRep
    foreignType Type
    t
      case typeConName ft of
        Text
    "Ptr"    -> Maybe FFIPtrType
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FFIPtrType -> Maybe FFIPtrType
    forall a. a -> Maybe a
    Just FFIPtrType
    FFIPtr)
        Text
    "FunPtr" -> Maybe FFIPtrType
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (FFIPtrType -> Maybe FFIPtrType
    forall a. a -> Maybe a
    Just FFIPtrType
    FFIFunPtr)
        Text
    _        -> Maybe FFIPtrType
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe FFIPtrType)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe FFIPtrType
    forall a. Maybe a
    Nothing

    -- | If the passed in type is nullable, return the conversion function
    -- between the FFI pointer type (may be a `Ptr` or a `FunPtr`) and the
    -- corresponding `Maybe` type.
    maybeNullConvert :: Type -> CodeGen e (Maybe Text)
    maybeNullConvert :: forall e. Type -> CodeGen e (Maybe Text)
    maybeNullConvert (TBasicType BasicType
    TPtr) = Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Text
    forall a. Maybe a
    Nothing
    maybeNullConvert (TGList Type
    _) = Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Text
    forall a. Maybe a
    Nothing
    maybeNullConvert (TGSList Type
    _) = Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Text
    forall a. Maybe a
    Nothing
    maybeNullConvert Type
    t = do
      pt <- Type -> CodeGen e (Maybe FFIPtrType)
    forall e. Type -> CodeGen e (Maybe FFIPtrType)
    typePtrType Type
    t
      case pt of
        Just FFIPtrType
    FFIPtr -> Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "SP.convertIfNonNull")
        Just FFIPtrType
    FFIFunPtr -> Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "SP.convertFunPtrIfNonNull")
        Maybe FFIPtrType
    Nothing -> Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Text
    forall a. Maybe a
    Nothing

    -- | An appropriate NULL value for the given type, for types which are
    -- represented by pointers on the C side.
    nullPtrForType :: Type -> CodeGen e (Maybe Text)
    nullPtrForType :: forall e. Type -> CodeGen e (Maybe Text)
    nullPtrForType Type
    t = do
      pt <- Type -> CodeGen e (Maybe FFIPtrType)
    forall e. Type -> CodeGen e (Maybe FFIPtrType)
    typePtrType Type
    t
      case pt of
        Just FFIPtrType
    FFIPtr -> Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "FP.nullPtr")
        Just FFIPtrType
    FFIFunPtr -> Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Text -> Maybe Text
    forall a. a -> Maybe a
    Just Text
    "FP.nullFunPtr")
        Maybe FFIPtrType
    Nothing -> Maybe Text
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall a.
    a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe Text
    forall a. Maybe a
    Nothing

    -- | Returns whether the given type should be represented by a
    -- `Maybe` type on the Haskell side. This applies to all properties
    -- which have a C representation in terms of pointers, except for
    -- G(S)Lists, for which NULL is a valid G(S)List, and raw pointers,
    -- which we just pass through to the Haskell side. Notice that
    -- introspection annotations can override this.
    typeIsNullable :: Type -> CodeGen e Bool
    typeIsNullable :: forall e. Type -> CodeGen e Bool
    typeIsNullable Type
    t = Maybe Text -> Bool
    forall a. Maybe a -> Bool
    isJust (Maybe Text -> Bool)
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type
    -> ReaderT
         CodeGenConfig
         (StateT (CGState, ModuleInfo) (Except e))
         (Maybe Text)
    forall e. Type -> CodeGen e (Maybe Text)
    maybeNullConvert Type
    t

    -- | If the given type maps to a list in Haskell, return the type of the
    -- elements, and the function that maps over them.
    elementTypeAndMap :: Type -> Text -> Maybe (Type, Text)
    -- ByteString
    elementTypeAndMap :: Type -> Text -> Maybe (Type, Text)
    elementTypeAndMap (TCArray Bool
    _ Int
    _ Int
    _ (TBasicType BasicType
    TUInt8)) Text
    _ = Maybe (Type, Text)
    forall a. Maybe a
    Nothing
    elementTypeAndMap (TCArray Bool
    True Int
    _ Int
    _ Type
    t) Text
    _ = (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text
    "mapZeroTerminatedCArray")
    elementTypeAndMap (TCArray Bool
    _ Int
    _ Int
    _ Type
    TGValue) Text
    len =
      (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    TGValue, Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "B.GValue.mapGValueArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    len)
    elementTypeAndMap (TCArray Bool
    False (-1) Int
    _ Type
    t) Text
    len =
      (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "mapCArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    len)
    elementTypeAndMap (TCArray Bool
    False Int
    fixed Int
    _ Type
    t) Text
    _ =
      (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text -> Text
    parenthesize (Text -> Text) -> Text -> Text
    forall a b. (a -> b) -> a -> b
    $ Text
    "mapCArrayWithLength " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    tshow Int
    fixed)
    elementTypeAndMap (TGArray Type
    t) Text
    _ = (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text
    "mapGArray")
    elementTypeAndMap (TPtrArray Type
    t) Text
    _ = (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text
    "mapPtrArray")
    elementTypeAndMap (TGList Type
    t) Text
    _ = (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text
    "mapGList")
    elementTypeAndMap (TGSList Type
    t) Text
    _ = (Type, Text) -> Maybe (Type, Text)
    forall a. a -> Maybe a
    Just (Type
    t, Text
    "mapGSList")
    -- GHashTable is treated separately, see Transfer.hs
    elementTypeAndMap Type
    _ Text
    _ = Maybe (Type, Text)
    forall a. Maybe a
    Nothing

    -- Return just the element type.
    elementType :: Type -> Maybe Type
    elementType :: Type -> Maybe Type
    elementType Type
    t = (Type, Text) -> Type
    forall a b. (a, b) -> a
    fst ((Type, Text) -> Type) -> Maybe (Type, Text) -> Maybe Type
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Text -> Maybe (Type, Text)
    elementTypeAndMap Type
    t Text
    forall a. HasCallStack => a
    undefined

    -- Return just the map.
    elementMap :: Type -> Text -> Maybe Text
    elementMap :: Type -> Text -> Maybe Text
    elementMap Type
    t Text
    len = (Type, Text) -> Text
    forall a b. (a, b) -> b
    snd ((Type, Text) -> Text) -> Maybe (Type, Text) -> Maybe Text
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Type -> Text -> Maybe (Type, Text)
    elementTypeAndMap Type
    t Text
    len