module Data.GI.CodeGen.GObject
    ( isGObject
    , apiIsGObject
    , nameIsGObject
    ) where

#if !MIN_VERSION_base(4,8,0)
import Control.Applicative ((<$>))
#endif

import Data.GI.CodeGen.API
import Data.GI.CodeGen.Code
import Data.GI.CodeGen.Type

-- Returns whether the given type is a descendant of the given parent.
typeDoParentSearch :: Name -> Type -> CodeGen e Bool
typeDoParentSearch :: forall e. Name -> Type -> CodeGen e Bool
typeDoParentSearch Name
parent (TInterface Name
n) = forall e. HasCallStack => Name -> CodeGen e API
findAPIByName Name
n forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                                           forall e. Name -> Name -> API -> CodeGen e Bool
apiDoParentSearch Name
parent Name
n
typeDoParentSearch Name
_ Type
_ = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

apiDoParentSearch :: Name -> Name -> API -> CodeGen e Bool
apiDoParentSearch :: forall e. Name -> Name -> API -> CodeGen e Bool
apiDoParentSearch Name
parent Name
n API
api
    | Name
parent forall a. Eq a => a -> a -> Bool
== Name
n = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
    | Bool
otherwise   = case API
api of
      APIObject Object
o ->
        case Object -> Maybe Name
objParent Object
o of
          Just  Name
p -> forall e. Name -> Type -> CodeGen e Bool
typeDoParentSearch Name
parent (Name -> Type
TInterface Name
p)
          Maybe Name
Nothing -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
      APIInterface Interface
iface ->
        do let prs :: [Name]
prs = Interface -> [Name]
ifPrerequisites Interface
iface
           [(Name, API)]
prereqs <- forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
prs forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall e. HasCallStack => Name -> CodeGen e API
findAPIByName [Name]
prs
           forall (t :: * -> *). Foldable t => t Bool -> Bool
or forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (forall e. Name -> Name -> API -> CodeGen e Bool
apiDoParentSearch Name
parent)) [(Name, API)]
prereqs
      API
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False

-- | Check whether the given type descends from GObject.
isGObject :: Type -> CodeGen e Bool
isGObject :: forall e. Type -> CodeGen e Bool
isGObject = forall e. Name -> Type -> CodeGen e Bool
typeDoParentSearch forall a b. (a -> b) -> a -> b
$ Text -> Text -> Name
Name Text
"GObject" Text
"Object"

-- | Check whether the given name descends from GObject.
nameIsGObject :: Name -> CodeGen e Bool
nameIsGObject :: forall e. Name -> CodeGen e Bool
nameIsGObject Name
n = forall e. HasCallStack => Name -> CodeGen e API
findAPIByName Name
n forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall e. Name -> API -> CodeGen e Bool
apiIsGObject Name
n

-- | Check whether the given API descends from GObject.
apiIsGObject :: Name -> API -> CodeGen e Bool
apiIsGObject :: forall e. Name -> API -> CodeGen e Bool
apiIsGObject = forall e. Name -> Name -> API -> CodeGen e Bool
apiDoParentSearch forall a b. (a -> b) -> a -> b
$ Text -> Text -> Name
Name Text
"GObject" Text
"Object"