{-# 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 used as a dependency for other packages.
    , Library -> BuildInfo
libBuildInfo      :: BuildInfo
    }
    deriving (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
$cto :: forall x. Rep Library x -> Library
$cfrom :: forall x. Library -> Rep Library x
Generic, Int -> Library -> ShowS
[Library] -> ShowS
Library -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Library] -> ShowS
$cshowList :: [Library] -> ShowS
show :: Library -> String
$cshow :: Library -> String
showsPrec :: Int -> Library -> ShowS
$cshowsPrec :: Int -> Library -> ShowS
Show, Library -> Library -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Library -> Library -> Bool
$c/= :: Library -> Library -> Bool
== :: Library -> Library -> Bool
$c== :: Library -> Library -> Bool
Eq, Eq 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
min :: Library -> Library -> Library
$cmin :: Library -> Library -> Library
max :: Library -> Library -> Library
$cmax :: Library -> Library -> Library
>= :: Library -> Library -> Bool
$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
compare :: Library -> Library -> Ordering
$ccompare :: Library -> Library -> Ordering
Ord, ReadPrec [Library]
ReadPrec Library
Int -> ReadS Library
ReadS [Library]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Library]
$creadListPrec :: ReadPrec [Library]
readPrec :: ReadPrec Library
$creadPrec :: ReadPrec Library
readList :: ReadS [Library]
$creadList :: ReadS [Library]
readsPrec :: Int -> ReadS Library
$creadsPrec :: Int -> ReadS Library
Read, Typeable, Typeable Library
Library -> DataType
Library -> Constr
(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)
gmapMo :: 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
gmapMp :: forall (m :: * -> *).
MonadPlus 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
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Library -> m Library
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Library -> m Library
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Library -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Library -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Library -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Library -> [u]
gmapQr :: 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
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Library -> r
gmapT :: (forall b. Data b => b -> b) -> Library -> Library
$cgmapT :: (forall b. Data b => b -> b) -> Library -> Library
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Library)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Library)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Library)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Library)
dataTypeOf :: Library -> DataType
$cdataTypeOf :: Library -> DataType
toConstr :: Library -> Constr
$ctoConstr :: Library -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Library
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Library
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Library -> c Library
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Library -> c Library
Data)

instance L.HasBuildInfo Library where
    buildInfo :: Lens' Library BuildInfo
buildInfo BuildInfo -> f BuildInfo
f Library
l = (\BuildInfo
x -> Library
l { libBuildInfo :: BuildInfo
libBuildInfo = BuildInfo
x }) 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 = forall a. (Generic a, GNFData (Rep a)) => a -> ()
genericRnf

emptyLibrary :: Library
emptyLibrary :: Library
emptyLibrary = Library
    { libName :: LibraryName
libName           = LibraryName
LMainLibName
    , exposedModules :: [ModuleName]
exposedModules    = forall a. Monoid a => a
mempty
    , reexportedModules :: [ModuleReexport]
reexportedModules = forall a. Monoid a => a
mempty
    , signatures :: [ModuleName]
signatures        = forall a. Monoid a => a
mempty
    , libExposed :: Bool
libExposed        = Bool
True
    , libVisibility :: LibraryVisibility
libVisibility     = forall a. Monoid a => a
mempty
    , libBuildInfo :: BuildInfo
libBuildInfo      = 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 = 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    = forall {a}. Monoid a => (Library -> a) -> a
combine Library -> [ModuleName]
exposedModules
    , reexportedModules :: [ModuleReexport]
reexportedModules = forall {a}. Monoid a => (Library -> a) -> a
combine Library -> [ModuleReexport]
reexportedModules
    , signatures :: [ModuleName]
signatures        = 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     = forall {a}. Monoid a => (Library -> a) -> a
combine Library -> LibraryVisibility
libVisibility
    , libBuildInfo :: BuildInfo
libBuildInfo      = 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 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
              forall a. [a] -> [a] -> [a]
++ BuildInfo -> [ModuleName]
otherModules (Library -> BuildInfo
libBuildInfo Library
lib)
              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