{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric      #-}

module Distribution.Types.Library (
    Library(..),
    emptyLibrary,
    explicitLibModules,
    libModulesAutogen,
) where

import Distribution.Compat.Prelude
import Prelude ()

import Distribution.ModuleName
import Distribution.Types.BuildInfo
import Distribution.Types.LibraryVisibility
import Distribution.Types.ModuleReexport
import Distribution.Types.LibraryName

import qualified Distribution.Types.BuildInfo.Lens as L

data Library = Library
    { Library -> LibraryName
libName           :: LibraryName
    , Library -> [ModuleName]
exposedModules    :: [ModuleName]
    , Library -> [ModuleReexport]
reexportedModules :: [ModuleReexport]
    , Library -> [ModuleName]
signatures        :: [ModuleName]       -- ^ What sigs need implementations?
    , Library -> Bool
libExposed        :: Bool               -- ^ Is the lib to be exposed by default? (i.e. whether its modules available in GHCi for example)
    , Library -> LibraryVisibility
libVisibility     :: LibraryVisibility  -- ^ Whether this multilib can be dependent from outside.
    , Library -> BuildInfo
libBuildInfo      :: BuildInfo
    }
    deriving ((forall x. Library -> Rep Library x)
-> (forall x. Rep Library x -> Library) -> Generic Library
forall x. Rep Library x -> Library
forall x. Library -> Rep Library x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Library -> Rep Library x
from :: forall x. Library -> Rep Library x
$cto :: forall x. Rep Library x -> Library
to :: forall x. Rep Library x -> Library
Generic, Int -> Library -> ShowS
[Library] -> ShowS
Library -> String
(Int -> Library -> ShowS)
-> (Library -> String) -> ([Library] -> ShowS) -> Show Library
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Library -> ShowS
showsPrec :: Int -> Library -> ShowS
$cshow :: Library -> String
show :: Library -> String
$cshowList :: [Library] -> ShowS
showList :: [Library] -> ShowS
Show, Library -> Library -> Bool
(Library -> Library -> Bool)
-> (Library -> Library -> Bool) -> Eq Library
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Library -> Library -> Bool
== :: Library -> Library -> Bool
$c/= :: Library -> Library -> Bool
/= :: Library -> Library -> Bool
Eq, Eq Library
Eq Library =>
(Library -> Library -> Ordering)
-> (Library -> Library -> Bool)
-> (Library -> Library -> Bool)
-> (Library -> Library -> Bool)
-> (Library -> Library -> Bool)
-> (Library -> Library -> Library)
-> (Library -> Library -> Library)
-> Ord Library
Library -> Library -> Bool
Library -> Library -> Ordering
Library -> Library -> Library
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Library -> Library -> Ordering
compare :: Library -> Library -> Ordering
$c< :: Library -> Library -> Bool
< :: Library -> Library -> Bool
$c<= :: Library -> Library -> Bool
<= :: Library -> Library -> Bool
$c> :: Library -> Library -> Bool
> :: Library -> Library -> Bool
$c>= :: Library -> Library -> Bool
>= :: Library -> Library -> Bool
$cmax :: Library -> Library -> Library
max :: Library -> Library -> Library
$cmin :: Library -> Library -> Library
min :: Library -> Library -> Library
Ord, ReadPrec [Library]
ReadPrec Library
Int -> ReadS Library
ReadS [Library]
(Int -> ReadS Library)
-> ReadS [Library]
-> ReadPrec Library
-> ReadPrec [Library]
-> Read Library
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Library
readsPrec :: Int -> ReadS Library
$creadList :: ReadS [Library]
readList :: ReadS [Library]
$creadPrec :: ReadPrec Library
readPrec :: ReadPrec Library
$creadListPrec :: ReadPrec [Library]
readListPrec :: ReadPrec [Library]
Read, Typeable, Typeable Library
Typeable Library =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Library -> c Library)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Library)
-> (Library -> Constr)
-> (Library -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Library))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Library))
-> ((forall b. Data b => b -> b) -> Library -> Library)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Library -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Library -> r)
-> (forall u. (forall d. Data d => d -> u) -> Library -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Library -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Library -> m Library)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Library -> m Library)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Library -> m Library)
-> Data Library
Library -> Constr
Library -> DataType
(forall b. Data b => b -> b) -> Library -> Library
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Library -> u
forall u. (forall d. Data d => d -> u) -> Library -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Library -> m Library
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Library -> m Library
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Library
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Library -> c Library
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Library)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Library)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Library -> c Library
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Library -> c Library
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Library
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Library
$ctoConstr :: Library -> Constr
toConstr :: Library -> Constr
$cdataTypeOf :: Library -> DataType
dataTypeOf :: Library -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Library)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Library)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Library)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Library)
$cgmapT :: (forall b. Data b => b -> b) -> Library -> Library
gmapT :: (forall b. Data b => b -> b) -> Library -> Library
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Library -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Library -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Library -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Library -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Library -> m Library
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Library -> m Library
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Library -> m Library
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Library -> m Library
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Library -> m Library
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Library -> m Library
Data)

instance L.HasBuildInfo Library where
    buildInfo :: Lens' Library BuildInfo
buildInfo BuildInfo -> f BuildInfo
f Library
l = (\BuildInfo
x -> Library
l { libBuildInfo = x }) (BuildInfo -> Library) -> f BuildInfo -> f Library
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BuildInfo -> f BuildInfo
f (Library -> BuildInfo
libBuildInfo Library
l)

instance Binary Library
instance Structured Library
instance NFData Library where rnf :: Library -> ()
rnf = Library -> ()
forall a. (Generic a, GNFData (Rep a)) => a -> ()
genericRnf

emptyLibrary :: Library
emptyLibrary :: Library
emptyLibrary = Library
    { libName :: LibraryName
libName           = LibraryName
LMainLibName
    , exposedModules :: [ModuleName]
exposedModules    = [ModuleName]
forall a. Monoid a => a
mempty
    , reexportedModules :: [ModuleReexport]
reexportedModules = [ModuleReexport]
forall a. Monoid a => a
mempty
    , signatures :: [ModuleName]
signatures        = [ModuleName]
forall a. Monoid a => a
mempty
    , libExposed :: Bool
libExposed        = Bool
True
    , libVisibility :: LibraryVisibility
libVisibility     = LibraryVisibility
forall a. Monoid a => a
mempty
    , libBuildInfo :: BuildInfo
libBuildInfo      = BuildInfo
forall a. Monoid a => a
mempty
    }

-- | This instance is not good.
--
-- We need it for 'PackageDescription.Configuration.addBuildableCondition'.
-- More correct method would be some kind of "create empty clone".
--
-- More concretely, 'addBuildableCondition' will make `libVisibility = False`
-- libraries when `buildable: false`. This may cause problems.
--
instance Monoid Library where
    mempty :: Library
mempty = Library
emptyLibrary
    mappend :: Library -> Library -> Library
mappend = Library -> Library -> Library
forall a. Semigroup a => a -> a -> a
(<>)

instance Semigroup Library where
  Library
a <> :: Library -> Library -> Library
<> Library
b = Library
    { libName :: LibraryName
libName           = LibraryName -> LibraryName -> LibraryName
combineLibraryName (Library -> LibraryName
libName Library
a) (Library -> LibraryName
libName Library
b)
    , exposedModules :: [ModuleName]
exposedModules    = (Library -> [ModuleName]) -> [ModuleName]
forall {a}. Monoid a => (Library -> a) -> a
combine Library -> [ModuleName]
exposedModules
    , reexportedModules :: [ModuleReexport]
reexportedModules = (Library -> [ModuleReexport]) -> [ModuleReexport]
forall {a}. Monoid a => (Library -> a) -> a
combine Library -> [ModuleReexport]
reexportedModules
    , signatures :: [ModuleName]
signatures        = (Library -> [ModuleName]) -> [ModuleName]
forall {a}. Monoid a => (Library -> a) -> a
combine Library -> [ModuleName]
signatures
    , libExposed :: Bool
libExposed        = Library -> Bool
libExposed Library
a Bool -> Bool -> Bool
&& Library -> Bool
libExposed Library
b -- so False propagates
    , libVisibility :: LibraryVisibility
libVisibility     = (Library -> LibraryVisibility) -> LibraryVisibility
forall {a}. Monoid a => (Library -> a) -> a
combine Library -> LibraryVisibility
libVisibility
    , libBuildInfo :: BuildInfo
libBuildInfo      = (Library -> BuildInfo) -> BuildInfo
forall {a}. Monoid a => (Library -> a) -> a
combine Library -> BuildInfo
libBuildInfo
    }
    where combine :: (Library -> a) -> a
combine Library -> a
field = Library -> a
field Library
a a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` Library -> a
field Library
b

-- | Get all the module names from the library (exposed and internal modules)
-- which are explicitly listed in the package description which would
-- need to be compiled.  (This does not include reexports, which
-- do not need to be compiled.)  This may not include all modules for which
-- GHC generated interface files (i.e., implicit modules.)
explicitLibModules :: Library -> [ModuleName]
explicitLibModules :: Library -> [ModuleName]
explicitLibModules Library
lib = Library -> [ModuleName]
exposedModules Library
lib
              [ModuleName] -> [ModuleName] -> [ModuleName]
forall a. [a] -> [a] -> [a]
++ BuildInfo -> [ModuleName]
otherModules (Library -> BuildInfo
libBuildInfo Library
lib)
              [ModuleName] -> [ModuleName] -> [ModuleName]
forall a. [a] -> [a] -> [a]
++ Library -> [ModuleName]
signatures Library
lib

-- | Get all the auto generated module names from the library, exposed or not.
-- This are a subset of 'libModules'.
libModulesAutogen :: Library -> [ModuleName]
libModulesAutogen :: Library -> [ModuleName]
libModulesAutogen Library
lib = BuildInfo -> [ModuleName]
autogenModules (Library -> BuildInfo
libBuildInfo Library
lib)

-- | Combine 'LibraryName'. in parsing we prefer value coming
-- from munged @name@ field over the @lib-name@.
--
-- /Should/ be irrelevant.
combineLibraryName :: LibraryName -> LibraryName -> LibraryName
combineLibraryName :: LibraryName -> LibraryName -> LibraryName
combineLibraryName l :: LibraryName
l@(LSubLibName UnqualComponentName
_) LibraryName
_ = LibraryName
l
combineLibraryName LibraryName
_ LibraryName
l                 = LibraryName
l