{-# LANGUAGE ScopedTypeVariables #-}
module Data.GI.CodeGen.Inheritance
    ( fullObjectPropertyList
    , fullInterfacePropertyList
    , fullObjectSignalList
    , fullInterfaceSignalList
    , fullObjectMethodList
    , fullInterfaceMethodList
    , instanceTree
    ) where

import Control.Monad (foldM, when)
import qualified Data.Map as M
#if !MIN_VERSION_base(4,13,0)
import Data.Monoid ((<>))
#endif
import Data.Text (Text)

import Data.GI.CodeGen.API
import Data.GI.CodeGen.Code (findAPIByName, CodeGen, line)
import Data.GI.CodeGen.Util (tshow)
import Data.GI.CodeGen.Fixups (dropMovedItems)

-- | Find the parent of a given object when building the
-- instanceTree. For the purposes of the binding we do not need to
-- distinguish between GObject.Object and GObject.InitiallyUnowned.
getParent :: API -> Maybe Name
getParent :: API -> Maybe Name
getParent (APIObject Object
o) = Maybe Name -> Maybe Name
rename (Maybe Name -> Maybe Name) -> Maybe Name -> Maybe Name
forall a b. (a -> b) -> a -> b
$ Object -> Maybe Name
objParent Object
o
    where
      rename :: Maybe Name -> Maybe Name
      rename :: Maybe Name -> Maybe Name
rename (Just (Name Text
"GObject" Text
"InitiallyUnowned")) =
          Name -> Maybe Name
forall a. a -> Maybe a
Just (Text -> Text -> Name
Name Text
"GObject" Text
"Object")
      rename Maybe Name
x = Maybe Name
x
getParent API
_ = Maybe Name
forall a. Maybe a
Nothing

-- | Compute the (ordered) list of parents of the current object.
instanceTree :: Name -> CodeGen e [Name]
instanceTree :: forall e. Name -> CodeGen e [Name]
instanceTree Name
n = do
  API
api <- Name -> CodeGen e API
forall e. HasCallStack => Name -> CodeGen e API
findAPIByName Name
n
  case API -> Maybe Name
getParent API
api of
    Just Name
p -> (Name
p Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
:) ([Name] -> [Name]) -> CodeGen e [Name] -> CodeGen e [Name]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> CodeGen e [Name]
forall e. Name -> CodeGen e [Name]
instanceTree Name
p
    Maybe Name
Nothing -> [Name] -> CodeGen e [Name]
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return []

-- A class for qualities of an object/interface that it inherits from
-- its ancestors. Properties and Signals are two classes of interest.
class Inheritable i where
    ifInheritables :: Interface -> [i]
    objInheritables :: Object -> [i]
    iName :: i -> Text

instance Inheritable Property where
    ifInheritables :: Interface -> [Property]
ifInheritables = Interface -> [Property]
ifProperties
    objInheritables :: Object -> [Property]
objInheritables = Object -> [Property]
objProperties
    iName :: Property -> Text
iName = Property -> Text
propName

instance Inheritable Signal where
    ifInheritables :: Interface -> [Signal]
ifInheritables = Interface -> [Signal]
ifSignals
    objInheritables :: Object -> [Signal]
objInheritables = Object -> [Signal]
objSignals
    iName :: Signal -> Text
iName = Signal -> Text
sigName

instance Inheritable Method where
    ifInheritables :: Interface -> [Method]
ifInheritables = Interface -> [Method]
ifMethods
    objInheritables :: Object -> [Method]
objInheritables = Object -> [Method]
objMethods
    iName :: Method -> Text
iName = Name -> Text
name (Name -> Text) -> (Method -> Name) -> Method -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Method -> Name
methodName

-- Returns a list of all inheritables defined for this object
-- (including those defined by its ancestors and the interfaces it
-- implements), together with the name of the interface defining the
-- property.
apiInheritables :: Inheritable i => Name -> CodeGen e [(Name, i)]
apiInheritables :: forall i e. Inheritable i => Name -> CodeGen e [(Name, i)]
apiInheritables Name
n = do
  API
api <- Name -> CodeGen e API
forall e. HasCallStack => Name -> CodeGen e API
findAPIByName Name
n
  case API -> Maybe API
dropMovedItems API
api of
    Just (APIInterface Interface
iface) -> [(Name, i)] -> CodeGen e [(Name, i)]
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Name, i)] -> CodeGen e [(Name, i)])
-> [(Name, i)] -> CodeGen e [(Name, i)]
forall a b. (a -> b) -> a -> b
$ (i -> (Name, i)) -> [i] -> [(Name, i)]
forall a b. (a -> b) -> [a] -> [b]
map ((,) Name
n) (Interface -> [i]
forall i. Inheritable i => Interface -> [i]
ifInheritables Interface
iface)
    Just (APIObject Object
object) -> [(Name, i)] -> CodeGen e [(Name, i)]
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Name, i)] -> CodeGen e [(Name, i)])
-> [(Name, i)] -> CodeGen e [(Name, i)]
forall a b. (a -> b) -> a -> b
$ (i -> (Name, i)) -> [i] -> [(Name, i)]
forall a b. (a -> b) -> [a] -> [b]
map ((,) Name
n) (Object -> [i]
forall i. Inheritable i => Object -> [i]
objInheritables Object
object)
    Maybe API
_ -> [Char] -> CodeGen e [(Name, i)]
forall a. HasCallStack => [Char] -> a
error ([Char] -> CodeGen e [(Name, i)])
-> [Char] -> CodeGen e [(Name, i)]
forall a b. (a -> b) -> a -> b
$ [Char]
"apiInheritables : Unexpected API : " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Name -> [Char]
forall a. Show a => a -> [Char]
show Name
n

fullAPIInheritableList :: Inheritable i => Name -> CodeGen e [(Name, i)]
fullAPIInheritableList :: forall i e. Inheritable i => Name -> CodeGen e [(Name, i)]
fullAPIInheritableList Name
n = do
  API
api <- Name -> CodeGen e API
forall e. HasCallStack => Name -> CodeGen e API
findAPIByName Name
n
  case API
api of
    APIInterface Interface
iface -> Name -> Interface -> CodeGen e [(Name, i)]
forall i e.
Inheritable i =>
Name -> Interface -> CodeGen e [(Name, i)]
fullInterfaceInheritableList Name
n Interface
iface
    APIObject Object
object -> Name -> Object -> CodeGen e [(Name, i)]
forall i e.
Inheritable i =>
Name -> Object -> CodeGen e [(Name, i)]
fullObjectInheritableList Name
n Object
object
    API
_ -> [Char] -> CodeGen e [(Name, i)]
forall a. HasCallStack => [Char] -> a
error ([Char] -> CodeGen e [(Name, i)])
-> [Char] -> CodeGen e [(Name, i)]
forall a b. (a -> b) -> a -> b
$ [Char]
"FullAPIInheritableList : Unexpected API : " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Name -> [Char]
forall a. Show a => a -> [Char]
show Name
n

fullObjectInheritableList :: Inheritable i => Name -> Object ->
                             CodeGen e [(Name, i)]
fullObjectInheritableList :: forall i e.
Inheritable i =>
Name -> Object -> CodeGen e [(Name, i)]
fullObjectInheritableList Name
n Object
obj = do
  [Name]
iT <- Name -> CodeGen e [Name]
forall e. Name -> CodeGen e [Name]
instanceTree Name
n
  [(Name, i)] -> [(Name, i)] -> [(Name, i)]
forall a. [a] -> [a] -> [a]
(++) ([(Name, i)] -> [(Name, i)] -> [(Name, i)])
-> CodeGen e [(Name, i)]
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     ([(Name, i)] -> [(Name, i)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([[(Name, i)]] -> [(Name, i)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(Name, i)]] -> [(Name, i)])
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     [[(Name, i)]]
-> CodeGen e [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Name -> CodeGen e [(Name, i)])
-> [Name]
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     [[(Name, i)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Name -> CodeGen e [(Name, i)]
forall i e. Inheritable i => Name -> CodeGen e [(Name, i)]
apiInheritables (Name
n Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
: [Name]
iT))
       ReaderT
  CodeGenConfig
  (StateT (CGState, ModuleInfo) (Except e))
  ([(Name, i)] -> [(Name, i)])
-> CodeGen e [(Name, i)] -> CodeGen e [(Name, i)]
forall a b.
ReaderT
  CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) (a -> b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ([[(Name, i)]] -> [(Name, i)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(Name, i)]] -> [(Name, i)])
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     [[(Name, i)]]
-> CodeGen e [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Name -> CodeGen e [(Name, i)])
-> [Name]
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     [[(Name, i)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Name -> CodeGen e [(Name, i)]
forall i e. Inheritable i => Name -> CodeGen e [(Name, i)]
apiInheritables (Object -> [Name]
objInterfaces Object
obj))

fullInterfaceInheritableList :: Inheritable i => Name -> Interface ->
                                CodeGen e [(Name, i)]
fullInterfaceInheritableList :: forall i e.
Inheritable i =>
Name -> Interface -> CodeGen e [(Name, i)]
fullInterfaceInheritableList Name
n Interface
iface =
  [(Name, i)] -> [(Name, i)] -> [(Name, i)]
forall a. [a] -> [a] -> [a]
(++) ((i -> (Name, i)) -> [i] -> [(Name, i)]
forall a b. (a -> b) -> [a] -> [b]
map ((,) Name
n) (Interface -> [i]
forall i. Inheritable i => Interface -> [i]
ifInheritables Interface
iface))
    ([(Name, i)] -> [(Name, i)])
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) [(Name, i)]
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([[(Name, i)]] -> [(Name, i)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(Name, i)]] -> [(Name, i)])
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     [[(Name, i)]]
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Name
 -> ReaderT
      CodeGenConfig
      (StateT (CGState, ModuleInfo) (Except e))
      [(Name, i)])
-> [Name]
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     [[(Name, i)]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Name
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) [(Name, i)]
forall i e. Inheritable i => Name -> CodeGen e [(Name, i)]
fullAPIInheritableList (Interface -> [Name]
ifPrerequisites Interface
iface))

-- | It is sometimes the case that a property name or signal is defined
-- both in an object and in one of its ancestors/implemented
-- interfaces. This is harmless if the properties are isomorphic
-- (there will be more than one qualified set of property
-- setters/getters that we can call, but they are all isomorphic). If
-- they are not isomorphic we print a warning, and choose to use the
-- one closest to the leaves of the object hierarchy.
removeDuplicates :: forall i e. (Eq i, Show i, Inheritable i) =>
                        Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates :: forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
verbose [(Name, i)]
inheritables =
    ([(Text, (Bool, Name, i))] -> [(Name, i)]
filterTainted ([(Text, (Bool, Name, i))] -> [(Name, i)])
-> (Map Text (Bool, Name, i) -> [(Text, (Bool, Name, i))])
-> Map Text (Bool, Name, i)
-> [(Name, i)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Text (Bool, Name, i) -> [(Text, (Bool, Name, i))]
forall k a. Map k a -> [(k, a)]
M.toList) (Map Text (Bool, Name, i) -> [(Name, i)])
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Map Text (Bool, Name, i)
 -> (Name, i)
 -> ReaderT
      CodeGenConfig
      (StateT (CGState, ModuleInfo) (Except e))
      (Map Text (Bool, Name, i)))
-> Map Text (Bool, Name, i)
-> [(Name, i)]
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM Map Text (Bool, Name, i)
-> (Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
filterDups Map Text (Bool, Name, i)
forall k a. Map k a
M.empty [(Name, i)]
inheritables
    where
      filterDups :: M.Map Text (Bool, Name, i) -> (Name, i) ->
                    CodeGen e (M.Map Text (Bool, Name, i))
      filterDups :: Map Text (Bool, Name, i)
-> (Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
filterDups Map Text (Bool, Name, i)
m (Name
name, i
prop) =
        case Text -> Map Text (Bool, Name, i) -> Maybe (Bool, Name, i)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (i -> Text
forall i. Inheritable i => i -> Text
iName i
prop) Map Text (Bool, Name, i)
m of
          Just (Bool
tainted, Name
n, i
p)
              | Bool
tainted     -> Map Text (Bool, Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return Map Text (Bool, Name, i)
m
              | (i
p i -> i -> Bool
forall a. Eq a => a -> a -> Bool
== i
prop) -> Map Text (Bool, Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return Map Text (Bool, Name, i)
m -- Duplicated, but isomorphic property
              | Bool
otherwise   ->
                do Bool
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
verbose (ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
 -> ReaderT
      CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ())
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall a b. (a -> b) -> a -> b
$ do
                     Text
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall e. Text -> CodeGen e ()
line   Text
"--- XXX Duplicated object with different types:"
                     Text
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall e. Text -> CodeGen e ()
line (Text
 -> ReaderT
      CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ())
-> Text
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall a b. (a -> b) -> a -> b
$ Text
"  --- " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Name -> Text
forall a. Show a => a -> Text
tshow Name
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" -> " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> i -> Text
forall a. Show a => a -> Text
tshow i
p
                     Text
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall e. Text -> CodeGen e ()
line (Text
 -> ReaderT
      CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ())
-> Text
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) ()
forall a b. (a -> b) -> a -> b
$ Text
"  --- " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Name -> Text
forall a. Show a => a -> Text
tshow Name
name Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" -> " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> i -> Text
forall a. Show a => a -> Text
tshow i
prop
                   -- Tainted
                   Map Text (Bool, Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Text (Bool, Name, i)
 -> ReaderT
      CodeGenConfig
      (StateT (CGState, ModuleInfo) (Except e))
      (Map Text (Bool, Name, i)))
-> Map Text (Bool, Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall a b. (a -> b) -> a -> b
$ Text
-> (Bool, Name, i)
-> Map Text (Bool, Name, i)
-> Map Text (Bool, Name, i)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (i -> Text
forall i. Inheritable i => i -> Text
iName i
prop) (Bool
True, Name
n, i
p) Map Text (Bool, Name, i)
m
          Maybe (Bool, Name, i)
Nothing -> Map Text (Bool, Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall a.
a
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Text (Bool, Name, i)
 -> ReaderT
      CodeGenConfig
      (StateT (CGState, ModuleInfo) (Except e))
      (Map Text (Bool, Name, i)))
-> Map Text (Bool, Name, i)
-> ReaderT
     CodeGenConfig
     (StateT (CGState, ModuleInfo) (Except e))
     (Map Text (Bool, Name, i))
forall a b. (a -> b) -> a -> b
$ Text
-> (Bool, Name, i)
-> Map Text (Bool, Name, i)
-> Map Text (Bool, Name, i)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (i -> Text
forall i. Inheritable i => i -> Text
iName i
prop) (Bool
False, Name
name, i
prop) Map Text (Bool, Name, i)
m
      filterTainted :: [(Text, (Bool, Name, i))] -> [(Name, i)]
      filterTainted :: [(Text, (Bool, Name, i))] -> [(Name, i)]
filterTainted [(Text, (Bool, Name, i))]
xs =
          [(Name
name, i
prop) | (Text
_, (Bool
_, Name
name, i
prop)) <- [(Text, (Bool, Name, i))]
xs]

-- | List all properties defined for an object, including those
-- defined by its ancestors.
fullObjectPropertyList :: Name -> Object -> CodeGen e [(Name, Property)]
fullObjectPropertyList :: forall e. Name -> Object -> CodeGen e [(Name, Property)]
fullObjectPropertyList Name
n Object
o = Name -> Object -> CodeGen e [(Name, Property)]
forall i e.
Inheritable i =>
Name -> Object -> CodeGen e [(Name, i)]
fullObjectInheritableList Name
n Object
o CodeGen e [(Name, Property)]
-> ([(Name, Property)] -> CodeGen e [(Name, Property)])
-> CodeGen e [(Name, Property)]
forall a b.
ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> (a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                         Bool -> [(Name, Property)] -> CodeGen e [(Name, Property)]
forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
True

-- | List all properties defined for an interface, including those
-- defined by its prerequisites.
fullInterfacePropertyList :: Name -> Interface -> CodeGen e [(Name, Property)]
fullInterfacePropertyList :: forall e. Name -> Interface -> CodeGen e [(Name, Property)]
fullInterfacePropertyList Name
n Interface
i = Name -> Interface -> CodeGen e [(Name, Property)]
forall i e.
Inheritable i =>
Name -> Interface -> CodeGen e [(Name, i)]
fullInterfaceInheritableList Name
n Interface
i CodeGen e [(Name, Property)]
-> ([(Name, Property)] -> CodeGen e [(Name, Property)])
-> CodeGen e [(Name, Property)]
forall a b.
ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> (a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                            Bool -> [(Name, Property)] -> CodeGen e [(Name, Property)]
forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
True

-- | List all signals defined for an object, including those
-- defined by its ancestors.
fullObjectSignalList :: Name -> Object -> CodeGen e [(Name, Signal)]
fullObjectSignalList :: forall e. Name -> Object -> CodeGen e [(Name, Signal)]
fullObjectSignalList Name
n Object
o = Name -> Object -> CodeGen e [(Name, Signal)]
forall i e.
Inheritable i =>
Name -> Object -> CodeGen e [(Name, i)]
fullObjectInheritableList Name
n Object
o CodeGen e [(Name, Signal)]
-> ([(Name, Signal)] -> CodeGen e [(Name, Signal)])
-> CodeGen e [(Name, Signal)]
forall a b.
ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> (a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                           Bool -> [(Name, Signal)] -> CodeGen e [(Name, Signal)]
forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
True

-- | List all signals defined for an interface, including those
-- defined by its prerequisites.
fullInterfaceSignalList :: Name -> Interface -> CodeGen e [(Name, Signal)]
fullInterfaceSignalList :: forall e. Name -> Interface -> CodeGen e [(Name, Signal)]
fullInterfaceSignalList Name
n Interface
i = Name -> Interface -> CodeGen e [(Name, Signal)]
forall i e.
Inheritable i =>
Name -> Interface -> CodeGen e [(Name, i)]
fullInterfaceInheritableList Name
n Interface
i CodeGen e [(Name, Signal)]
-> ([(Name, Signal)] -> CodeGen e [(Name, Signal)])
-> CodeGen e [(Name, Signal)]
forall a b.
ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> (a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                              Bool -> [(Name, Signal)] -> CodeGen e [(Name, Signal)]
forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
True

-- | List all methods defined for an object, including those defined
-- by its ancestors.
fullObjectMethodList :: Name -> Object -> CodeGen e [(Name, Method)]
fullObjectMethodList :: forall e. Name -> Object -> CodeGen e [(Name, Method)]
fullObjectMethodList Name
n Object
o = Name -> Object -> CodeGen e [(Name, Method)]
forall i e.
Inheritable i =>
Name -> Object -> CodeGen e [(Name, i)]
fullObjectInheritableList Name
n Object
o CodeGen e [(Name, Method)]
-> ([(Name, Method)] -> CodeGen e [(Name, Method)])
-> CodeGen e [(Name, Method)]
forall a b.
ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> (a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                           Bool -> [(Name, Method)] -> CodeGen e [(Name, Method)]
forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
False

-- | List all methods defined for an interface, including those
-- defined by its prerequisites.
fullInterfaceMethodList :: Name -> Interface -> CodeGen e [(Name, Method)]
fullInterfaceMethodList :: forall e. Name -> Interface -> CodeGen e [(Name, Method)]
fullInterfaceMethodList Name
n Interface
i = Name -> Interface -> CodeGen e [(Name, Method)]
forall i e.
Inheritable i =>
Name -> Interface -> CodeGen e [(Name, i)]
fullInterfaceInheritableList Name
n Interface
i CodeGen e [(Name, Method)]
-> ([(Name, Method)] -> CodeGen e [(Name, Method)])
-> CodeGen e [(Name, Method)]
forall a b.
ReaderT CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) a
-> (a
    -> ReaderT
         CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b)
-> ReaderT
     CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
                              Bool -> [(Name, Method)] -> CodeGen e [(Name, Method)]
forall i e.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen e [(Name, i)]
removeDuplicates Bool
False