module Distribution.Types.DependencyMap (
    DependencyMap,
    toDepMap,
    fromDepMap,
    constrainBy,
) where

import Prelude ()
import Distribution.Compat.Prelude

import Distribution.Types.Dependency
import Distribution.Types.PackageName
import Distribution.Types.LibraryName
import Distribution.Version

import qualified Data.Map.Lazy as Map

-- | A map of dependencies.  Newtyped since the default monoid instance is not
--   appropriate.  The monoid instance uses 'intersectVersionRanges'.
newtype DependencyMap = DependencyMap { DependencyMap -> Map PackageName (VersionRange, Set LibraryName)
unDependencyMap :: Map PackageName (VersionRange, Set LibraryName) }
  deriving (Int -> DependencyMap -> ShowS
[DependencyMap] -> ShowS
DependencyMap -> String
(Int -> DependencyMap -> ShowS)
-> (DependencyMap -> String)
-> ([DependencyMap] -> ShowS)
-> Show DependencyMap
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [DependencyMap] -> ShowS
$cshowList :: [DependencyMap] -> ShowS
show :: DependencyMap -> String
$cshow :: DependencyMap -> String
showsPrec :: Int -> DependencyMap -> ShowS
$cshowsPrec :: Int -> DependencyMap -> ShowS
External instance of the constraint type Show LibraryName
External instance of the constraint type Show LibraryName
External instance of the constraint type forall a. Show a => Show (Set a)
External instance of the constraint type Show VersionRange
External instance of the constraint type forall a. Show a => Show (Set a)
External instance of the constraint type Show LibraryName
External instance of the constraint type Show VersionRange
External instance of the constraint type forall a b. (Show a, Show b) => Show (a, b)
External instance of the constraint type Show PackageName
External instance of the constraint type forall a b. (Show a, Show b) => Show (a, b)
External instance of the constraint type Show VersionRange
External instance of the constraint type forall a. Show a => Show (Set a)
External instance of the constraint type Show LibraryName
External instance of the constraint type Show PackageName
External instance of the constraint type forall k a. (Show k, Show a) => Show (Map k a)
External instance of the constraint type Ord Int
Show, ReadPrec [DependencyMap]
ReadPrec DependencyMap
Int -> ReadS DependencyMap
ReadS [DependencyMap]
(Int -> ReadS DependencyMap)
-> ReadS [DependencyMap]
-> ReadPrec DependencyMap
-> ReadPrec [DependencyMap]
-> Read DependencyMap
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [DependencyMap]
$creadListPrec :: ReadPrec [DependencyMap]
readPrec :: ReadPrec DependencyMap
$creadPrec :: ReadPrec DependencyMap
readList :: ReadS [DependencyMap]
$creadList :: ReadS [DependencyMap]
readsPrec :: Int -> ReadS DependencyMap
$creadsPrec :: Int -> ReadS DependencyMap
External instance of the constraint type Read LibraryName
External instance of the constraint type Read LibraryName
External instance of the constraint type forall a. (Read a, Ord a) => Read (Set a)
External instance of the constraint type Read VersionRange
External instance of the constraint type forall a. (Read a, Ord a) => Read (Set a)
External instance of the constraint type Read LibraryName
External instance of the constraint type Ord LibraryName
External instance of the constraint type Read VersionRange
External instance of the constraint type forall a b. (Read a, Read b) => Read (a, b)
External instance of the constraint type Read PackageName
External instance of the constraint type forall a b. (Read a, Read b) => Read (a, b)
External instance of the constraint type Read VersionRange
External instance of the constraint type forall a. (Read a, Ord a) => Read (Set a)
External instance of the constraint type Read LibraryName
External instance of the constraint type Ord LibraryName
External instance of the constraint type Read PackageName
External instance of the constraint type forall k e. (Ord k, Read k, Read e) => Read (Map k e)
External instance of the constraint type Monad ReadPrec
External instance of the constraint type Monad ReadPrec
External instance of the constraint type Ord PackageName
External instance of the constraint type Ord LibraryName
Instance of class: Read of the constraint type Read DependencyMap
Read)

instance Monoid DependencyMap where
    mempty :: DependencyMap
mempty = Map PackageName (VersionRange, Set LibraryName) -> DependencyMap
DependencyMap Map PackageName (VersionRange, Set LibraryName)
forall k a. Map k a
Map.empty
    mappend :: DependencyMap -> DependencyMap -> DependencyMap
mappend = DependencyMap -> DependencyMap -> DependencyMap
forall a. Semigroup a => a -> a -> a
Instance of class: Semigroup of the constraint type Semigroup DependencyMap
(<>)

instance Semigroup DependencyMap where
    (DependencyMap Map PackageName (VersionRange, Set LibraryName)
a) <> :: DependencyMap -> DependencyMap -> DependencyMap
<> (DependencyMap Map PackageName (VersionRange, Set LibraryName)
b) =
        Map PackageName (VersionRange, Set LibraryName) -> DependencyMap
DependencyMap (((VersionRange, Set LibraryName)
 -> (VersionRange, Set LibraryName)
 -> (VersionRange, Set LibraryName))
-> Map PackageName (VersionRange, Set LibraryName)
-> Map PackageName (VersionRange, Set LibraryName)
-> Map PackageName (VersionRange, Set LibraryName)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
External instance of the constraint type Ord PackageName
Map.unionWith (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
intersectVersionRangesAndJoinComponents Map PackageName (VersionRange, Set LibraryName)
a Map PackageName (VersionRange, Set LibraryName)
b)

intersectVersionRangesAndJoinComponents :: (VersionRange, Set LibraryName)
                                        -> (VersionRange, Set LibraryName)
                                        -> (VersionRange, Set LibraryName)
intersectVersionRangesAndJoinComponents :: (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
intersectVersionRangesAndJoinComponents (VersionRange
va, Set LibraryName
ca) (VersionRange
vb, Set LibraryName
cb) =
  (VersionRange -> VersionRange -> VersionRange
intersectVersionRanges VersionRange
va VersionRange
vb, Set LibraryName
ca Set LibraryName -> Set LibraryName -> Set LibraryName
forall a. Semigroup a => a -> a -> a
External instance of the constraint type forall a. Ord a => Semigroup (Set a)
External instance of the constraint type Ord LibraryName
<> Set LibraryName
cb)

toDepMap :: [Dependency] -> DependencyMap
toDepMap :: [Dependency] -> DependencyMap
toDepMap [Dependency]
ds =
  Map PackageName (VersionRange, Set LibraryName) -> DependencyMap
DependencyMap (Map PackageName (VersionRange, Set LibraryName) -> DependencyMap)
-> Map PackageName (VersionRange, Set LibraryName) -> DependencyMap
forall a b. (a -> b) -> a -> b
$ ((VersionRange, Set LibraryName)
 -> (VersionRange, Set LibraryName)
 -> (VersionRange, Set LibraryName))
-> [(PackageName, (VersionRange, Set LibraryName))]
-> Map PackageName (VersionRange, Set LibraryName)
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
External instance of the constraint type Ord PackageName
Map.fromListWith (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
intersectVersionRangesAndJoinComponents [ (PackageName
p,(VersionRange
vr,Set LibraryName
cs)) | Dependency PackageName
p VersionRange
vr Set LibraryName
cs <- [Dependency]
ds ]

fromDepMap :: DependencyMap -> [Dependency]
fromDepMap :: DependencyMap -> [Dependency]
fromDepMap DependencyMap
m = [ PackageName -> VersionRange -> Set LibraryName -> Dependency
Dependency PackageName
p VersionRange
vr Set LibraryName
cs | (PackageName
p,(VersionRange
vr,Set LibraryName
cs)) <- Map PackageName (VersionRange, Set LibraryName)
-> [(PackageName, (VersionRange, Set LibraryName))]
forall k a. Map k a -> [(k, a)]
Map.toList (DependencyMap -> Map PackageName (VersionRange, Set LibraryName)
unDependencyMap DependencyMap
m) ]

-- Apply extra constraints to a dependency map.
-- Combines dependencies where the result will only contain keys from the left
-- (first) map.  If a key also exists in the right map, both constraints will
-- be intersected.
constrainBy :: DependencyMap  -- ^ Input map
            -> DependencyMap  -- ^ Extra constraints
            -> DependencyMap
constrainBy :: DependencyMap -> DependencyMap -> DependencyMap
constrainBy DependencyMap
left DependencyMap
extra =
    Map PackageName (VersionRange, Set LibraryName) -> DependencyMap
DependencyMap (Map PackageName (VersionRange, Set LibraryName) -> DependencyMap)
-> Map PackageName (VersionRange, Set LibraryName) -> DependencyMap
forall a b. (a -> b) -> a -> b
$
      (PackageName
 -> (VersionRange, Set LibraryName)
 -> Map PackageName (VersionRange, Set LibraryName)
 -> Map PackageName (VersionRange, Set LibraryName))
-> Map PackageName (VersionRange, Set LibraryName)
-> Map PackageName (VersionRange, Set LibraryName)
-> Map PackageName (VersionRange, Set LibraryName)
forall k a b. (k -> a -> b -> b) -> b -> Map k a -> b
Map.foldrWithKey PackageName
-> (VersionRange, Set LibraryName)
-> Map PackageName (VersionRange, Set LibraryName)
-> Map PackageName (VersionRange, Set LibraryName)
forall {k}.
Ord k =>
k
-> (VersionRange, Set LibraryName)
-> Map k (VersionRange, Set LibraryName)
-> Map k (VersionRange, Set LibraryName)
External instance of the constraint type Ord PackageName
tightenConstraint (DependencyMap -> Map PackageName (VersionRange, Set LibraryName)
unDependencyMap DependencyMap
left)
                                         (DependencyMap -> Map PackageName (VersionRange, Set LibraryName)
unDependencyMap DependencyMap
extra)
  where tightenConstraint :: k
-> (VersionRange, Set LibraryName)
-> Map k (VersionRange, Set LibraryName)
-> Map k (VersionRange, Set LibraryName)
tightenConstraint k
n (VersionRange, Set LibraryName)
c Map k (VersionRange, Set LibraryName)
l =
            case k
-> Map k (VersionRange, Set LibraryName)
-> Maybe (VersionRange, Set LibraryName)
forall k a. Ord k => k -> Map k a -> Maybe a
Evidence bound by a type signature of the constraint type Ord k
Map.lookup k
n Map k (VersionRange, Set LibraryName)
l of
              Maybe (VersionRange, Set LibraryName)
Nothing -> Map k (VersionRange, Set LibraryName)
l
              Just (VersionRange, Set LibraryName)
vrcs -> k
-> (VersionRange, Set LibraryName)
-> Map k (VersionRange, Set LibraryName)
-> Map k (VersionRange, Set LibraryName)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Evidence bound by a type signature of the constraint type Ord k
Map.insert k
n ((VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
-> (VersionRange, Set LibraryName)
intersectVersionRangesAndJoinComponents (VersionRange, Set LibraryName)
vrcs (VersionRange, Set LibraryName)
c) Map k (VersionRange, Set LibraryName)
l