{-# 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)
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
instanceTree :: Name -> CodeGen [Name]
instanceTree :: Name -> CodeGen [Name]
instanceTree Name
n = do
API
api <- HasCallStack => Name -> CodeGen API
Name -> CodeGen 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]) -> BaseCodeGen e [Name] -> BaseCodeGen e [Name]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Name -> CodeGen [Name]
instanceTree Name
p
Maybe Name
Nothing -> [Name] -> BaseCodeGen e [Name]
forall (m :: * -> *) a. Monad m => a -> m a
return []
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
apiInheritables :: Inheritable i => Name -> CodeGen [(Name, i)]
apiInheritables :: Name -> CodeGen [(Name, i)]
apiInheritables Name
n = do
API
api <- HasCallStack => Name -> CodeGen API
Name -> CodeGen API
findAPIByName Name
n
case API -> Maybe API
dropMovedItems API
api of
Just (APIInterface Interface
iface) -> [(Name, i)] -> BaseCodeGen e [(Name, i)]
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Name, i)] -> BaseCodeGen e [(Name, i)])
-> [(Name, i)] -> BaseCodeGen 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)] -> BaseCodeGen e [(Name, i)]
forall (m :: * -> *) a. Monad m => a -> m a
return ([(Name, i)] -> BaseCodeGen e [(Name, i)])
-> [(Name, i)] -> BaseCodeGen 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] -> BaseCodeGen e [(Name, i)]
forall a. HasCallStack => [Char] -> a
error ([Char] -> BaseCodeGen e [(Name, i)])
-> [Char] -> BaseCodeGen 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 [(Name, i)]
fullAPIInheritableList :: Name -> CodeGen [(Name, i)]
fullAPIInheritableList Name
n = do
API
api <- HasCallStack => Name -> CodeGen API
Name -> CodeGen API
findAPIByName Name
n
case API
api of
APIInterface Interface
iface -> Name -> Interface -> CodeGen [(Name, i)]
forall i. Inheritable i => Name -> Interface -> CodeGen [(Name, i)]
fullInterfaceInheritableList Name
n Interface
iface
APIObject Object
object -> Name -> Object -> CodeGen [(Name, i)]
forall i. Inheritable i => Name -> Object -> CodeGen [(Name, i)]
fullObjectInheritableList Name
n Object
object
API
_ -> [Char] -> BaseCodeGen e [(Name, i)]
forall a. HasCallStack => [Char] -> a
error ([Char] -> BaseCodeGen e [(Name, i)])
-> [Char] -> BaseCodeGen 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 [(Name, i)]
fullObjectInheritableList :: Name -> Object -> CodeGen [(Name, i)]
fullObjectInheritableList Name
n Object
obj = do
[Name]
iT <- Name -> CodeGen [Name]
instanceTree Name
n
[(Name, i)] -> [(Name, i)] -> [(Name, i)]
forall a. [a] -> [a] -> [a]
(++) ([(Name, i)] -> [(Name, i)] -> [(Name, i)])
-> BaseCodeGen 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)]]
-> BaseCodeGen e [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Name -> BaseCodeGen 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)
mapM Name -> BaseCodeGen e [(Name, i)]
forall i. Inheritable i => Name -> CodeGen [(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)])
-> BaseCodeGen e [(Name, i)] -> BaseCodeGen e [(Name, i)]
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)]]
-> BaseCodeGen e [(Name, i)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Name -> BaseCodeGen 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)
mapM Name -> BaseCodeGen e [(Name, i)]
forall i. Inheritable i => Name -> CodeGen [(Name, i)]
apiInheritables (Object -> [Name]
objInterfaces Object
obj))
fullInterfaceInheritableList :: Inheritable i => Name -> Interface ->
CodeGen [(Name, i)]
fullInterfaceInheritableList :: Name -> Interface -> CodeGen [(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)
mapM Name
-> ReaderT
CodeGenConfig (StateT (CGState, ModuleInfo) (Except e)) [(Name, i)]
forall i. Inheritable i => Name -> CodeGen [(Name, i)]
fullAPIInheritableList (Interface -> [Name]
ifPrerequisites Interface
iface))
removeDuplicates :: forall i. (Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates :: Bool -> [(Name, i)] -> CodeGen [(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))
Map Text (Bool, Name, i)
-> (Name, i) -> CodeGen (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 (M.Map Text (Bool, Name, i))
filterDups :: Map Text (Bool, Name, i)
-> (Name, i) -> CodeGen (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)
-> BaseCodeGen e (Map Text (Bool, Name, i))
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)
-> BaseCodeGen e (Map Text (Bool, Name, i))
forall (m :: * -> *) a. Monad m => a -> m a
return Map Text (Bool, Name, i)
m
| 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 -> CodeGen ()
line Text
"--- XXX Duplicated object with different types:"
Text -> CodeGen ()
line (Text -> CodeGen ()) -> Text -> CodeGen ()
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 -> CodeGen ()
line (Text -> CodeGen ()) -> Text -> CodeGen ()
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
Map Text (Bool, Name, i)
-> BaseCodeGen e (Map Text (Bool, Name, i))
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Text (Bool, Name, i)
-> BaseCodeGen e (Map Text (Bool, Name, i)))
-> Map Text (Bool, Name, i)
-> BaseCodeGen 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)
-> BaseCodeGen e (Map Text (Bool, Name, i))
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Text (Bool, Name, i)
-> BaseCodeGen e (Map Text (Bool, Name, i)))
-> Map Text (Bool, Name, i)
-> BaseCodeGen 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]
fullObjectPropertyList :: Name -> Object -> CodeGen [(Name, Property)]
fullObjectPropertyList :: Name -> Object -> CodeGen [(Name, Property)]
fullObjectPropertyList Name
n Object
o = Name -> Object -> CodeGen [(Name, Property)]
forall i. Inheritable i => Name -> Object -> CodeGen [(Name, i)]
fullObjectInheritableList Name
n Object
o BaseCodeGen e [(Name, Property)]
-> ([(Name, Property)] -> BaseCodeGen e [(Name, Property)])
-> BaseCodeGen e [(Name, Property)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Bool -> [(Name, Property)] -> CodeGen [(Name, Property)]
forall i.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates Bool
True
fullInterfacePropertyList :: Name -> Interface -> CodeGen [(Name, Property)]
fullInterfacePropertyList :: Name -> Interface -> CodeGen [(Name, Property)]
fullInterfacePropertyList Name
n Interface
i = Name -> Interface -> CodeGen [(Name, Property)]
forall i. Inheritable i => Name -> Interface -> CodeGen [(Name, i)]
fullInterfaceInheritableList Name
n Interface
i BaseCodeGen e [(Name, Property)]
-> ([(Name, Property)] -> BaseCodeGen e [(Name, Property)])
-> BaseCodeGen e [(Name, Property)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Bool -> [(Name, Property)] -> CodeGen [(Name, Property)]
forall i.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates Bool
True
fullObjectSignalList :: Name -> Object -> CodeGen [(Name, Signal)]
fullObjectSignalList :: Name -> Object -> CodeGen [(Name, Signal)]
fullObjectSignalList Name
n Object
o = Name -> Object -> CodeGen [(Name, Signal)]
forall i. Inheritable i => Name -> Object -> CodeGen [(Name, i)]
fullObjectInheritableList Name
n Object
o BaseCodeGen e [(Name, Signal)]
-> ([(Name, Signal)] -> BaseCodeGen e [(Name, Signal)])
-> BaseCodeGen e [(Name, Signal)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Bool -> [(Name, Signal)] -> CodeGen [(Name, Signal)]
forall i.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates Bool
True
fullInterfaceSignalList :: Name -> Interface -> CodeGen [(Name, Signal)]
fullInterfaceSignalList :: Name -> Interface -> CodeGen [(Name, Signal)]
fullInterfaceSignalList Name
n Interface
i = Name -> Interface -> CodeGen [(Name, Signal)]
forall i. Inheritable i => Name -> Interface -> CodeGen [(Name, i)]
fullInterfaceInheritableList Name
n Interface
i BaseCodeGen e [(Name, Signal)]
-> ([(Name, Signal)] -> BaseCodeGen e [(Name, Signal)])
-> BaseCodeGen e [(Name, Signal)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Bool -> [(Name, Signal)] -> CodeGen [(Name, Signal)]
forall i.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates Bool
True
fullObjectMethodList :: Name -> Object -> CodeGen [(Name, Method)]
fullObjectMethodList :: Name -> Object -> CodeGen [(Name, Method)]
fullObjectMethodList Name
n Object
o = Name -> Object -> CodeGen [(Name, Method)]
forall i. Inheritable i => Name -> Object -> CodeGen [(Name, i)]
fullObjectInheritableList Name
n Object
o BaseCodeGen e [(Name, Method)]
-> ([(Name, Method)] -> BaseCodeGen e [(Name, Method)])
-> BaseCodeGen e [(Name, Method)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Bool -> [(Name, Method)] -> CodeGen [(Name, Method)]
forall i.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates Bool
False
fullInterfaceMethodList :: Name -> Interface -> CodeGen [(Name, Method)]
fullInterfaceMethodList :: Name -> Interface -> CodeGen [(Name, Method)]
fullInterfaceMethodList Name
n Interface
i = Name -> Interface -> CodeGen [(Name, Method)]
forall i. Inheritable i => Name -> Interface -> CodeGen [(Name, i)]
fullInterfaceInheritableList Name
n Interface
i BaseCodeGen e [(Name, Method)]
-> ([(Name, Method)] -> BaseCodeGen e [(Name, Method)])
-> BaseCodeGen e [(Name, Method)]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Bool -> [(Name, Method)] -> CodeGen [(Name, Method)]
forall i.
(Eq i, Show i, Inheritable i) =>
Bool -> [(Name, i)] -> CodeGen [(Name, i)]
removeDuplicates Bool
False