@@ -61,6 +61,7 @@ import Distribution.Text (display)
61
61
import Distribution.Types.CondTree
62
62
import Distribution.Types.Dependency (Dependency )
63
63
import Distribution.Types.ForeignLib
64
+ import Distribution.Types.ForeignLibType (knownForeignLibTypes )
64
65
import Distribution.Types.GenericPackageDescription (emptyGenericPackageDescription )
65
66
import Distribution.Types.PackageDescription (specVersion' )
66
67
import Distribution.Types.UnqualComponentName (UnqualComponentName , mkUnqualComponentName )
@@ -306,6 +307,16 @@ goSections specVer = traverse_ process
306
307
commonStanzas <- use stateCommonStanzas
307
308
name' <- parseUnqualComponentName pos args
308
309
flib <- lift $ parseCondTree' (foreignLibFieldGrammar name') commonStanzas fields
310
+
311
+ let hasType ts = foreignLibType ts /= foreignLibType mempty
312
+ unless (onAllBranches hasType flib) $ lift $ parseFailure pos $ concat
313
+ [ " Foreign library " ++ show (display name')
314
+ , " is missing required field \" type\" or the field "
315
+ , " is not present in all conditional branches. The "
316
+ , " available test types are: "
317
+ , intercalate " , " (map display knownForeignLibTypes)
318
+ ]
319
+
309
320
-- TODO check duplicate name here?
310
321
stateGpd . L. condForeignLibs %= snoc (name', flib)
311
322
@@ -321,6 +332,16 @@ goSections specVer = traverse_ process
321
332
name' <- parseUnqualComponentName pos args
322
333
testStanza <- lift $ parseCondTree' testSuiteFieldGrammar commonStanzas fields
323
334
testSuite <- lift $ traverse (validateTestSuite pos) testStanza
335
+
336
+ let hasType ts = testInterface ts /= testInterface mempty
337
+ unless (onAllBranches hasType testSuite) $ lift $ parseFailure pos $ concat
338
+ [ " Test suite " ++ show (display name')
339
+ , " is missing required field \" type\" or the field "
340
+ , " is not present in all conditional branches. The "
341
+ , " available test types are: "
342
+ , intercalate " , " (map display knownTestTypes)
343
+ ]
344
+
324
345
-- TODO check duplicate name here?
325
346
stateGpd . L. condTestSuites %= snoc (name', testSuite)
326
347
@@ -329,6 +350,16 @@ goSections specVer = traverse_ process
329
350
name' <- parseUnqualComponentName pos args
330
351
benchStanza <- lift $ parseCondTree' benchmarkFieldGrammar commonStanzas fields
331
352
bench <- lift $ traverse (validateBenchmark pos) benchStanza
353
+
354
+ let hasType ts = benchmarkInterface ts /= benchmarkInterface mempty
355
+ unless (onAllBranches hasType bench) $ lift $ parseFailure pos $ concat
356
+ [ " Benchmark " ++ show (display name')
357
+ , " is missing required field \" type\" or the field "
358
+ , " is not present in all conditional branches. The "
359
+ , " available benchmark types are: "
360
+ , intercalate " , " (map display knownBenchmarkTypes)
361
+ ]
362
+
332
363
-- TODO check duplicate name here?
333
364
stateGpd . L. condBenchmarks %= snoc (name', bench)
334
365
@@ -599,6 +630,28 @@ mergeCommonStanza (CondNode bi _ bis) (CondNode x _ cs) =
599
630
-- tree components are appended together.
600
631
cs' = map (fmap fromBuildInfo) bis ++ cs
601
632
633
+ -------------------------------------------------------------------------------
634
+ -- Branches
635
+ -------------------------------------------------------------------------------
636
+
637
+ -- Check that a property holds on all branches of a condition tree
638
+ onAllBranches :: forall v c a . Monoid a => (a -> Bool ) -> CondTree v c a -> Bool
639
+ onAllBranches p = go mempty
640
+ where
641
+ -- If the current level of the tree satisfies the property, then we are
642
+ -- done. If not, then one of the conditional branches below the current node
643
+ -- must satisfy it. Each node may have multiple immediate children; we only
644
+ -- one need one to satisfy the property because the configure step uses
645
+ -- 'mappend' to join together the results of flag resolution.
646
+ go :: a -> CondTree v c a -> Bool
647
+ go acc ct = let acc' = acc `mappend` condTreeData ct
648
+ in p acc' || any (goBranch acc') (condTreeComponents ct)
649
+
650
+ -- Both the 'true' and the 'false' block must satisfy the property.
651
+ goBranch :: a -> CondBranch v c a -> Bool
652
+ goBranch _ (CondBranch _ _ Nothing ) = False
653
+ goBranch acc (CondBranch _ t (Just e)) = go acc t && go acc e
654
+
602
655
-------------------------------------------------------------------------------
603
656
-- Old syntax
604
657
-------------------------------------------------------------------------------
0 commit comments