{-# LANGUAGE LambdaCase      #-}
{-# LANGUAGE RecordWildCards #-}

module FFICXX.Generate.Dependency where

-- fficxx generates one module per one C++ class, and C++ class depends on other classes,
-- so we need to import other modules corresponding to C++ classes in the dependency list.
-- Calculating the import list from dependency graph is what this module does.

-- Previously, we have only `Class` type, but added `TemplateClass` recently. Therefore
-- we have to calculate dependency graph for both types of classes. So we needed to change
-- `Class` to `Either TemplateClass Class` in many of routines that calculates module import
-- list.

-- `Dep4Func` contains a list of classes (both ordinary and template types) that is needed
-- for the definition of a member function.
-- The goal of `extractClassDep...` functions are to extract Dep4Func, and from the definition
-- of a class or a template class, we get a list of `Dep4Func`s and then we deduplicate the
-- dependency class list and finally get the import list for the module corresponding to
-- a given class.

import           Data.Either       ( rights )
import           Data.Function     ( on )
import qualified Data.HashMap.Strict as HM
import           Data.List         ( find, foldl', nub, nubBy )
import qualified Data.Map as M
import           Data.Maybe        ( catMaybes, fromMaybe, mapMaybe )
import           Data.Monoid       ( (<>) )
import           System.FilePath   ( (<.>) )
--
import FFICXX.Runtime.CodeGen.Cxx  ( HeaderName(..) )
--
import FFICXX.Generate.Name        ( ffiClassName, hsClassName, hsTemplateClassName )
import FFICXX.Generate.Type.Cabal  ( AddCInc,AddCSrc,CabalName(..)
                                   , cabal_moduleprefix, cabal_pkgname
                                   , cabal_cheaderprefix, unCabalName
                                   )
import FFICXX.Generate.Type.Class  ( Arg(..)
                                   , Class(..)
                                   , CPPTypes(..)
                                   , DaughterMap
                                   , Function(..)
                                   , TemplateAppInfo(..)
                                   , TemplateArgType(TArg_Class)
                                   , TemplateClass(..)
                                   , TemplateFunction(..)
                                   , TemplateMemberFunction(..)
                                   , TopLevel(..)
                                   , Types(..)
                                   , Variable(unVariable)
                                   , argsFromOpExp
                                   )
import FFICXX.Generate.Type.Config ( ModuleUnit(..)
                                   , ModuleUnitImports(..)
                                   , emptyModuleUnitImports
                                   , ModuleUnitMap(..)
                                   )
import FFICXX.Generate.Type.Module ( ClassImportHeader(..)
                                   , ClassModule(..)
                                   , PackageConfig(..)
                                   , TemplateClassImportHeader(..)
                                   , TemplateClassModule(..)
                                   , TopLevelImportHeader(..)
                                   )


-- utility functions

getcabal :: Either TemplateClass Class -> Cabal
getcabal = (TemplateClass -> Cabal)
-> (Class -> Cabal) -> Either TemplateClass Class -> Cabal
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either TemplateClass -> Cabal
tclass_cabal Class -> Cabal
class_cabal

getparents :: Either b Class -> [Either a Class]
getparents = (b -> [Either a Class])
-> (Class -> [Either a Class])
-> Either b Class
-> [Either a Class]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([Either a Class] -> b -> [Either a Class]
forall a b. a -> b -> a
const []) ((Class -> Either a Class) -> [Class] -> [Either a Class]
forall a b. (a -> b) -> [a] -> [b]
map Class -> Either a Class
forall a b. b -> Either a b
Right ([Class] -> [Either a Class])
-> (Class -> [Class]) -> Class -> [Either a Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> [Class]
class_parents)

-- TODO: replace tclass_name with appropriate FFI name when supported.
getFFIName :: Either TemplateClass Class -> String
getFFIName = (TemplateClass -> String)
-> (Class -> String) -> Either TemplateClass Class -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either TemplateClass -> String
tclass_name Class -> String
ffiClassName


getPkgName :: Either TemplateClass Class -> CabalName
getPkgName :: Either TemplateClass Class -> CabalName
getPkgName = Cabal -> CabalName
cabal_pkgname (Cabal -> CabalName)
-> (Either TemplateClass Class -> Cabal)
-> Either TemplateClass Class
-> CabalName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> Cabal
getcabal


-- |
extractClassFromType :: Types -> [Either TemplateClass Class]
extractClassFromType :: Types -> [Either TemplateClass Class]
extractClassFromType Types
Void                     = []
extractClassFromType Types
SelfType                 = []
extractClassFromType (CT CTypes
_ IsConst
_)                 = []
extractClassFromType (CPT (CPTClass Class
c) IsConst
_)     = [Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c]
extractClassFromType (CPT (CPTClassRef Class
c) IsConst
_)  = [Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c]
extractClassFromType (CPT (CPTClassCopy Class
c) IsConst
_) = [Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c]
extractClassFromType (CPT (CPTClassMove Class
c) IsConst
_) = [Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c]
extractClassFromType (TemplateApp (TemplateAppInfo TemplateClass
t [TemplateArgType]
ps String
_)) =
  TemplateClass -> Either TemplateClass Class
forall a b. a -> Either a b
Left TemplateClass
t Either TemplateClass Class
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. a -> [a] -> [a]
: ((Class -> Either TemplateClass Class)
-> [Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> [a] -> [b]
map Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right ([Class] -> [Either TemplateClass Class])
-> [Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$ (TemplateArgType -> Maybe Class) -> [TemplateArgType] -> [Class]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\case TArg_Class Class
c -> Class -> Maybe Class
forall a. a -> Maybe a
Just Class
c; TemplateArgType
_ -> Maybe Class
forall a. Maybe a
Nothing) [TemplateArgType]
ps)
extractClassFromType (TemplateAppRef (TemplateAppInfo TemplateClass
t [TemplateArgType]
ps String
_))   =
  TemplateClass -> Either TemplateClass Class
forall a b. a -> Either a b
Left TemplateClass
t Either TemplateClass Class
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. a -> [a] -> [a]
: ((Class -> Either TemplateClass Class)
-> [Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> [a] -> [b]
map Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right ([Class] -> [Either TemplateClass Class])
-> [Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$ (TemplateArgType -> Maybe Class) -> [TemplateArgType] -> [Class]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\case TArg_Class Class
c -> Class -> Maybe Class
forall a. a -> Maybe a
Just Class
c; TemplateArgType
_ -> Maybe Class
forall a. Maybe a
Nothing) [TemplateArgType]
ps)
extractClassFromType (TemplateAppMove (TemplateAppInfo TemplateClass
t [TemplateArgType]
ps String
_))   =
  TemplateClass -> Either TemplateClass Class
forall a b. a -> Either a b
Left TemplateClass
t Either TemplateClass Class
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. a -> [a] -> [a]
: ((Class -> Either TemplateClass Class)
-> [Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> [a] -> [b]
map Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right ([Class] -> [Either TemplateClass Class])
-> [Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$ (TemplateArgType -> Maybe Class) -> [TemplateArgType] -> [Class]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\case TArg_Class Class
c -> Class -> Maybe Class
forall a. a -> Maybe a
Just Class
c; TemplateArgType
_ -> Maybe Class
forall a. Maybe a
Nothing) [TemplateArgType]
ps)
extractClassFromType (TemplateType TemplateClass
t)         = [TemplateClass -> Either TemplateClass Class
forall a b. a -> Either a b
Left TemplateClass
t]
extractClassFromType (TemplateParam String
_)        = []
extractClassFromType (TemplateParamPointer String
_) = []

classFromArg :: Arg -> [Either TemplateClass Class]
classFromArg :: Arg -> [Either TemplateClass Class]
classFromArg = Types -> [Either TemplateClass Class]
extractClassFromType (Types -> [Either TemplateClass Class])
-> (Arg -> Types) -> Arg -> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arg -> Types
arg_type


class_allparents :: Class -> [Class]
class_allparents :: Class -> [Class]
class_allparents Class
c = let ps :: [Class]
ps = Class -> [Class]
class_parents Class
c
                     in  if [Class] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Class]
ps
                           then []
                           else [Class] -> [Class]
forall a. Eq a => [a] -> [a]
nub ([Class]
ps [Class] -> [Class] -> [Class]
forall a. Semigroup a => a -> a -> a
<> ((Class -> [Class]) -> [Class] -> [Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Class -> [Class]
class_allparents [Class]
ps))


getClassModuleBase :: Class -> String
getClassModuleBase :: Class -> String
getClassModuleBase = String -> String -> String
(<.>) (String -> String -> String)
-> (Class -> String) -> Class -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Cabal -> String
cabal_moduleprefix(Cabal -> String) -> (Class -> Cabal) -> Class -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Class -> Cabal
class_cabal) (Class -> String -> String) -> (Class -> String) -> Class -> String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((String, String) -> String
forall a b. (a, b) -> a
fst((String, String) -> String)
-> (Class -> (String, String)) -> Class -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Class -> (String, String)
hsClassName)

getTClassModuleBase :: TemplateClass -> String
getTClassModuleBase :: TemplateClass -> String
getTClassModuleBase = String -> String -> String
(<.>) (String -> String -> String)
-> (TemplateClass -> String) -> TemplateClass -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Cabal -> String
cabal_moduleprefix(Cabal -> String)
-> (TemplateClass -> Cabal) -> TemplateClass -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateClass -> Cabal
tclass_cabal) (TemplateClass -> String -> String)
-> (TemplateClass -> String) -> TemplateClass -> String
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((String, String) -> String
forall a b. (a, b) -> a
fst((String, String) -> String)
-> (TemplateClass -> (String, String)) -> TemplateClass -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateClass -> (String, String)
hsTemplateClassName)


-- | Daughter map not including itself
mkDaughterMap :: [Class] -> DaughterMap
mkDaughterMap :: [Class] -> DaughterMap
mkDaughterMap = (DaughterMap -> Class -> DaughterMap)
-> DaughterMap -> [Class] -> DaughterMap
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl DaughterMap -> Class -> DaughterMap
mkDaughterMapWorker DaughterMap
forall k a. Map k a
M.empty
  where mkDaughterMapWorker :: DaughterMap -> Class -> DaughterMap
mkDaughterMapWorker DaughterMap
m Class
c = let ps :: [String]
ps = (Class -> String) -> [Class] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Class -> String
getClassModuleBase (Class -> [Class]
class_allparents Class
c)
                                  in  (DaughterMap -> String -> DaughterMap)
-> DaughterMap -> [String] -> DaughterMap
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Class -> DaughterMap -> String -> DaughterMap
forall k a. Ord k => a -> Map k [a] -> k -> Map k [a]
addmeToYourDaughterList Class
c) DaughterMap
m [String]
ps
        addmeToYourDaughterList :: a -> Map k [a] -> k -> Map k [a]
addmeToYourDaughterList a
c Map k [a]
m k
p = let f :: Maybe [a] -> Maybe [a]
f Maybe [a]
Nothing = [a] -> Maybe [a]
forall a. a -> Maybe a
Just [a
c]
                                            f (Just [a]
cs)  = [a] -> Maybe [a]
forall a. a -> Maybe a
Just (a
ca -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
cs)
                                        in  (Maybe [a] -> Maybe [a]) -> k -> Map k [a] -> Map k [a]
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
M.alter Maybe [a] -> Maybe [a]
f k
p Map k [a]
m



-- | Daughter Map including itself as a daughter
mkDaughterSelfMap :: [Class] -> DaughterMap
mkDaughterSelfMap :: [Class] -> DaughterMap
mkDaughterSelfMap = (DaughterMap -> Class -> DaughterMap)
-> DaughterMap -> [Class] -> DaughterMap
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' DaughterMap -> Class -> DaughterMap
worker DaughterMap
forall k a. Map k a
M.empty
  where worker :: DaughterMap -> Class -> DaughterMap
worker DaughterMap
m Class
c = let ps :: [String]
ps = (Class -> String) -> [Class] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Class -> String
getClassModuleBase (Class
cClass -> [Class] -> [Class]
forall a. a -> [a] -> [a]
:Class -> [Class]
class_allparents Class
c)
                     in  (DaughterMap -> String -> DaughterMap)
-> DaughterMap -> [String] -> DaughterMap
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (Class -> DaughterMap -> String -> DaughterMap
forall k a. Ord k => a -> Map k [a] -> k -> Map k [a]
addToList Class
c) DaughterMap
m [String]
ps
        addToList :: a -> Map k [a] -> k -> Map k [a]
addToList a
c Map k [a]
m k
p = let f :: Maybe [a] -> Maybe [a]
f Maybe [a]
Nothing = [a] -> Maybe [a]
forall a. a -> Maybe a
Just [a
c]
                              f (Just [a]
cs)  = [a] -> Maybe [a]
forall a. a -> Maybe a
Just (a
ca -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
cs)
                          in  (Maybe [a] -> Maybe [a]) -> k -> Map k [a] -> Map k [a]
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
M.alter Maybe [a] -> Maybe [a]
f k
p Map k [a]
m



-- | class dependency for a given function
data Dep4Func = Dep4Func { Dep4Func -> [Either TemplateClass Class]
returnDependency :: [Either TemplateClass Class]
                         , Dep4Func -> [Either TemplateClass Class]
argumentDependency :: [Either TemplateClass Class] }


-- |
extractClassDep :: Function -> Dep4Func
extractClassDep :: Function -> Dep4Func
extractClassDep (Constructor [Arg]
args Maybe String
_)  =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func [] ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
args)
extractClassDep (Virtual Types
ret String
_ [Arg]
args Maybe String
_) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
args)
extractClassDep (NonVirtual Types
ret String
_ [Arg]
args Maybe String
_) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
args)
extractClassDep (Static Types
ret String
_ [Arg]
args Maybe String
_) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
args)
extractClassDep (Destructor Maybe String
_) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func [] []

-- |
extractClassDepForTmplFun :: TemplateFunction -> Dep4Func
extractClassDepForTmplFun :: TemplateFunction -> Dep4Func
extractClassDepForTmplFun (TFun Types
ret  String
_ String
_ [Arg]
args) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
args)
extractClassDepForTmplFun (TFunNew [Arg]
args Maybe String
_) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func [] ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
args)
extractClassDepForTmplFun TemplateFunction
TFunDelete =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func [] []
extractClassDepForTmplFun (TFunOp Types
ret  String
_ OpExp
e) =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg ([Arg] -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$ OpExp -> [Arg]
argsFromOpExp OpExp
e)

-- |
extractClassDep4TmplMemberFun :: TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun :: TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun (TemplateMemberFunction {String
[String]
[Arg]
Maybe String
Types
tmf_alias :: TemplateMemberFunction -> Maybe String
tmf_args :: TemplateMemberFunction -> [Arg]
tmf_name :: TemplateMemberFunction -> String
tmf_ret :: TemplateMemberFunction -> Types
tmf_params :: TemplateMemberFunction -> [String]
tmf_alias :: Maybe String
tmf_args :: [Arg]
tmf_name :: String
tmf_ret :: Types
tmf_params :: [String]
..}) =
  [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
tmf_ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Arg -> [Either TemplateClass Class]
classFromArg [Arg]
tmf_args)

-- |
extractClassDepForTopLevel :: TopLevel -> Dep4Func
extractClassDepForTopLevel :: TopLevel -> Dep4Func
extractClassDepForTopLevel TopLevel
f =
    [Either TemplateClass Class]
-> [Either TemplateClass Class] -> Dep4Func
Dep4Func (Types -> [Either TemplateClass Class]
extractClassFromType Types
ret) ((Arg -> [Either TemplateClass Class])
-> [Arg] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Types -> [Either TemplateClass Class]
extractClassFromType (Types -> [Either TemplateClass Class])
-> (Arg -> Types) -> Arg -> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Arg -> Types
arg_type) [Arg]
args)
  where ret :: Types
ret = case TopLevel
f of
                TopLevelFunction {String
[Arg]
Maybe String
Types
toplevelfunc_alias :: TopLevel -> Maybe String
toplevelfunc_args :: TopLevel -> [Arg]
toplevelfunc_name :: TopLevel -> String
toplevelfunc_ret :: TopLevel -> Types
toplevelfunc_alias :: Maybe String
toplevelfunc_args :: [Arg]
toplevelfunc_name :: String
toplevelfunc_ret :: Types
..} -> Types
toplevelfunc_ret
                TopLevelVariable {String
Maybe String
Types
toplevelvar_alias :: TopLevel -> Maybe String
toplevelvar_name :: TopLevel -> String
toplevelvar_ret :: TopLevel -> Types
toplevelvar_alias :: Maybe String
toplevelvar_name :: String
toplevelvar_ret :: Types
..} -> Types
toplevelvar_ret
        args :: [Arg]
args = case TopLevel
f of
                 TopLevelFunction {String
[Arg]
Maybe String
Types
toplevelfunc_alias :: Maybe String
toplevelfunc_args :: [Arg]
toplevelfunc_name :: String
toplevelfunc_ret :: Types
toplevelfunc_alias :: TopLevel -> Maybe String
toplevelfunc_args :: TopLevel -> [Arg]
toplevelfunc_name :: TopLevel -> String
toplevelfunc_ret :: TopLevel -> Types
..} -> [Arg]
toplevelfunc_args
                 TopLevelVariable {String
Maybe String
Types
toplevelvar_alias :: Maybe String
toplevelvar_name :: String
toplevelvar_ret :: Types
toplevelvar_alias :: TopLevel -> Maybe String
toplevelvar_name :: TopLevel -> String
toplevelvar_ret :: TopLevel -> Types
..} -> []


-- TODO: Confirm the answer below is correct.
-- NOTE: Q: Why returnDependency only?
--       A: Difference between argument and return:
--          for a member function f,
--          we have (f :: (IA a, IB b) => a -> b -> IO C
--          return class is concrete and argument class is constraint.
mkModuleDepRaw :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepRaw :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepRaw x :: Either TemplateClass Class
x@(Right Class
c) =
  [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
    (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
x) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
         (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency (Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Function -> Dep4Func
extractClassDep) (Class -> [Function]
class_funcs Class
c)
      [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. [a] -> [a] -> [a]
++ (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency (Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) (Class -> [TemplateMemberFunction]
class_tmpl_funcs Class
c)
mkModuleDepRaw x :: Either TemplateClass Class
x@(Left TemplateClass
t) =
  ([Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> (TemplateClass -> [Either TemplateClass Class])
-> TemplateClass
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
x) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> (TemplateClass -> [Either TemplateClass Class])
-> TemplateClass
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateFunction -> Dep4Func
extractClassDepForTmplFun) ([TemplateFunction] -> [Either TemplateClass Class])
-> (TemplateClass -> [TemplateFunction])
-> TemplateClass
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemplateClass -> [TemplateFunction]
tclass_funcs) TemplateClass
t

-- |
isNotInSamePackageWith
  :: Either TemplateClass Class
  -> Either TemplateClass Class
  -> Bool
isNotInSamePackageWith :: Either TemplateClass Class -> Either TemplateClass Class -> Bool
isNotInSamePackageWith Either TemplateClass Class
x Either TemplateClass Class
y = (Either TemplateClass Class
x Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
y) Bool -> Bool -> Bool
&& (Either TemplateClass Class -> CabalName
getPkgName Either TemplateClass Class
x CabalName -> CabalName -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class -> CabalName
getPkgName Either TemplateClass Class
y)

-- x is in the sam
isInSamePackageButNotInheritedBy
  :: Either TemplateClass Class -- ^ y
  -> Either TemplateClass Class -- ^ x
  -> Bool
isInSamePackageButNotInheritedBy :: Either TemplateClass Class -> Either TemplateClass Class -> Bool
isInSamePackageButNotInheritedBy Either TemplateClass Class
x Either TemplateClass Class
y =
  Either TemplateClass Class
x Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
y Bool -> Bool -> Bool
&& Bool -> Bool
not (Either TemplateClass Class
x Either TemplateClass Class -> [Either TemplateClass Class] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Either TemplateClass Class -> [Either TemplateClass Class]
forall b a. Either b Class -> [Either a Class]
getparents Either TemplateClass Class
y) Bool -> Bool -> Bool
&& (Either TemplateClass Class -> CabalName
getPkgName Either TemplateClass Class
x CabalName -> CabalName -> Bool
forall a. Eq a => a -> a -> Bool
== Either TemplateClass Class -> CabalName
getPkgName Either TemplateClass Class
y)

-- TODO: Confirm the following answer
-- NOTE: Q: why returnDependency is not considered?
--       A: See explanation in mkModuleDepRaw
mkModuleDepHighNonSource :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepHighNonSource :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepHighNonSource y :: Either TemplateClass Class
y@(Right Class
c) =
  let extclasses :: [Either TemplateClass Class]
extclasses = (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
`isNotInSamePackageWith` Either TemplateClass Class
y) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
                        (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Function -> Dep4Func
extractClassDep) (Class -> [Function]
class_funcs Class
c)
                     [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. [a] -> [a] -> [a]
++ (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) (Class -> [TemplateMemberFunction]
class_tmpl_funcs Class
c)
      parents :: [Either a Class]
parents = (Class -> Either a Class) -> [Class] -> [Either a Class]
forall a b. (a -> b) -> [a] -> [b]
map Class -> Either a Class
forall a b. b -> Either a b
Right (Class -> [Class]
class_parents Class
c)
  in  [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class]
forall a. [Either a Class]
parents [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> [Either TemplateClass Class]
extclasses)
mkModuleDepHighNonSource y :: Either TemplateClass Class
y@(Left TemplateClass
t) =
  let fs :: [TemplateFunction]
fs = TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t
      extclasses :: [Either TemplateClass Class]
extclasses = (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
`isNotInSamePackageWith` Either TemplateClass Class
y) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
                     (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateFunction -> Dep4Func
extractClassDepForTmplFun) [TemplateFunction]
fs
  in  [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub [Either TemplateClass Class]
extclasses

-- TODO: Confirm the following answer
-- NOTE: Q: why returnDependency is not considered?
--       A: See explanation in mkModuleDepRaw
mkModuleDepHighSource :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepHighSource :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepHighSource y :: Either TemplateClass Class
y@(Right Class
c) =
  [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
    (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
`isInSamePackageButNotInheritedBy` Either TemplateClass Class
y) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
         (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency (Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Function -> Dep4Func
extractClassDep) (Class -> [Function]
class_funcs Class
c)
      [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. [a] -> [a] -> [a]
++ (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency (Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) (Class -> [TemplateMemberFunction]
class_tmpl_funcs Class
c)
mkModuleDepHighSource y :: Either TemplateClass Class
y@(Left TemplateClass
t) =
  let fs :: [TemplateFunction]
fs = TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t
  in [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
       (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
`isInSamePackageButNotInheritedBy` Either TemplateClass Class
y) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
         (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency (Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TemplateFunction -> Dep4Func
extractClassDepForTmplFun) [TemplateFunction]
fs

-- |
mkModuleDepCpp :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepCpp :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepCpp y :: Either TemplateClass Class
y@(Right Class
c) =
  let fs :: [Function]
fs = Class -> [Function]
class_funcs Class
c
      vs :: [Variable]
vs = Class -> [Variable]
class_vars Class
c
      tmfs :: [TemplateMemberFunction]
tmfs = Class -> [TemplateMemberFunction]
class_tmpl_funcs Class
c
  in  [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class]
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
y)  ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
           (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Function -> Dep4Func
extractClassDep) [Function]
fs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Function -> Dep4Func
extractClassDep) [Function]
fs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (Variable -> [Either TemplateClass Class])
-> [Variable] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Arg -> [Either TemplateClass Class]
classFromArg (Arg -> [Either TemplateClass Class])
-> (Variable -> Arg) -> Variable -> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Variable -> Arg
unVariable) [Variable]
vs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) [TemplateMemberFunction]
tmfs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) [TemplateMemberFunction]
tmfs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> Either TemplateClass Class -> [Either TemplateClass Class]
forall b a. Either b Class -> [Either a Class]
getparents Either TemplateClass Class
y
mkModuleDepCpp y :: Either TemplateClass Class
y@(Left TemplateClass
t) =
  let fs :: [TemplateFunction]
fs = TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t
  in  [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class]
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
y)  ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$
           (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateFunction -> Dep4Func
extractClassDepForTmplFun) [TemplateFunction]
fs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateFunction -> Dep4Func
extractClassDepForTmplFun) [TemplateFunction]
fs
        [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> Either TemplateClass Class -> [Either TemplateClass Class]
forall b a. Either b Class -> [Either a Class]
getparents Either TemplateClass Class
y

-- |
mkModuleDepFFI1 :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI1 :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI1 (Right Class
c) = let fs :: [Function]
fs = Class -> [Function]
class_funcs Class
c
                                vs :: [Variable]
vs = Class -> [Variable]
class_vars Class
c
                                tmfs :: [TemplateMemberFunction]
tmfs = Class -> [TemplateMemberFunction]
class_tmpl_funcs Class
c
                            in    (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Function -> Dep4Func
extractClassDep) [Function]
fs
                               [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (Function -> [Either TemplateClass Class])
-> [Function] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (Function -> Dep4Func)
-> Function
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Function -> Dep4Func
extractClassDep) [Function]
fs
                               [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (Variable -> [Either TemplateClass Class])
-> [Variable] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Arg -> [Either TemplateClass Class]
classFromArg (Arg -> [Either TemplateClass Class])
-> (Variable -> Arg) -> Variable -> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Variable -> Arg
unVariable) [Variable]
vs
                               [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) [TemplateMemberFunction]
tmfs
                               [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (TemplateMemberFunction -> [Either TemplateClass Class])
-> [TemplateMemberFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateMemberFunction -> Dep4Func)
-> TemplateMemberFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateMemberFunction -> Dep4Func
extractClassDep4TmplMemberFun) [TemplateMemberFunction]
tmfs
mkModuleDepFFI1 (Left TemplateClass
t)  = let fs :: [TemplateFunction]
fs = TemplateClass -> [TemplateFunction]
tclass_funcs TemplateClass
t
                            in    (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateFunction -> Dep4Func
extractClassDepForTmplFun) [TemplateFunction]
fs
                               [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> (TemplateFunction -> [Either TemplateClass Class])
-> [TemplateFunction] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency(Dep4Func -> [Either TemplateClass Class])
-> (TemplateFunction -> Dep4Func)
-> TemplateFunction
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TemplateFunction -> Dep4Func
extractClassDepForTmplFun) [TemplateFunction]
fs

-- |
mkModuleDepFFI :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI :: Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI y :: Either TemplateClass Class
y@(Right Class
c) =
  let ps :: [Either a Class]
ps = (Class -> Either a Class) -> [Class] -> [Either a Class]
forall a b. (a -> b) -> [a] -> [b]
map Class -> Either a Class
forall a b. b -> Either a b
Right (Class -> [Class]
class_allparents Class
c)
      alldeps' :: [Either TemplateClass Class]
alldeps' = ((Either TemplateClass Class -> [Either TemplateClass Class])
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI1 [Either TemplateClass Class]
forall a. [Either a Class]
ps) [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI1 Either TemplateClass Class
y
  in [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Eq a => [a] -> [a]
nub ((Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter (Either TemplateClass Class -> Either TemplateClass Class -> Bool
forall a. Eq a => a -> a -> Bool
/= Either TemplateClass Class
y) [Either TemplateClass Class]
alldeps')
mkModuleDepFFI (Left TemplateClass
_) = []

-- |
mkClassModule :: (ModuleUnit -> ModuleUnitImports)
              -> [(String,[String])]
              -> Class
              -> ClassModule
mkClassModule :: (ModuleUnit -> ModuleUnitImports)
-> [(String, [String])] -> Class -> ClassModule
mkClassModule ModuleUnit -> ModuleUnitImports
getImports [(String, [String])]
extra Class
c =
    ClassModule :: String
-> ClassImportHeader
-> [Either TemplateClass Class]
-> [Either TemplateClass Class]
-> [Either TemplateClass Class]
-> [Either TemplateClass Class]
-> [String]
-> ClassModule
ClassModule {
      cmModule :: String
cmModule = Class -> String
getClassModuleBase Class
c
    , cmCIH :: ClassImportHeader
cmCIH = (ModuleUnit -> ModuleUnitImports) -> Class -> ClassImportHeader
mkCIH ModuleUnit -> ModuleUnitImports
getImports Class
c
    , cmImportedModulesHighNonSource :: [Either TemplateClass Class]
cmImportedModulesHighNonSource = [Either TemplateClass Class]
highs_nonsource
    , cmImportedModulesRaw :: [Either TemplateClass Class]
cmImportedModulesRaw =[Either TemplateClass Class]
raws
    , cmImportedModulesHighSource :: [Either TemplateClass Class]
cmImportedModulesHighSource = [Either TemplateClass Class]
highs_source
    , cmImportedModulesForFFI :: [Either TemplateClass Class]
cmImportedModulesForFFI = [Either TemplateClass Class]
ffis
    , cmExtraImport :: [String]
cmExtraImport = [String]
extraimports
    }
  where highs_nonsource :: [Either TemplateClass Class]
highs_nonsource = Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepHighNonSource (Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c)
        raws :: [Either TemplateClass Class]
raws            = Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepRaw (Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c)
        highs_source :: [Either TemplateClass Class]
highs_source    = Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepHighSource (Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c)
        ffis :: [Either TemplateClass Class]
ffis            = Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepFFI (Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c)
        extraimports :: [String]
extraimports = [String] -> Maybe [String] -> [String]
forall a. a -> Maybe a -> a
fromMaybe [] (String -> [(String, [String])] -> Maybe [String]
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (Class -> String
class_name Class
c) [(String, [String])]
extra)

-- |
findModuleUnitImports :: ModuleUnitMap -> ModuleUnit -> ModuleUnitImports
findModuleUnitImports :: ModuleUnitMap -> ModuleUnit -> ModuleUnitImports
findModuleUnitImports ModuleUnitMap
m ModuleUnit
u =
  ModuleUnitImports -> Maybe ModuleUnitImports -> ModuleUnitImports
forall a. a -> Maybe a -> a
fromMaybe ModuleUnitImports
emptyModuleUnitImports (ModuleUnit
-> HashMap ModuleUnit ModuleUnitImports -> Maybe ModuleUnitImports
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
HM.lookup ModuleUnit
u (ModuleUnitMap -> HashMap ModuleUnit ModuleUnitImports
unModuleUnitMap ModuleUnitMap
m))

-- |
mkTCM ::
     TemplateClassImportHeader
  -> TemplateClassModule
mkTCM :: TemplateClassImportHeader -> TemplateClassModule
mkTCM TemplateClassImportHeader
tcih =
  let t :: TemplateClass
t = TemplateClassImportHeader -> TemplateClass
tcihTClass TemplateClassImportHeader
tcih
  in String -> TemplateClassImportHeader -> TemplateClassModule
TCM (TemplateClass -> String
getTClassModuleBase TemplateClass
t) TemplateClassImportHeader
tcih

-- |
mkPackageConfig
  :: (CabalName, ModuleUnit -> ModuleUnitImports) -- ^ (package name,getImports)
  -> ([Class],[TopLevel],[TemplateClassImportHeader],[(String,[String])])
  -> [AddCInc]
  -> [AddCSrc]
  -> PackageConfig
mkPackageConfig :: (CabalName, ModuleUnit -> ModuleUnitImports)
-> ([Class], [TopLevel], [TemplateClassImportHeader],
    [(String, [String])])
-> [AddCInc]
-> [AddCSrc]
-> PackageConfig
mkPackageConfig (CabalName
pkgname,ModuleUnit -> ModuleUnitImports
getImports) ([Class]
cs,[TopLevel]
fs,[TemplateClassImportHeader]
ts,[(String, [String])]
extra) [AddCInc]
acincs [AddCSrc]
acsrcs =
  let ms :: [ClassModule]
ms = (Class -> ClassModule) -> [Class] -> [ClassModule]
forall a b. (a -> b) -> [a] -> [b]
map ((ModuleUnit -> ModuleUnitImports)
-> [(String, [String])] -> Class -> ClassModule
mkClassModule ModuleUnit -> ModuleUnitImports
getImports [(String, [String])]
extra) [Class]
cs
      cmpfunc :: ClassImportHeader -> ClassImportHeader -> Bool
cmpfunc ClassImportHeader
x ClassImportHeader
y = Class -> String
class_name (ClassImportHeader -> Class
cihClass ClassImportHeader
x) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== Class -> String
class_name (ClassImportHeader -> Class
cihClass ClassImportHeader
y)
      cihs :: [ClassImportHeader]
cihs = (ClassImportHeader -> ClassImportHeader -> Bool)
-> [ClassImportHeader] -> [ClassImportHeader]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy ClassImportHeader -> ClassImportHeader -> Bool
cmpfunc ((ClassModule -> ClassImportHeader)
-> [ClassModule] -> [ClassImportHeader]
forall a b. (a -> b) -> [a] -> [b]
map ClassModule -> ClassImportHeader
cmCIH [ClassModule]
ms)
      --
      tih :: TopLevelImportHeader
tih = CabalName
-> (ModuleUnit -> ModuleUnitImports)
-> [ClassImportHeader]
-> [TopLevel]
-> TopLevelImportHeader
mkTIH CabalName
pkgname ModuleUnit -> ModuleUnitImports
getImports [ClassImportHeader]
cihs [TopLevel]
fs
      tcms :: [TemplateClassModule]
tcms = (TemplateClassImportHeader -> TemplateClassModule)
-> [TemplateClassImportHeader] -> [TemplateClassModule]
forall a b. (a -> b) -> [a] -> [b]
map TemplateClassImportHeader -> TemplateClassModule
mkTCM [TemplateClassImportHeader]
ts
      tcihs :: [TemplateClassImportHeader]
tcihs = (TemplateClassModule -> TemplateClassImportHeader)
-> [TemplateClassModule] -> [TemplateClassImportHeader]
forall a b. (a -> b) -> [a] -> [b]
map TemplateClassModule -> TemplateClassImportHeader
tcmTCIH [TemplateClassModule]
tcms
  in PkgConfig :: [ClassModule]
-> [ClassImportHeader]
-> TopLevelImportHeader
-> [TemplateClassModule]
-> [TemplateClassImportHeader]
-> [AddCInc]
-> [AddCSrc]
-> PackageConfig
PkgConfig {
       pcfg_classModules :: [ClassModule]
pcfg_classModules = [ClassModule]
ms
     , pcfg_classImportHeaders :: [ClassImportHeader]
pcfg_classImportHeaders = [ClassImportHeader]
cihs
     , pcfg_topLevelImportHeader :: TopLevelImportHeader
pcfg_topLevelImportHeader = TopLevelImportHeader
tih
     , pcfg_templateClassModules :: [TemplateClassModule]
pcfg_templateClassModules = [TemplateClassModule]
tcms
     , pcfg_templateClassImportHeaders :: [TemplateClassImportHeader]
pcfg_templateClassImportHeaders = [TemplateClassImportHeader]
tcihs
     , pcfg_additional_c_incs :: [AddCInc]
pcfg_additional_c_incs = [AddCInc]
acincs
     , pcfg_additional_c_srcs :: [AddCSrc]
pcfg_additional_c_srcs = [AddCSrc]
acsrcs
     }

-- TODO: change [String] to Set String
mkHSBOOTCandidateList :: [ClassModule] -> [String]
mkHSBOOTCandidateList :: [ClassModule] -> [String]
mkHSBOOTCandidateList [ClassModule]
ms =
  let
    -- get only class dependencies, not template classes.
    cs :: [Class]
cs = [Either TemplateClass Class] -> [Class]
forall a b. [Either a b] -> [b]
rights ((ClassModule -> [Either TemplateClass Class])
-> [ClassModule] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ClassModule -> [Either TemplateClass Class]
cmImportedModulesHighSource [ClassModule]
ms)
  in
    [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ((Class -> String) -> [Class] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Class -> String
getClassModuleBase [Class]
cs)

-- |
mkPkgHeaderFileName ::Class -> HeaderName
mkPkgHeaderFileName :: Class -> HeaderName
mkPkgHeaderFileName Class
c =
    String -> HeaderName
HdrName (   (Cabal -> String
cabal_cheaderprefix(Cabal -> String) -> (Class -> Cabal) -> Class -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Class -> Cabal
class_cabal) Class
c
            String -> String -> String
forall a. Semigroup a => a -> a -> a
<>  (String, String) -> String
forall a b. (a, b) -> a
fst (Class -> (String, String)
hsClassName Class
c)
            String -> String -> String
<.> String
"h"
            )

-- |
mkPkgCppFileName ::Class -> String
mkPkgCppFileName :: Class -> String
mkPkgCppFileName Class
c =
        (Cabal -> String
cabal_cheaderprefix(Cabal -> String) -> (Class -> Cabal) -> Class -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Class -> Cabal
class_cabal) Class
c
    String -> String -> String
forall a. Semigroup a => a -> a -> a
<>  (String, String) -> String
forall a b. (a, b) -> a
fst (Class -> (String, String)
hsClassName Class
c)
    String -> String -> String
<.> String
"cpp"

-- |
mkPkgIncludeHeadersInH :: Class -> [HeaderName]
mkPkgIncludeHeadersInH :: Class -> [HeaderName]
mkPkgIncludeHeadersInH Class
c =
    let pkgname :: CabalName
pkgname = (Cabal -> CabalName
cabal_pkgname (Cabal -> CabalName) -> (Class -> Cabal) -> Class -> CabalName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> Cabal
class_cabal) Class
c
        extclasses :: [Either TemplateClass Class]
extclasses = (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter ((CabalName -> CabalName -> Bool
forall a. Eq a => a -> a -> Bool
/= CabalName
pkgname) (CabalName -> Bool)
-> (Either TemplateClass Class -> CabalName)
-> Either TemplateClass Class
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> CabalName
getPkgName) ([Either TemplateClass Class] -> [Either TemplateClass Class])
-> (Either TemplateClass Class -> [Either TemplateClass Class])
-> Either TemplateClass Class
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepCpp (Either TemplateClass Class -> [Either TemplateClass Class])
-> Either TemplateClass Class -> [Either TemplateClass Class]
forall a b. (a -> b) -> a -> b
$ Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c
        extheaders :: [String]
extheaders = [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String])
-> ([Either TemplateClass Class] -> [String])
-> [Either TemplateClass Class]
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Either TemplateClass Class -> String)
-> [Either TemplateClass Class] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> String -> String
forall a. Semigroup a => a -> a -> a
<>String
"Type.h") (String -> String)
-> (Either TemplateClass Class -> String)
-> Either TemplateClass Class
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CabalName -> String
unCabalName (CabalName -> String)
-> (Either TemplateClass Class -> CabalName)
-> Either TemplateClass Class
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> CabalName
getPkgName) ([Either TemplateClass Class] -> [String])
-> [Either TemplateClass Class] -> [String]
forall a b. (a -> b) -> a -> b
$ [Either TemplateClass Class]
extclasses
    in (Class -> HeaderName) -> [Class] -> [HeaderName]
forall a b. (a -> b) -> [a] -> [b]
map Class -> HeaderName
mkPkgHeaderFileName (Class -> [Class]
class_allparents Class
c) [HeaderName] -> [HeaderName] -> [HeaderName]
forall a. Semigroup a => a -> a -> a
<> (String -> HeaderName) -> [String] -> [HeaderName]
forall a b. (a -> b) -> [a] -> [b]
map String -> HeaderName
HdrName [String]
extheaders

-- |
mkPkgIncludeHeadersInCPP :: Class -> [HeaderName]
mkPkgIncludeHeadersInCPP :: Class -> [HeaderName]
mkPkgIncludeHeadersInCPP = (Class -> HeaderName) -> [Class] -> [HeaderName]
forall a b. (a -> b) -> [a] -> [b]
map Class -> HeaderName
mkPkgHeaderFileName ([Class] -> [HeaderName])
-> (Class -> [Class]) -> Class -> [HeaderName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Either TemplateClass Class] -> [Class]
forall a b. [Either a b] -> [b]
rights ([Either TemplateClass Class] -> [Class])
-> (Class -> [Either TemplateClass Class]) -> Class -> [Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepCpp (Either TemplateClass Class -> [Either TemplateClass Class])
-> (Class -> Either TemplateClass Class)
-> Class
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right

-- |
mkCIH :: (ModuleUnit -> ModuleUnitImports)  -- ^ (mk namespace and include headers)
      -> Class
      -> ClassImportHeader
mkCIH :: (ModuleUnit -> ModuleUnitImports) -> Class -> ClassImportHeader
mkCIH ModuleUnit -> ModuleUnitImports
getImports Class
c =
  ClassImportHeader :: Class
-> HeaderName
-> [Namespace]
-> String
-> [Either TemplateClass Class]
-> [HeaderName]
-> [HeaderName]
-> [HeaderName]
-> ClassImportHeader
ClassImportHeader {
    cihClass :: Class
cihClass                    = Class
c
  , cihSelfHeader :: HeaderName
cihSelfHeader               = Class -> HeaderName
mkPkgHeaderFileName Class
c
  , cihNamespace :: [Namespace]
cihNamespace                = (ModuleUnitImports -> [Namespace]
muimports_namespaces (ModuleUnitImports -> [Namespace])
-> (Class -> ModuleUnitImports) -> Class -> [Namespace]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModuleUnit -> ModuleUnitImports
getImports (ModuleUnit -> ModuleUnitImports)
-> (Class -> ModuleUnit) -> Class -> ModuleUnitImports
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ModuleUnit
MU_Class (String -> ModuleUnit) -> (Class -> String) -> Class -> ModuleUnit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> String
class_name) Class
c
  , cihSelfCpp :: String
cihSelfCpp                  = Class -> String
mkPkgCppFileName Class
c
  , cihImportedClasses :: [Either TemplateClass Class]
cihImportedClasses          = Either TemplateClass Class -> [Either TemplateClass Class]
mkModuleDepCpp (Class -> Either TemplateClass Class
forall a b. b -> Either a b
Right Class
c)
  , cihIncludedHPkgHeadersInH :: [HeaderName]
cihIncludedHPkgHeadersInH   = Class -> [HeaderName]
mkPkgIncludeHeadersInH Class
c
  , cihIncludedHPkgHeadersInCPP :: [HeaderName]
cihIncludedHPkgHeadersInCPP = Class -> [HeaderName]
mkPkgIncludeHeadersInCPP Class
c
  , cihIncludedCPkgHeaders :: [HeaderName]
cihIncludedCPkgHeaders      = (ModuleUnitImports -> [HeaderName]
muimports_headers (ModuleUnitImports -> [HeaderName])
-> (Class -> ModuleUnitImports) -> Class -> [HeaderName]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModuleUnit -> ModuleUnitImports
getImports (ModuleUnit -> ModuleUnitImports)
-> (Class -> ModuleUnit) -> Class -> ModuleUnitImports
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ModuleUnit
MU_Class (String -> ModuleUnit) -> (Class -> String) -> Class -> ModuleUnit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Class -> String
class_name) Class
c
  }

-- | for top-level
mkTIH
  :: CabalName
  -> (ModuleUnit -> ModuleUnitImports)
  -> [ClassImportHeader]
  -> [TopLevel]
  -> TopLevelImportHeader
mkTIH :: CabalName
-> (ModuleUnit -> ModuleUnitImports)
-> [ClassImportHeader]
-> [TopLevel]
-> TopLevelImportHeader
mkTIH CabalName
pkgname ModuleUnit -> ModuleUnitImports
getImports [ClassImportHeader]
cihs [TopLevel]
fs =
  let tl_cs1 :: [Either TemplateClass Class]
tl_cs1 = (TopLevel -> [Either TemplateClass Class])
-> [TopLevel] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
argumentDependency (Dep4Func -> [Either TemplateClass Class])
-> (TopLevel -> Dep4Func)
-> TopLevel
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TopLevel -> Dep4Func
extractClassDepForTopLevel) [TopLevel]
fs
      tl_cs2 :: [Either TemplateClass Class]
tl_cs2 = (TopLevel -> [Either TemplateClass Class])
-> [TopLevel] -> [Either TemplateClass Class]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Dep4Func -> [Either TemplateClass Class]
returnDependency (Dep4Func -> [Either TemplateClass Class])
-> (TopLevel -> Dep4Func)
-> TopLevel
-> [Either TemplateClass Class]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TopLevel -> Dep4Func
extractClassDepForTopLevel) [TopLevel]
fs
      tl_cs :: [Either TemplateClass Class]
tl_cs = (Either TemplateClass Class -> Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==) (String -> String -> Bool)
-> (Either TemplateClass Class -> String)
-> Either TemplateClass Class
-> Either TemplateClass Class
-> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (TemplateClass -> String)
-> (Class -> String) -> Either TemplateClass Class -> String
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either TemplateClass -> String
tclass_name Class -> String
ffiClassName) ([Either TemplateClass Class]
tl_cs1 [Either TemplateClass Class]
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. Semigroup a => a -> a -> a
<> [Either TemplateClass Class]
tl_cs2)
      -- NOTE: Select only class dependencies in the current package.
      -- TODO: This is clearly not a good impl. we need to look into this again
      --       after reconsidering multi-package generation.
      tl_cihs :: [ClassImportHeader]
tl_cihs = [Maybe ClassImportHeader] -> [ClassImportHeader]
forall a. [Maybe a] -> [a]
catMaybes ((Either TemplateClass Class
 -> [Maybe ClassImportHeader] -> [Maybe ClassImportHeader])
-> [Maybe ClassImportHeader]
-> [Either TemplateClass Class]
-> [Maybe ClassImportHeader]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Either TemplateClass Class
-> [Maybe ClassImportHeader] -> [Maybe ClassImportHeader]
fn [] [Either TemplateClass Class]
tl_cs)
         where
           fn :: Either TemplateClass Class
-> [Maybe ClassImportHeader] -> [Maybe ClassImportHeader]
fn Either TemplateClass Class
c [Maybe ClassImportHeader]
ys =
             let y :: Maybe ClassImportHeader
y = (ClassImportHeader -> Bool)
-> [ClassImportHeader] -> Maybe ClassImportHeader
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (\ClassImportHeader
x -> (Class -> String
ffiClassName (Class -> String)
-> (ClassImportHeader -> Class) -> ClassImportHeader -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ClassImportHeader -> Class
cihClass) ClassImportHeader
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== Either TemplateClass Class -> String
getFFIName Either TemplateClass Class
c) [ClassImportHeader]
cihs
             in Maybe ClassImportHeader
yMaybe ClassImportHeader
-> [Maybe ClassImportHeader] -> [Maybe ClassImportHeader]
forall a. a -> [a] -> [a]
:[Maybe ClassImportHeader]
ys
      -- NOTE: The remaining class dependencies outside the current package
      extclasses :: [Either TemplateClass Class]
extclasses = (Either TemplateClass Class -> Bool)
-> [Either TemplateClass Class] -> [Either TemplateClass Class]
forall a. (a -> Bool) -> [a] -> [a]
filter ((CabalName -> CabalName -> Bool
forall a. Eq a => a -> a -> Bool
/= CabalName
pkgname) (CabalName -> Bool)
-> (Either TemplateClass Class -> CabalName)
-> Either TemplateClass Class
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> CabalName
getPkgName) [Either TemplateClass Class]
tl_cs
      extheaders :: [HeaderName]
extheaders = (String -> HeaderName) -> [String] -> [HeaderName]
forall a b. (a -> b) -> [a] -> [b]
map String -> HeaderName
HdrName ([String] -> [HeaderName]) -> [String] -> [HeaderName]
forall a b. (a -> b) -> a -> b
$
                     [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$
                       (Either TemplateClass Class -> String)
-> [Either TemplateClass Class] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> String -> String
forall a. Semigroup a => a -> a -> a
<>String
"Type.h") (String -> String)
-> (Either TemplateClass Class -> String)
-> Either TemplateClass Class
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CabalName -> String
unCabalName (CabalName -> String)
-> (Either TemplateClass Class -> CabalName)
-> Either TemplateClass Class
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Either TemplateClass Class -> CabalName
getPkgName)  [Either TemplateClass Class]
extclasses

  in
     TopLevelImportHeader :: String
-> [ClassImportHeader]
-> [Either TemplateClass Class]
-> [TopLevel]
-> [Namespace]
-> [HeaderName]
-> [HeaderName]
-> TopLevelImportHeader
TopLevelImportHeader {
       tihHeaderFileName :: String
tihHeaderFileName = CabalName -> String
unCabalName CabalName
pkgname String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"TopLevel"
     , tihClassDep :: [ClassImportHeader]
tihClassDep = [ClassImportHeader]
tl_cihs
     , tihExtraClassDep :: [Either TemplateClass Class]
tihExtraClassDep = [Either TemplateClass Class]
extclasses
     , tihFuncs :: [TopLevel]
tihFuncs = [TopLevel]
fs
     , tihNamespaces :: [Namespace]
tihNamespaces        = ModuleUnitImports -> [Namespace]
muimports_namespaces (ModuleUnit -> ModuleUnitImports
getImports ModuleUnit
MU_TopLevel)
     , tihExtraHeadersInH :: [HeaderName]
tihExtraHeadersInH   = [HeaderName]
extheaders
     , tihExtraHeadersInCPP :: [HeaderName]
tihExtraHeadersInCPP = ModuleUnitImports -> [HeaderName]
muimports_headers (ModuleUnit -> ModuleUnitImports
getImports ModuleUnit
MU_TopLevel)
     }