Skip to content

Commit 575acc9

Browse files
authored
Merge pull request #11626 from leana8959/remove-duplicated-constraints
Remove duplicated constraints from CondTree
2 parents 4b56b0d + a0364e4 commit 575acc9

66 files changed

Lines changed: 418 additions & 2293 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ module Distribution.PackageDescription.Configuration
2828
, mapCondTree
2929
, mapTreeData
3030
, mapTreeConds
31-
, mapTreeConstrs
3231
, transformAllBuildInfos
3332
, transformAllBuildDepends
3433
, transformAllBuildDependsN
@@ -39,6 +38,7 @@ import Distribution.Compat.Prelude
3938
import Prelude ()
4039

4140
-- lens
41+
import qualified Distribution.Compat.Lens as L
4242
import qualified Distribution.Types.BuildInfo.Lens as L
4343
import qualified Distribution.Types.GenericPackageDescription.Lens as L
4444
import qualified Distribution.Types.PackageDescription.Lens as L
@@ -64,6 +64,7 @@ import Distribution.Utils.Path (sameDirectory)
6464
import Distribution.Version
6565

6666
import Data.Tree (Tree (Node))
67+
import Data.Tuple
6768

6869
------------------------------------------------------------------------------
6970

@@ -192,7 +193,7 @@ resolveWithFlags
192193
-- ^ Compiler information
193194
-> [PackageVersionConstraint]
194195
-- ^ Additional constraints
195-
-> [CondTree ConfVar [Dependency] PDTagged]
196+
-> [CondTree ConfVar PDTagged]
196197
-> ([Dependency] -> DepTestRslt)
197198
-- ^ Dependency test function.
198199
-> Either [MissingDependency] (TargetSet PDTagged, FlagAssignment)
@@ -203,10 +204,10 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps =
203204
where
204205
-- simplify trees by (partially) evaluating all conditions and converting
205206
-- dependencies to dependency maps.
206-
simplifiedTrees :: [CondTree FlagName DependencyMap PDTagged]
207+
simplifiedTrees :: [CondTree FlagName (PDTagged, DependencyMap)]
207208
simplifiedTrees =
208209
map
209-
( mapTreeConstrs toDepMap -- convert to maps
210+
( mapTreeData (\x -> (x, toDepMap $ L.view L.targetBuildDepends x))
210211
. addBuildableConditionPDTagged
211212
. mapTreeConds (fst . simplifyWithSysParams os arch impl)
212213
)
@@ -226,6 +227,7 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps =
226227
flip map simplifiedTrees $
227228
-- apply additional constraints to all dependencies
228229
first (`constrainBy` constrs)
230+
. swap
229231
. simplifyCondTree (env flags)
230232
deps = overallDependencies enabled targetSet
231233
in case checkDeps (fromDepMap deps) of
@@ -262,15 +264,15 @@ resolveWithFlags dom enabled os arch impl constrs trees checkDeps =
262264
-- can determine that Buildable is always True, it returns the input unchanged.
263265
-- If Buildable is always False, it returns the empty 'CondTree'.
264266
addBuildableCondition
265-
:: (Eq v, Monoid a, Monoid c)
267+
:: (Eq v, Monoid a)
266268
=> (a -> BuildInfo)
267-
-> CondTree v c a
268-
-> CondTree v c a
269+
-> CondTree v a
270+
-> CondTree v a
269271
addBuildableCondition getInfo t =
270272
case extractCondition (buildable . getInfo) t of
271273
Lit True -> t
272-
Lit False -> CondNode mempty mempty []
273-
c -> CondNode mempty mempty [condIfThen c t]
274+
Lit False -> CondNode mempty []
275+
c -> CondNode mempty [condIfThen c t]
274276

275277
-- | This is a special version of 'addBuildableCondition' for the 'PDTagged'
276278
-- type.
@@ -282,16 +284,18 @@ addBuildableCondition getInfo t =
282284
--
283285
-- See <https://github.com/haskell/cabal/pull/4094> for more details.
284286
addBuildableConditionPDTagged
285-
:: (Eq v, Monoid c)
286-
=> CondTree v c PDTagged
287-
-> CondTree v c PDTagged
287+
:: Eq v
288+
=> CondTree v PDTagged
289+
-> CondTree v PDTagged
288290
addBuildableConditionPDTagged t =
289291
case extractCondition (buildable . getInfo) t of
290292
Lit True -> t
291-
Lit False -> deleteConstraints t
292-
c -> CondNode mempty mempty [condIfThenElse c t (deleteConstraints t)]
293+
Lit False -> mapTreeData deleteConstraints t
294+
c -> CondNode mempty [condIfThenElse c t (mapTreeData deleteConstraints t)]
293295
where
294-
deleteConstraints = mapTreeConstrs (const mempty)
296+
deleteConstraints (Lib lib) = Lib (L.set L.targetBuildDepends mempty lib)
297+
deleteConstraints (SubComp unqualName comp) = SubComp unqualName (L.set L.targetBuildDepends mempty comp)
298+
deleteConstraints PDNull = PDNull
295299

296300
getInfo :: PDTagged -> BuildInfo
297301
getInfo (Lib l) = libBuildInfo l
@@ -326,10 +330,10 @@ extractConditions f gpkg =
326330
, extractCondition (f . benchmarkBuildInfo) . snd <$> condBenchmarks gpkg
327331
]
328332

329-
freeVars :: CondTree ConfVar c a -> [FlagName]
333+
freeVars :: CondTree ConfVar a -> [FlagName]
330334
freeVars t = [f | PackageFlag f <- freeVars' t]
331335
where
332-
freeVars' (CondNode _ _ ifs) = concatMap compfv ifs
336+
freeVars' (CondNode _ ifs) = concatMap compfv ifs
333337
compfv (CondBranch c ct mct) = condfv c ++ freeVars' ct ++ maybe [] freeVars' mct
334338
condfv c = case c of
335339
Var v -> [v]
@@ -406,6 +410,12 @@ instance Semigroup PDTagged where
406410
SubComp n x <> SubComp n' x' | n == n' = SubComp n (x <> x')
407411
_ <> _ = cabalBug "Cannot combine incompatible tags"
408412

413+
instance L.HasBuildInfo PDTagged where
414+
buildInfo f x = case x of
415+
Lib lib -> Lib <$> L.buildInfo f lib
416+
SubComp name comp -> SubComp name <$> L.buildInfo f comp
417+
PDNull -> PDNull <$ f mempty
418+
409419
-- | Create a package description with all configurations resolved.
410420
--
411421
-- This function takes a `GenericPackageDescription` and several environment
@@ -554,36 +564,47 @@ flattenPackageDescription
554564
where
555565
mlib = f <$> mlib0
556566
where
557-
f lib = (libFillInDefaults . fst . ignoreConditions $ lib){libName = LMainLibName}
567+
f :: CondTree ConfVar Library -> Library
568+
f lib = (libFillInDefaults . ignoreConditions $ lib){libName = LMainLibName}
558569
sub_libs = flattenLib <$> sub_libs0
559570
flibs = flattenFLib <$> flibs0
560571
exes = flattenExe <$> exes0
561572
tests = flattenTst <$> tests0
562573
bms = flattenBm <$> bms0
574+
575+
flattenLib :: (UnqualComponentName, CondTree ConfVar Library) -> Library
563576
flattenLib (n, t) =
564577
libFillInDefaults $
565-
(fst $ ignoreConditions t)
578+
(ignoreConditions t)
566579
{ libName = LSubLibName n
567580
, libExposed = False
568581
}
582+
583+
flattenFLib :: (UnqualComponentName, CondTree ConfVar ForeignLib) -> ForeignLib
569584
flattenFLib (n, t) =
570585
flibFillInDefaults $
571-
(fst $ ignoreConditions t)
586+
(ignoreConditions t)
572587
{ foreignLibName = n
573588
}
589+
590+
flattenExe :: (UnqualComponentName, CondTree ConfVar Executable) -> Executable
574591
flattenExe (n, t) =
575592
exeFillInDefaults $
576-
(fst $ ignoreConditions t)
593+
(ignoreConditions t)
577594
{ exeName = n
578595
}
596+
597+
flattenTst :: (UnqualComponentName, CondTree ConfVar TestSuite) -> TestSuite
579598
flattenTst (n, t) =
580599
testFillInDefaults $
581-
(fst $ ignoreConditions t)
600+
(ignoreConditions t)
582601
{ testName = n
583602
}
603+
604+
flattenBm :: (UnqualComponentName, CondTree ConfVar Benchmark) -> Benchmark
584605
flattenBm (n, t) =
585606
benchFillInDefaults $
586-
(fst $ ignoreConditions t)
607+
(ignoreConditions t)
587608
{ benchmarkName = n
588609
}
589610

@@ -640,8 +661,6 @@ transformAllBuildDepends
640661
transformAllBuildDepends f =
641662
over (L.traverseBuildInfos . L.targetBuildDepends . traverse) f
642663
. over (L.packageDescription . L.setupBuildInfo . traverse . L.setupDepends . traverse) f
643-
-- cannot be point-free as normal because of higher rank
644-
. over (\f' -> L.allCondTrees $ traverseCondTreeC f') (map f)
645664

646665
-- | Walk a 'GenericPackageDescription' and apply @f@ to all nested
647666
-- @build-depends@ fields.
@@ -652,5 +671,3 @@ transformAllBuildDependsN
652671
transformAllBuildDependsN f =
653672
over (L.traverseBuildInfos . L.targetBuildDepends) f
654673
. over (L.packageDescription . L.setupBuildInfo . traverse . L.setupDepends) f
655-
-- cannot be point-free as normal because of higher rank
656-
. over (\f' -> L.allCondTrees $ traverseCondTreeC f') f

Cabal-syntax/src/Distribution/PackageDescription/Parsec.hs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ goSections specVer = traverse_ process
263263
-> Map String CondTreeBuildInfo
264264
-- \^ common stanzas
265265
-> [Field Position]
266-
-> ParseResult src (CondTree ConfVar [Dependency] a)
266+
-> ParseResult src (CondTree ConfVar a)
267267
parseCondTree' = parseCondTreeWithCommonStanzas specVer
268268

269269
parseSection :: Name Position -> [SectionArg Position] -> [Field Position] -> SectionParser src ()
@@ -478,11 +478,9 @@ parseCondTree
478478
-- ^ common stanzas
479479
-> (BuildInfo -> a)
480480
-- ^ constructor from buildInfo
481-
-> (a -> [Dependency])
482-
-- ^ condition extractor
483481
-> [Field Position]
484-
-> ParseResult src (CondTree ConfVar [Dependency] a)
485-
parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go
482+
-> ParseResult src (CondTree ConfVar a)
483+
parseCondTree v hasElif grammar commonStanzas fromBuildInfo = go
486484
where
487485
go fields0 = do
488486
(fields, endo) <-
@@ -493,9 +491,9 @@ parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go
493491
let (fs, ss) = partitionFields fields
494492
x <- parseFieldGrammar v fs grammar
495493
branches <- concat <$> traverse parseIfs ss
496-
return $ endo $ CondNode x (cond x) branches
494+
return $ endo $ CondNode x branches
497495

498-
parseIfs :: [Section Position] -> ParseResult src [CondBranch ConfVar [Dependency] a]
496+
parseIfs :: [Section Position] -> ParseResult src [CondBranch ConfVar a]
499497
parseIfs [] = return []
500498
parseIfs (MkSection (Name pos name) test fields : sections) | name == "if" = do
501499
test' <- parseConditionConfVar (startOfSection (incPos 2 pos) test) test
@@ -508,7 +506,7 @@ parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go
508506

509507
parseElseIfs
510508
:: [Section Position]
511-
-> ParseResult src (Maybe (CondTree ConfVar [Dependency] a), [CondBranch ConfVar [Dependency] a])
509+
-> ParseResult src (Maybe (CondTree ConfVar a), [CondBranch ConfVar a])
512510
parseElseIfs [] = return (Nothing, [])
513511
parseElseIfs (MkSection (Name pos name) args fields : sections) | name == "else" = do
514512
unless (null args) $
@@ -525,7 +523,7 @@ parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go
525523
(elseFields, sections') <- parseElseIfs sections
526524
-- we parse an empty 'Fields', to get empty value for a node
527525
a <- parseFieldGrammar v mempty grammar
528-
return (Just $ CondNode a (cond a) [CondBranch test' fields' elseFields], sections')
526+
return (Just $ CondNode a [CondBranch test' fields' elseFields], sections')
529527
parseElseIfs (MkSection (Name pos name) _ _ : sections) | name == "elif" = do
530528
parseWarning pos PWTInvalidSubsection "invalid subsection \"elif\". You should set cabal-version: 2.2 or larger to use elif-conditionals."
531529
(,) Nothing <$> parseIfs sections
@@ -593,7 +591,7 @@ with new AST, this all need to be rewritten.
593591
-- The approach is simple, and have good properties:
594592
--
595593
-- * Common stanzas are parsed exactly once, even if not-used. Thus we report errors in them.
596-
type CondTreeBuildInfo = CondTree ConfVar [Dependency] BuildInfo
594+
type CondTreeBuildInfo = CondTree ConfVar BuildInfo
597595

598596
-- | Create @a@ from 'BuildInfo'.
599597
-- This class is used to implement common stanza parsing.
@@ -635,10 +633,10 @@ parseCondTreeWithCommonStanzas
635633
-> Map String CondTreeBuildInfo
636634
-- ^ common stanzas
637635
-> [Field Position]
638-
-> ParseResult src (CondTree ConfVar [Dependency] a)
636+
-> ParseResult src (CondTree ConfVar a)
639637
parseCondTreeWithCommonStanzas v grammar fromBuildInfo commonStanzas fields = do
640638
(fields', endo) <- processImports v fromBuildInfo commonStanzas fields
641-
x <- parseCondTree v hasElif grammar commonStanzas fromBuildInfo (view L.targetBuildDepends) fields'
639+
x <- parseCondTree v hasElif grammar commonStanzas fromBuildInfo fields'
642640
return (endo x)
643641
where
644642
hasElif = specHasElif v
@@ -652,7 +650,7 @@ processImports
652650
-> Map String CondTreeBuildInfo
653651
-- ^ common stanzas
654652
-> [Field Position]
655-
-> ParseResult src ([Field Position], CondTree ConfVar [Dependency] a -> CondTree ConfVar [Dependency] a)
653+
-> ParseResult src ([Field Position], CondTree ConfVar a -> CondTree ConfVar a)
656654
processImports v fromBuildInfo commonStanzas = go []
657655
where
658656
hasCommonStanzas = specHasCommonStanzas v
@@ -695,11 +693,11 @@ warnImport _ f = pure (Just f)
695693
mergeCommonStanza
696694
:: L.HasBuildInfo a
697695
=> (BuildInfo -> a)
698-
-> CondTree ConfVar [Dependency] BuildInfo
699-
-> CondTree ConfVar [Dependency] a
700-
-> CondTree ConfVar [Dependency] a
701-
mergeCommonStanza fromBuildInfo (CondNode bi _ bis) (CondNode x _ cs) =
702-
CondNode x' (x' ^. L.targetBuildDepends) cs'
696+
-> CondTree ConfVar BuildInfo
697+
-> CondTree ConfVar a
698+
-> CondTree ConfVar a
699+
mergeCommonStanza fromBuildInfo (CondNode bi bis) (CondNode x cs) =
700+
CondNode x' cs'
703701
where
704702
-- new value is old value with buildInfo field _prepended_.
705703
x' = x & L.buildInfo %~ (bi <>)
@@ -712,21 +710,21 @@ mergeCommonStanza fromBuildInfo (CondNode bi _ bis) (CondNode x _ cs) =
712710
-------------------------------------------------------------------------------
713711

714712
-- Check that a property holds on all branches of a condition tree
715-
onAllBranches :: forall v c a. Monoid a => (a -> Bool) -> CondTree v c a -> Bool
713+
onAllBranches :: forall v a. Monoid a => (a -> Bool) -> CondTree v a -> Bool
716714
onAllBranches p = go mempty
717715
where
718716
-- If the current level of the tree satisfies the property, then we are
719717
-- done. If not, then one of the conditional branches below the current node
720718
-- must satisfy it. Each node may have multiple immediate children; we only
721719
-- one need one to satisfy the property because the configure step uses
722720
-- 'mappend' to join together the results of flag resolution.
723-
go :: a -> CondTree v c a -> Bool
721+
go :: a -> CondTree v a -> Bool
724722
go acc ct =
725723
let acc' = acc `mappend` condTreeData ct
726724
in p acc' || any (goBranch acc') (condTreeComponents ct)
727725

728726
-- Both the 'true' and the 'false' block must satisfy the property.
729-
goBranch :: a -> CondBranch v c a -> Bool
727+
goBranch :: a -> CondBranch v a -> Bool
730728
goBranch _ (CondBranch _ _ Nothing) = False
731729
goBranch acc (CondBranch _ t (Just e)) = go acc t && go acc e
732730

@@ -750,7 +748,7 @@ checkForUndefinedFlags gpd = do
750748
"These flags are used without having been defined: "
751749
++ intercalate ", " [unFlagName fn | fn <- Set.toList $ usedFlags `Set.difference` definedFlags]
752750
where
753-
f :: CondTree ConfVar c a -> Const (Set.Set FlagName) (CondTree ConfVar c a)
751+
f :: CondTree ConfVar a -> Const (Set.Set FlagName) (CondTree ConfVar a)
754752
f ct = Const (Set.fromList (freeVars ct))
755753

756754
-- | Since @cabal-version: 1.24@ one can specify @custom-setup@.

0 commit comments

Comments
 (0)