@@ -418,30 +418,36 @@ parseFields v fields grammar = do
418
418
419
419
warnInvalidSubsection :: Section Position -> ParseResult ()
420
420
warnInvalidSubsection (MkSection (Name pos name) _ _) =
421
- void ( parseFailure pos $ " invalid subsection " ++ show name)
421
+ void $ parseFailure pos $ " invalid subsection " ++ show name
422
422
423
423
parseCondTree
424
- :: forall a c .
425
- CabalSpecVersion
426
- -> HasElif -- ^ accept @elif@
427
- -> ParsecFieldGrammar' a -- ^ grammar
428
- -> (a -> c ) -- ^ condition extractor
424
+ :: forall a . L. HasBuildInfo a
425
+ => CabalSpecVersion
426
+ -> HasElif -- ^ accept @elif@
427
+ -> ParsecFieldGrammar' a -- ^ grammar
428
+ -> Map String CondTreeBuildInfo -- ^ common stanzas
429
+ -> (BuildInfo -> a ) -- ^ constructor from buildInfo
430
+ -> (a -> [Dependency ]) -- ^ condition extractor
429
431
-> [Field Position ]
430
- -> ParseResult (CondTree ConfVar c a )
431
- parseCondTree v hasElif grammar cond = go
432
+ -> ParseResult (CondTree ConfVar [ Dependency ] a )
433
+ parseCondTree v hasElif grammar commonStanzas fromBuildInfo cond = go
432
434
where
433
- go fields = do
435
+ go fields0 = do
436
+ (fields, endo) <-
437
+ if v >= CabalSpecV3_0
438
+ then processImports v fromBuildInfo commonStanzas fields0
439
+ else traverse (warnImport v) fields0 >>= \ fields1 -> return (catMaybes fields1, id )
440
+
434
441
let (fs, ss) = partitionFields fields
435
442
x <- parseFieldGrammar v fs grammar
436
443
branches <- concat <$> traverse parseIfs ss
437
- return ( CondNode x (cond x) branches) -- TODO: branches
444
+ return $ endo $ CondNode x (cond x) branches
438
445
439
- parseIfs :: [Section Position ] -> ParseResult [CondBranch ConfVar c a ]
446
+ parseIfs :: [Section Position ] -> ParseResult [CondBranch ConfVar [ Dependency ] a ]
440
447
parseIfs [] = return []
441
448
parseIfs (MkSection (Name _ name) test fields : sections) | name == " if" = do
442
449
test' <- parseConditionConfVar test
443
450
fields' <- go fields
444
- -- TODO: else
445
451
(elseFields, sections') <- parseElseIfs sections
446
452
return (CondBranch test' fields' elseFields : sections')
447
453
parseIfs (MkSection (Name pos name) _ _ : sections) = do
@@ -450,7 +456,7 @@ parseCondTree v hasElif grammar cond = go
450
456
451
457
parseElseIfs
452
458
:: [Section Position ]
453
- -> ParseResult (Maybe (CondTree ConfVar c a ), [CondBranch ConfVar c a ])
459
+ -> ParseResult (Maybe (CondTree ConfVar [ Dependency ] a ), [CondBranch ConfVar [ Dependency ] a ])
454
460
parseElseIfs [] = return (Nothing , [] )
455
461
parseElseIfs (MkSection (Name pos name) args fields : sections) | name == " else" = do
456
462
unless (null args) $
@@ -459,10 +465,7 @@ parseCondTree v hasElif grammar cond = go
459
465
sections' <- parseIfs sections
460
466
return (Just elseFields, sections')
461
467
462
-
463
-
464
468
parseElseIfs (MkSection (Name _ name) test fields : sections) | hasElif == HasElif , name == " elif" = do
465
- -- TODO: check cabal-version
466
469
test' <- parseConditionConfVar test
467
470
fields' <- go fields
468
471
(elseFields, sections') <- parseElseIfs sections
@@ -566,21 +569,32 @@ parseCondTreeWithCommonStanzas
566
569
-> Map String CondTreeBuildInfo -- ^ common stanzas
567
570
-> [Field Position ]
568
571
-> ParseResult (CondTree ConfVar [Dependency ] a )
569
- parseCondTreeWithCommonStanzas v grammar fromBuildInfo commonStanzas = goImports []
572
+ parseCondTreeWithCommonStanzas v grammar fromBuildInfo commonStanzas fields = do
573
+ (fields', endo) <- processImports v fromBuildInfo commonStanzas fields
574
+ x <- parseCondTree v hasElif grammar commonStanzas fromBuildInfo (view L. targetBuildDepends) fields'
575
+ return (endo x)
570
576
where
571
577
hasElif = specHasElif v
578
+
579
+ processImports
580
+ :: forall a . L. HasBuildInfo a
581
+ => CabalSpecVersion
582
+ -> (BuildInfo -> a ) -- ^ construct fromBuildInfo
583
+ -> Map String CondTreeBuildInfo -- ^ common stanzas
584
+ -> [Field Position ]
585
+ -> ParseResult ([Field Position ], CondTree ConfVar [Dependency ] a -> CondTree ConfVar [Dependency ] a )
586
+ processImports v fromBuildInfo commonStanzas = go []
587
+ where
572
588
hasCommonStanzas = specHasCommonStanzas v
573
589
574
590
getList' :: List CommaFSep Token String -> [String ]
575
591
getList' = Newtype. unpack
576
592
577
- -- parse leading imports
578
- -- not supported:
579
- goImports acc (Field (Name pos name) _ : fields) | name == " import" , hasCommonStanzas == NoCommonStanzas = do
593
+ go acc (Field (Name pos name) _ : fields) | name == " import" , hasCommonStanzas == NoCommonStanzas = do
580
594
parseWarning pos PWTUnknownField " Unknown field: import. You should set cabal-version: 2.2 or larger to use common stanzas"
581
- goImports acc fields
595
+ go acc fields
582
596
-- supported:
583
- goImports acc (Field (Name pos name) fls : fields) | name == " import" = do
597
+ go acc (Field (Name pos name) fls : fields) | name == " import" = do
584
598
names <- getList' <$> runFieldParser pos parsec v fls
585
599
names' <- for names $ \ commonName ->
586
600
case Map. lookup commonName commonStanzas of
@@ -590,16 +604,21 @@ parseCondTreeWithCommonStanzas v grammar fromBuildInfo commonStanzas = goImports
590
604
Just commonTree ->
591
605
pure (Just commonTree)
592
606
593
- goImports (acc ++ catMaybes names') fields
594
-
595
- -- Go to parsing condTree after first non-import 'Field'.
596
- goImports acc fields = go acc fields
607
+ go (acc ++ catMaybes names') fields
597
608
598
609
-- parse actual CondTree
599
- go :: [CondTreeBuildInfo ] -> [Field Position ] -> ParseResult (CondTree ConfVar [Dependency ] a )
600
- go bis fields = do
601
- x <- parseCondTree v hasElif grammar (view L. targetBuildDepends) fields
602
- pure $ foldr (mergeCommonStanza fromBuildInfo) x bis
610
+ go acc fields = do
611
+ fields' <- catMaybes <$> traverse (warnImport v) fields
612
+ pure $ (fields', \ x -> foldr (mergeCommonStanza fromBuildInfo) x acc)
613
+
614
+ -- | Warn on "import" fields, also map to Maybe, so errorneous fields can be filtered
615
+ warnImport :: CabalSpecVersion -> Field Position -> ParseResult (Maybe (Field Position ))
616
+ warnImport v (Field (Name pos name) _) | name == " import" = do
617
+ if specHasCommonStanzas v == NoCommonStanzas
618
+ then parseWarning pos PWTUnknownField " Unknown field: import. You should set cabal-version: 2.2 or larger to use common stanzas"
619
+ else parseWarning pos PWTUnknownField " Unknown field: import. Common stanza imports should be at the top of the enclosing section"
620
+ return Nothing
621
+ warnImport _ f = pure (Just f)
603
622
604
623
mergeCommonStanza
605
624
:: L. HasBuildInfo a
0 commit comments