{-# LANGUAGE ScopedTypeVariables #-}
module Distribution.PackageDescription.Check.Conditional
  ( checkCondTarget
  , checkDuplicateModules
  ) where
import Distribution.Compat.Prelude
import Prelude ()
import Distribution.Compiler
import Distribution.ModuleName (ModuleName)
import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Check.Monad
import Distribution.System
import qualified Data.Map as Map
import Control.Monad
initTargetAnnotation
  :: Monoid a
  => (UnqualComponentName -> a -> a) 
  -> UnqualComponentName
  -> TargetAnnotation a
initTargetAnnotation :: forall a.
Monoid a =>
(UnqualComponentName -> a -> a)
-> UnqualComponentName -> TargetAnnotation a
initTargetAnnotation UnqualComponentName -> a -> a
nf UnqualComponentName
n = a -> Bool -> TargetAnnotation a
forall a. a -> Bool -> TargetAnnotation a
TargetAnnotation (UnqualComponentName -> a -> a
nf UnqualComponentName
n a
forall a. Monoid a => a
mempty) Bool
False
updateTargetAnnotation
  :: Monoid a
  => a 
  -> TargetAnnotation a
  -> TargetAnnotation a
updateTargetAnnotation :: forall a. Monoid a => a -> TargetAnnotation a -> TargetAnnotation a
updateTargetAnnotation a
t TargetAnnotation a
ta = TargetAnnotation a
ta{taTarget = taTarget ta <> t}
annotateCondTree
  :: forall a
   . (Eq a, Monoid a)
  => [PackageFlag] 
  -> TargetAnnotation a
  -> CondTree ConfVar [Dependency] a
  -> CondTree ConfVar [Dependency] (TargetAnnotation a)
annotateCondTree :: forall a.
(Eq a, Monoid a) =>
[PackageFlag]
-> TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
annotateCondTree [PackageFlag]
fs TargetAnnotation a
ta (CondNode a
a [Dependency]
c [CondBranch ConfVar [Dependency] a]
bs) =
  let ta' :: TargetAnnotation a
ta' = a -> TargetAnnotation a -> TargetAnnotation a
forall a. Monoid a => a -> TargetAnnotation a -> TargetAnnotation a
updateTargetAnnotation a
a TargetAnnotation a
ta
      bs' :: [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs' = (CondBranch ConfVar [Dependency] a
 -> CondBranch ConfVar [Dependency] (TargetAnnotation a))
-> [CondBranch ConfVar [Dependency] a]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
forall a b. (a -> b) -> [a] -> [b]
map (TargetAnnotation a
-> CondBranch ConfVar [Dependency] a
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
annotateBranch TargetAnnotation a
ta') [CondBranch ConfVar [Dependency] a]
bs
      bs'' :: [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs'' = [PackageFlag]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
forall a.
(Eq a, Monoid a) =>
[PackageFlag]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
crossAnnotateBranches [PackageFlag]
defTrueFlags [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs'
   in TargetAnnotation a
-> [Dependency]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
forall v c a. a -> c -> [CondBranch v c a] -> CondTree v c a
CondNode TargetAnnotation a
ta' [Dependency]
c [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs''
  where
    annotateBranch
      :: TargetAnnotation a
      -> CondBranch ConfVar [Dependency] a
      -> CondBranch
          ConfVar
          [Dependency]
          (TargetAnnotation a)
    annotateBranch :: TargetAnnotation a
-> CondBranch ConfVar [Dependency] a
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
annotateBranch TargetAnnotation a
wta (CondBranch Condition ConfVar
k CondTree ConfVar [Dependency] a
t Maybe (CondTree ConfVar [Dependency] a)
mf) =
      let uf :: Bool
uf = Condition ConfVar -> Bool
isPkgFlagCond Condition ConfVar
k
          wta' :: TargetAnnotation a
wta' = TargetAnnotation a
wta{taPackageFlag = taPackageFlag wta || uf}
          atf :: TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
atf = [PackageFlag]
-> TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
forall a.
(Eq a, Monoid a) =>
[PackageFlag]
-> TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
annotateCondTree [PackageFlag]
fs
       in Condition ConfVar
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
-> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
forall v c a.
Condition v
-> CondTree v c a -> Maybe (CondTree v c a) -> CondBranch v c a
CondBranch
            Condition ConfVar
k
            (TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
atf TargetAnnotation a
wta' CondTree ConfVar [Dependency] a
t)
            (TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
atf TargetAnnotation a
wta (CondTree ConfVar [Dependency] a
 -> CondTree ConfVar [Dependency] (TargetAnnotation a))
-> Maybe (CondTree ConfVar [Dependency] a)
-> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (CondTree ConfVar [Dependency] a)
mf)
    
    
    
    
    
    isPkgFlagCond :: Condition ConfVar -> Bool
    isPkgFlagCond :: Condition ConfVar -> Bool
isPkgFlagCond (Lit Bool
_) = Bool
False
    isPkgFlagCond (Var (PackageFlag FlagName
f)) = FlagName -> [FlagName] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem FlagName
f [FlagName]
defOffFlags
    isPkgFlagCond (Var ConfVar
_) = Bool
False
    isPkgFlagCond (CNot Condition ConfVar
cn) = Bool -> Bool
not (Condition ConfVar -> Bool
isPkgFlagCond Condition ConfVar
cn)
    isPkgFlagCond (CAnd Condition ConfVar
ca Condition ConfVar
cb) = Condition ConfVar -> Bool
isPkgFlagCond Condition ConfVar
ca Bool -> Bool -> Bool
|| Condition ConfVar -> Bool
isPkgFlagCond Condition ConfVar
cb
    isPkgFlagCond (COr Condition ConfVar
ca Condition ConfVar
cb) = Condition ConfVar -> Bool
isPkgFlagCond Condition ConfVar
ca Bool -> Bool -> Bool
&& Condition ConfVar -> Bool
isPkgFlagCond Condition ConfVar
cb
    
    defOffFlags :: [FlagName]
defOffFlags =
      (PackageFlag -> FlagName) -> [PackageFlag] -> [FlagName]
forall a b. (a -> b) -> [a] -> [b]
map PackageFlag -> FlagName
flagName ([PackageFlag] -> [FlagName]) -> [PackageFlag] -> [FlagName]
forall a b. (a -> b) -> a -> b
$
        (PackageFlag -> Bool) -> [PackageFlag] -> [PackageFlag]
forall a. (a -> Bool) -> [a] -> [a]
filter
          ( \PackageFlag
f ->
              Bool -> Bool
not (PackageFlag -> Bool
flagDefault PackageFlag
f)
                Bool -> Bool -> Bool
&& PackageFlag -> Bool
flagManual PackageFlag
f
          )
          [PackageFlag]
fs
    defTrueFlags :: [PackageFlag]
    defTrueFlags :: [PackageFlag]
defTrueFlags = (PackageFlag -> Bool) -> [PackageFlag] -> [PackageFlag]
forall a. (a -> Bool) -> [a] -> [a]
filter PackageFlag -> Bool
flagDefault [PackageFlag]
fs
crossAnnotateBranches
  :: forall a
   . (Eq a, Monoid a)
  => [PackageFlag] 
  -> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
  -> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
crossAnnotateBranches :: forall a.
(Eq a, Monoid a) =>
[PackageFlag]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
crossAnnotateBranches [PackageFlag]
fs [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs = (CondBranch ConfVar [Dependency] (TargetAnnotation a)
 -> CondBranch ConfVar [Dependency] (TargetAnnotation a))
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
forall a b. (a -> b) -> [a] -> [b]
map CondBranch ConfVar [Dependency] (TargetAnnotation a)
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
crossAnnBranch [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs
  where
    crossAnnBranch
      :: CondBranch ConfVar [Dependency] (TargetAnnotation a)
      -> CondBranch ConfVar [Dependency] (TargetAnnotation a)
    crossAnnBranch :: CondBranch ConfVar [Dependency] (TargetAnnotation a)
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
crossAnnBranch CondBranch ConfVar [Dependency] (TargetAnnotation a)
wr =
      let
        rs :: [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
rs = (CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Bool)
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
forall a. (a -> Bool) -> [a] -> [a]
filter (CondBranch ConfVar [Dependency] (TargetAnnotation a)
-> CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Bool
forall a. Eq a => a -> a -> Bool
/= CondBranch ConfVar [Dependency] (TargetAnnotation a)
wr) [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs
        ts :: [a]
ts = (CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Maybe a)
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)] -> [a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Maybe a
realiseBranch [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
rs
       in
        a
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
updateTargetAnnBranch ([a] -> a
forall a. Monoid a => [a] -> a
mconcat [a]
ts) CondBranch ConfVar [Dependency] (TargetAnnotation a)
wr
    realiseBranch :: CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Maybe a
    realiseBranch :: CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Maybe a
realiseBranch CondBranch ConfVar [Dependency] (TargetAnnotation a)
b =
      let
        
        realiseBranchFunction :: ConfVar -> Either ConfVar Bool
        realiseBranchFunction :: ConfVar -> Either ConfVar Bool
realiseBranchFunction (PackageFlag FlagName
n) | FlagName -> [FlagName] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem FlagName
n ((PackageFlag -> FlagName) -> [PackageFlag] -> [FlagName]
forall a b. (a -> b) -> [a] -> [b]
map PackageFlag -> FlagName
flagName [PackageFlag]
fs) = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
True
        realiseBranchFunction ConfVar
_ = Bool -> Either ConfVar Bool
forall a b. b -> Either a b
Right Bool
False
        ms :: Maybe ([Dependency], a)
ms = (ConfVar -> Either ConfVar Bool)
-> CondBranch ConfVar [Dependency] a -> Maybe ([Dependency], a)
forall a d v.
(Semigroup a, Semigroup d) =>
(v -> Either v Bool) -> CondBranch v d a -> Maybe (d, a)
simplifyCondBranch ConfVar -> Either ConfVar Bool
realiseBranchFunction ((TargetAnnotation a -> a)
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
-> CondBranch ConfVar [Dependency] a
forall a b.
(a -> b)
-> CondBranch ConfVar [Dependency] a
-> CondBranch ConfVar [Dependency] b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TargetAnnotation a -> a
forall a. TargetAnnotation a -> a
taTarget CondBranch ConfVar [Dependency] (TargetAnnotation a)
b)
       in
        (([Dependency], a) -> a) -> Maybe ([Dependency], a) -> Maybe a
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Dependency], a) -> a
forall a b. (a, b) -> b
snd Maybe ([Dependency], a)
ms
    updateTargetAnnBranch
      :: a
      -> CondBranch ConfVar [Dependency] (TargetAnnotation a)
      -> CondBranch ConfVar [Dependency] (TargetAnnotation a)
    updateTargetAnnBranch :: a
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
updateTargetAnnBranch a
a (CondBranch Condition ConfVar
k CondTree ConfVar [Dependency] (TargetAnnotation a)
t Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
mt) =
      let updateTargetAnnTree :: CondTree v c (TargetAnnotation a)
-> CondTree v c (TargetAnnotation a)
updateTargetAnnTree (CondNode TargetAnnotation a
ka c
c [CondBranch v c (TargetAnnotation a)]
wbs) =
            (TargetAnnotation a
-> c
-> [CondBranch v c (TargetAnnotation a)]
-> CondTree v c (TargetAnnotation a)
forall v c a. a -> c -> [CondBranch v c a] -> CondTree v c a
CondNode (a -> TargetAnnotation a -> TargetAnnotation a
forall a. Monoid a => a -> TargetAnnotation a -> TargetAnnotation a
updateTargetAnnotation a
a TargetAnnotation a
ka) c
c [CondBranch v c (TargetAnnotation a)]
wbs)
       in Condition ConfVar
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
-> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
-> CondBranch ConfVar [Dependency] (TargetAnnotation a)
forall v c a.
Condition v
-> CondTree v c a -> Maybe (CondTree v c a) -> CondBranch v c a
CondBranch Condition ConfVar
k (CondTree ConfVar [Dependency] (TargetAnnotation a)
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
forall {v} {c}.
CondTree v c (TargetAnnotation a)
-> CondTree v c (TargetAnnotation a)
updateTargetAnnTree CondTree ConfVar [Dependency] (TargetAnnotation a)
t) (CondTree ConfVar [Dependency] (TargetAnnotation a)
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
forall {v} {c}.
CondTree v c (TargetAnnotation a)
-> CondTree v c (TargetAnnotation a)
updateTargetAnnTree (CondTree ConfVar [Dependency] (TargetAnnotation a)
 -> CondTree ConfVar [Dependency] (TargetAnnotation a))
-> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
-> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
mt)
checkCondTarget
  :: forall m a
   . (Monad m, Eq a, Monoid a)
  => [PackageFlag] 
  -> (a -> CheckM m ()) 
  -> (UnqualComponentName -> a -> a)
  
  
  
  -> (UnqualComponentName, CondTree ConfVar [Dependency] a)
  
  -> CheckM m ()
checkCondTarget :: forall (m :: * -> *) a.
(Monad m, Eq a, Monoid a) =>
[PackageFlag]
-> (a -> CheckM m ())
-> (UnqualComponentName -> a -> a)
-> (UnqualComponentName, CondTree ConfVar [Dependency] a)
-> CheckM m ()
checkCondTarget [PackageFlag]
fs a -> CheckM m ()
cf UnqualComponentName -> a -> a
nf (UnqualComponentName
unqualName, CondTree ConfVar [Dependency] a
ct) =
  CondTree ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wTree (CondTree ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ())
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
-> CheckM m ()
forall a b. (a -> b) -> a -> b
$ [PackageFlag]
-> TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
forall a.
(Eq a, Monoid a) =>
[PackageFlag]
-> TargetAnnotation a
-> CondTree ConfVar [Dependency] a
-> CondTree ConfVar [Dependency] (TargetAnnotation a)
annotateCondTree [PackageFlag]
fs ((UnqualComponentName -> a -> a)
-> UnqualComponentName -> TargetAnnotation a
forall a.
Monoid a =>
(UnqualComponentName -> a -> a)
-> UnqualComponentName -> TargetAnnotation a
initTargetAnnotation UnqualComponentName -> a -> a
nf UnqualComponentName
unqualName) CondTree ConfVar [Dependency] a
ct
  where
    
    
    wTree
      :: CondTree ConfVar [Dependency] (TargetAnnotation a)
      -> CheckM m ()
    wTree :: CondTree ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wTree (CondNode TargetAnnotation a
ta [Dependency]
_ [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs)
      
      
      
      
      
      
      | (CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Bool)
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Bool
isSimple [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs = do
          (CheckCtx m -> CheckCtx m) -> CheckM m () -> CheckM m ()
forall (m :: * -> *).
Monad m =>
(CheckCtx m -> CheckCtx m) -> CheckM m () -> CheckM m ()
localCM (TargetAnnotation a -> CheckCtx m -> CheckCtx m
forall (m :: * -> *) a.
Monad m =>
TargetAnnotation a -> CheckCtx m -> CheckCtx m
initCheckCtx TargetAnnotation a
ta) (a -> CheckM m ()
cf (a -> CheckM m ()) -> a -> CheckM m ()
forall a b. (a -> b) -> a -> b
$ TargetAnnotation a -> a
forall a. TargetAnnotation a -> a
taTarget TargetAnnotation a
ta)
          (CondBranch ConfVar [Dependency] (TargetAnnotation a)
 -> CheckM m ())
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> CheckM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ CondBranch ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wBranch [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs
      
      
      | Bool
otherwise = do
          (CondBranch ConfVar [Dependency] (TargetAnnotation a)
 -> CheckM m ())
-> [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
-> CheckM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ CondBranch ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wBranch [CondBranch ConfVar [Dependency] (TargetAnnotation a)]
bs
    isSimple
      :: CondBranch ConfVar [Dependency] (TargetAnnotation a)
      -> Bool
    isSimple :: CondBranch ConfVar [Dependency] (TargetAnnotation a) -> Bool
isSimple (CondBranch Condition ConfVar
_ CondTree ConfVar [Dependency] (TargetAnnotation a)
_ Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
Nothing) = Bool
True
    isSimple (CondBranch Condition ConfVar
_ CondTree ConfVar [Dependency] (TargetAnnotation a)
_ (Just CondTree ConfVar [Dependency] (TargetAnnotation a)
_)) = Bool
False
    wBranch
      :: CondBranch ConfVar [Dependency] (TargetAnnotation a)
      -> CheckM m ()
    wBranch :: CondBranch ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wBranch (CondBranch Condition ConfVar
k CondTree ConfVar [Dependency] (TargetAnnotation a)
t Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
mf) = do
      Condition ConfVar -> CheckM m ()
forall (m :: * -> *). Monad m => Condition ConfVar -> CheckM m ()
checkCondVars Condition ConfVar
k
      CondTree ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wTree CondTree ConfVar [Dependency] (TargetAnnotation a)
t
      CheckM m ()
-> (CondTree ConfVar [Dependency] (TargetAnnotation a)
    -> CheckM m ())
-> Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
-> CheckM m ()
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> CheckM m ()
forall a. a -> CheckM m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()) CondTree ConfVar [Dependency] (TargetAnnotation a) -> CheckM m ()
wTree Maybe (CondTree ConfVar [Dependency] (TargetAnnotation a))
mf
checkCondVars :: Monad m => Condition ConfVar -> CheckM m ()
checkCondVars :: forall (m :: * -> *). Monad m => Condition ConfVar -> CheckM m ()
checkCondVars Condition ConfVar
cond =
  let (Condition ConfVar
_, [ConfVar]
vs) = Condition ConfVar
-> (ConfVar -> Either ConfVar Bool)
-> (Condition ConfVar, [ConfVar])
forall c d.
Condition c -> (c -> Either d Bool) -> (Condition d, [d])
simplifyCondition Condition ConfVar
cond (\ConfVar
v -> ConfVar -> Either ConfVar Bool
forall a b. a -> Either a b
Left ConfVar
v)
   in 
      
      
      (ConfVar -> CheckM m ()) -> [ConfVar] -> CheckM m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ConfVar -> CheckM m ()
forall (m :: * -> *). Monad m => ConfVar -> CheckM m ()
vcheck [ConfVar]
vs
  where
    vcheck :: Monad m => ConfVar -> CheckM m ()
    vcheck :: forall (m :: * -> *). Monad m => ConfVar -> CheckM m ()
vcheck (OS (OtherOS String
os)) =
      PackageCheck -> CheckM m ()
forall (m :: * -> *). Monad m => PackageCheck -> CheckM m ()
tellP (CheckExplanation -> PackageCheck
PackageDistInexcusable (CheckExplanation -> PackageCheck)
-> CheckExplanation -> PackageCheck
forall a b. (a -> b) -> a -> b
$ [String] -> CheckExplanation
UnknownOS [String
os])
    vcheck (Arch (OtherArch String
arch)) =
      PackageCheck -> CheckM m ()
forall (m :: * -> *). Monad m => PackageCheck -> CheckM m ()
tellP (CheckExplanation -> PackageCheck
PackageDistInexcusable (CheckExplanation -> PackageCheck)
-> CheckExplanation -> PackageCheck
forall a b. (a -> b) -> a -> b
$ [String] -> CheckExplanation
UnknownArch [String
arch])
    vcheck (Impl (OtherCompiler String
os) VersionRange
_) =
      PackageCheck -> CheckM m ()
forall (m :: * -> *). Monad m => PackageCheck -> CheckM m ()
tellP (CheckExplanation -> PackageCheck
PackageDistInexcusable (CheckExplanation -> PackageCheck)
-> CheckExplanation -> PackageCheck
forall a b. (a -> b) -> a -> b
$ [String] -> CheckExplanation
UnknownCompiler [String
os])
    vcheck ConfVar
_ = () -> CheckM m ()
forall a. a -> CheckM m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkDuplicateModules :: GenericPackageDescription -> [PackageCheck]
checkDuplicateModules :: GenericPackageDescription -> [PackageCheck]
checkDuplicateModules GenericPackageDescription
pkg =
  (CondTree ConfVar [Dependency] Library -> [PackageCheck])
-> [CondTree ConfVar [Dependency] Library] -> [PackageCheck]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CondTree ConfVar [Dependency] Library -> [PackageCheck]
forall {v} {c}. CondTree v c Library -> [PackageCheck]
checkLib (([CondTree ConfVar [Dependency] Library]
 -> [CondTree ConfVar [Dependency] Library])
-> (CondTree ConfVar [Dependency] Library
    -> [CondTree ConfVar [Dependency] Library]
    -> [CondTree ConfVar [Dependency] Library])
-> Maybe (CondTree ConfVar [Dependency] Library)
-> [CondTree ConfVar [Dependency] Library]
-> [CondTree ConfVar [Dependency] Library]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [CondTree ConfVar [Dependency] Library]
-> [CondTree ConfVar [Dependency] Library]
forall a. a -> a
id (:) (GenericPackageDescription
-> Maybe (CondTree ConfVar [Dependency] Library)
condLibrary GenericPackageDescription
pkg) ([CondTree ConfVar [Dependency] Library]
 -> [CondTree ConfVar [Dependency] Library])
-> ([(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
    -> [CondTree ConfVar [Dependency] Library])
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
-> [CondTree ConfVar [Dependency] Library]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((UnqualComponentName, CondTree ConfVar [Dependency] Library)
 -> CondTree ConfVar [Dependency] Library)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
-> [CondTree ConfVar [Dependency] Library]
forall a b. (a -> b) -> [a] -> [b]
map (UnqualComponentName, CondTree ConfVar [Dependency] Library)
-> CondTree ConfVar [Dependency] Library
forall a b. (a, b) -> b
snd ([(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
 -> [CondTree ConfVar [Dependency] Library])
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
-> [CondTree ConfVar [Dependency] Library]
forall a b. (a -> b) -> a -> b
$ GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
condSubLibraries GenericPackageDescription
pkg)
    [PackageCheck] -> [PackageCheck] -> [PackageCheck]
forall a. [a] -> [a] -> [a]
++ (CondTree ConfVar [Dependency] Executable -> [PackageCheck])
-> [CondTree ConfVar [Dependency] Executable] -> [PackageCheck]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CondTree ConfVar [Dependency] Executable -> [PackageCheck]
forall {v} {c}. CondTree v c Executable -> [PackageCheck]
checkExe (((UnqualComponentName, CondTree ConfVar [Dependency] Executable)
 -> CondTree ConfVar [Dependency] Executable)
-> [(UnqualComponentName,
     CondTree ConfVar [Dependency] Executable)]
-> [CondTree ConfVar [Dependency] Executable]
forall a b. (a -> b) -> [a] -> [b]
map (UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> CondTree ConfVar [Dependency] Executable
forall a b. (a, b) -> b
snd ([(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
 -> [CondTree ConfVar [Dependency] Executable])
-> [(UnqualComponentName,
     CondTree ConfVar [Dependency] Executable)]
-> [CondTree ConfVar [Dependency] Executable]
forall a b. (a -> b) -> a -> b
$ GenericPackageDescription
-> [(UnqualComponentName,
     CondTree ConfVar [Dependency] Executable)]
condExecutables GenericPackageDescription
pkg)
    [PackageCheck] -> [PackageCheck] -> [PackageCheck]
forall a. [a] -> [a] -> [a]
++ (CondTree ConfVar [Dependency] TestSuite -> [PackageCheck])
-> [CondTree ConfVar [Dependency] TestSuite] -> [PackageCheck]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CondTree ConfVar [Dependency] TestSuite -> [PackageCheck]
forall {v} {c}. CondTree v c TestSuite -> [PackageCheck]
checkTest (((UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
 -> CondTree ConfVar [Dependency] TestSuite)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
-> [CondTree ConfVar [Dependency] TestSuite]
forall a b. (a -> b) -> [a] -> [b]
map (UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> CondTree ConfVar [Dependency] TestSuite
forall a b. (a, b) -> b
snd ([(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
 -> [CondTree ConfVar [Dependency] TestSuite])
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
-> [CondTree ConfVar [Dependency] TestSuite]
forall a b. (a -> b) -> a -> b
$ GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
condTestSuites GenericPackageDescription
pkg)
    [PackageCheck] -> [PackageCheck] -> [PackageCheck]
forall a. [a] -> [a] -> [a]
++ (CondTree ConfVar [Dependency] Benchmark -> [PackageCheck])
-> [CondTree ConfVar [Dependency] Benchmark] -> [PackageCheck]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap CondTree ConfVar [Dependency] Benchmark -> [PackageCheck]
forall {v} {c}. CondTree v c Benchmark -> [PackageCheck]
checkBench (((UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
 -> CondTree ConfVar [Dependency] Benchmark)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
-> [CondTree ConfVar [Dependency] Benchmark]
forall a b. (a -> b) -> [a] -> [b]
map (UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> CondTree ConfVar [Dependency] Benchmark
forall a b. (a, b) -> b
snd ([(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
 -> [CondTree ConfVar [Dependency] Benchmark])
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
-> [CondTree ConfVar [Dependency] Benchmark]
forall a b. (a -> b) -> a -> b
$ GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
condBenchmarks GenericPackageDescription
pkg)
  where
    
    checkLib :: CondTree v c Library -> [PackageCheck]
checkLib = String
-> (Library -> [ModuleName])
-> CondTree v c Library
-> [PackageCheck]
forall a v c.
String -> (a -> [ModuleName]) -> CondTree v c a -> [PackageCheck]
checkDups String
"library" (\Library
l -> Library -> [ModuleName]
explicitLibModules Library
l [ModuleName] -> [ModuleName] -> [ModuleName]
forall a. [a] -> [a] -> [a]
++ (ModuleReexport -> ModuleName) -> [ModuleReexport] -> [ModuleName]
forall a b. (a -> b) -> [a] -> [b]
map ModuleReexport -> ModuleName
moduleReexportName (Library -> [ModuleReexport]
reexportedModules Library
l))
    checkExe :: CondTree v c Executable -> [PackageCheck]
checkExe = String
-> (Executable -> [ModuleName])
-> CondTree v c Executable
-> [PackageCheck]
forall a v c.
String -> (a -> [ModuleName]) -> CondTree v c a -> [PackageCheck]
checkDups String
"executable" Executable -> [ModuleName]
exeModules
    checkTest :: CondTree v c TestSuite -> [PackageCheck]
checkTest = String
-> (TestSuite -> [ModuleName])
-> CondTree v c TestSuite
-> [PackageCheck]
forall a v c.
String -> (a -> [ModuleName]) -> CondTree v c a -> [PackageCheck]
checkDups String
"test suite" TestSuite -> [ModuleName]
testModules
    checkBench :: CondTree v c Benchmark -> [PackageCheck]
checkBench = String
-> (Benchmark -> [ModuleName])
-> CondTree v c Benchmark
-> [PackageCheck]
forall a v c.
String -> (a -> [ModuleName]) -> CondTree v c a -> [PackageCheck]
checkDups String
"benchmark" Benchmark -> [ModuleName]
benchmarkModules
    checkDups :: String -> (a -> [ModuleName]) -> CondTree v c a -> [PackageCheck]
    checkDups :: forall a v c.
String -> (a -> [ModuleName]) -> CondTree v c a -> [PackageCheck]
checkDups String
s a -> [ModuleName]
getModules CondTree v c a
t =
      let sumPair :: (Int, Int) -> (Int, Int) -> (Int, Int)
sumPair (Int
x, Int
x') (Int
y, Int
y') = (Int
x Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
x' :: Int, Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
y' :: Int)
          mergePair :: (a, a) -> (b, b) -> (a, b)
mergePair (a
x, a
x') (b
y, b
y') = (a
x a -> a -> a
forall a. Num a => a -> a -> a
+ a
x', b -> b -> b
forall a. Ord a => a -> a -> a
max b
y b
y')
          maxPair :: (a, a) -> (b, b) -> (a, b)
maxPair (a
x, a
x') (b
y, b
y') = (a -> a -> a
forall a. Ord a => a -> a -> a
max a
x a
x', b -> b -> b
forall a. Ord a => a -> a -> a
max b
y b
y')
          libMap :: Map ModuleName (Int, Int)
libMap =
            Map ModuleName (Int, Int)
-> ((c, a) -> Map ModuleName (Int, Int))
-> (Map ModuleName (Int, Int)
    -> Map ModuleName (Int, Int) -> Map ModuleName (Int, Int))
-> (Map ModuleName (Int, Int)
    -> Map ModuleName (Int, Int) -> Map ModuleName (Int, Int))
-> CondTree v c a
-> Map ModuleName (Int, Int)
forall b c a v.
b
-> ((c, a) -> b)
-> (b -> b -> b)
-> (b -> b -> b)
-> CondTree v c a
-> b
foldCondTree
              Map ModuleName (Int, Int)
forall k a. Map k a
Map.empty
              (\(c
_, a
v) -> ((Int, Int) -> (Int, Int) -> (Int, Int))
-> [(ModuleName, (Int, Int))] -> Map ModuleName (Int, Int)
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith (Int, Int) -> (Int, Int) -> (Int, Int)
sumPair ([(ModuleName, (Int, Int))] -> Map ModuleName (Int, Int))
-> ([ModuleName] -> [(ModuleName, (Int, Int))])
-> [ModuleName]
-> Map ModuleName (Int, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModuleName -> (ModuleName, (Int, Int)))
-> [ModuleName] -> [(ModuleName, (Int, Int))]
forall a b. (a -> b) -> [a] -> [b]
map (\ModuleName
x -> (ModuleName
x, (Int
1, Int
1))) ([ModuleName] -> Map ModuleName (Int, Int))
-> [ModuleName] -> Map ModuleName (Int, Int)
forall a b. (a -> b) -> a -> b
$ a -> [ModuleName]
getModules a
v)
              (((Int, Int) -> (Int, Int) -> (Int, Int))
-> Map ModuleName (Int, Int)
-> Map ModuleName (Int, Int)
-> Map ModuleName (Int, Int)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith (Int, Int) -> (Int, Int) -> (Int, Int)
forall {a} {b}. (Num a, Ord b) => (a, a) -> (b, b) -> (a, b)
mergePair) 
              (((Int, Int) -> (Int, Int) -> (Int, Int))
-> Map ModuleName (Int, Int)
-> Map ModuleName (Int, Int)
-> Map ModuleName (Int, Int)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith (Int, Int) -> (Int, Int) -> (Int, Int)
forall {a} {b}. (Ord a, Ord b) => (a, a) -> (b, b) -> (a, b)
maxPair) 
              CondTree v c a
t
          dupLibsStrict :: [ModuleName]
dupLibsStrict = Map ModuleName (Int, Int) -> [ModuleName]
forall k a. Map k a -> [k]
Map.keys (Map ModuleName (Int, Int) -> [ModuleName])
-> Map ModuleName (Int, Int) -> [ModuleName]
forall a b. (a -> b) -> a -> b
$ ((Int, Int) -> Bool)
-> Map ModuleName (Int, Int) -> Map ModuleName (Int, Int)
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1) (Int -> Bool) -> ((Int, Int) -> Int) -> (Int, Int) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> Int
forall a b. (a, b) -> a
fst) Map ModuleName (Int, Int)
libMap
          dupLibsLax :: [ModuleName]
dupLibsLax = Map ModuleName (Int, Int) -> [ModuleName]
forall k a. Map k a -> [k]
Map.keys (Map ModuleName (Int, Int) -> [ModuleName])
-> Map ModuleName (Int, Int) -> [ModuleName]
forall a b. (a -> b) -> a -> b
$ ((Int, Int) -> Bool)
-> Map ModuleName (Int, Int) -> Map ModuleName (Int, Int)
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1) (Int -> Bool) -> ((Int, Int) -> Int) -> (Int, Int) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> Int
forall a b. (a, b) -> b
snd) Map ModuleName (Int, Int)
libMap
       in if Bool -> Bool
not ([ModuleName] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ModuleName]
dupLibsLax)
            then
              [ CheckExplanation -> PackageCheck
PackageBuildImpossible
                  (String -> [ModuleName] -> CheckExplanation
DuplicateModule String
s [ModuleName]
dupLibsLax)
              ]
            else
              if Bool -> Bool
not ([ModuleName] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ModuleName]
dupLibsStrict)
                then
                  [ CheckExplanation -> PackageCheck
PackageDistSuspicious
                      (String -> [ModuleName] -> CheckExplanation
PotentialDupModule String
s [ModuleName]
dupLibsStrict)
                  ]
                else []