Skip to content

Commit 1a9cc91

Browse files
committed
WIP
1 parent e5a868c commit 1a9cc91

File tree

1 file changed

+65
-4
lines changed

1 file changed

+65
-4
lines changed

cabal-install-parsers/src/Cabal/Project.hs

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{-# LANGUAGE DeriveTraversable #-}
66
{-# LANGUAGE MultiWayIf #-}
77
{-# LANGUAGE OverloadedStrings #-}
8+
{-# LANGUAGE ScopedTypeVariables #-}
89
-- | License: GPL-3.0-or-later AND BSD-3-Clause
910
--
1011
module Cabal.Project (
@@ -59,6 +60,7 @@ import qualified Distribution.FieldGrammar as C
5960
import qualified Distribution.Fields as C
6061
import qualified Distribution.PackageDescription as C
6162
import qualified Distribution.Parsec as C
63+
import qualified Distribution.Fields.ConfVar as C
6264

6365
import Cabal.Internal.Glob
6466
import Cabal.Internal.Newtypes
@@ -154,7 +156,7 @@ instance (NFData c, NFData b, NFData a) => NFData (Project c b a) where
154156
rnf x7 `seq` rnf x8 `seq` rnf x9 `seq`
155157
rnfList rnfPrettyField x10
156158
where
157-
rnfList :: (a -> ()) -> [a] -> ()
159+
rnfList :: (x -> ()) -> [x] -> ()
158160
rnfList _ [] = ()
159161
rnfList f (x:xs) = f x `seq` rnfList f xs
160162

@@ -227,13 +229,13 @@ parseProject = parseWith $ \fields0 -> do
227229
-- Right (CondNode {condTreeData = ["foo","bar/*.cabal"], condTreeConstraints = (), condTreeComponents = []})
228230
--
229231
parseProjectWithConditionals :: FilePath -> ByteString -> Either (ParseError NonEmpty) (C.CondTree C.ConfVar () (Project Void String String))
230-
parseProjectWithConditionals = parseWith $ \fields0 -> do
231-
let (fields1, sections) = C.partitionFields fields0
232+
parseProjectWithConditionals = parseWith $ \fields0 -> flip parseCondTree fields0 $ \fields1 sections -> do
232233
let fields2 = M.filterWithKey (\k _ -> k `elem` knownFields) fields1
233-
(\n -> C.CondNode n () []) <$> parse fields0 fields2 sections
234+
parse fields0 fields2 sections
234235
where
235236
knownFields = C.fieldGrammarKnownFieldList $ grammar []
236237

238+
parse :: [C.Field a] -> C.Fields C.Position -> [[C.Section C.Position]] -> C.ParseResult (Project Void String String)
237239
parse otherFields fields sections = do
238240
let prettyOtherFields = map void $ C.fromParsecFields $ filter otherFieldName otherFields
239241
prj <- C.parseFieldGrammar C.cabalSpecLatest fields $ grammar prettyOtherFields
@@ -419,3 +421,62 @@ readPackagesOfProject :: Project uri opt FilePath -> IO (Either (ParseError NonE
419421
readPackagesOfProject prj = runExceptT $ for prj $ \fp -> do
420422
contents <- liftIO $ BS.readFile fp
421423
either throwE (\gpd -> return (fp, gpd)) (parsePackage fp contents)
424+
425+
-------------------------------------------------------------------------------
426+
-- Read package files
427+
-------------------------------------------------------------------------------
428+
429+
parseCondTree
430+
:: forall a. (C.Fields C.Position -> [[C.Section C.Position]] -> C.ParseResult a) -- ^ parse
431+
-> [C.Field C.Position]
432+
-> C.ParseResult (C.CondTree C.ConfVar () a)
433+
parseCondTree subparse = go
434+
where
435+
go fields = do
436+
let (fs, ss) = C.partitionFields fields
437+
(ss', branches) <- second concat . unzip <$> traverse (parseIfs id id) ss
438+
x <- subparse fs ss'
439+
return $ C.CondNode x () branches
440+
441+
parseIfs
442+
:: ([C.Section C.Position] -> [C.Section C.Position])
443+
-> ([C.CondBranch C.ConfVar () a] -> [C.CondBranch C.ConfVar () a])
444+
-> [C.Section C.Position]
445+
-> C.ParseResult ([C.Section C.Position], [C.CondBranch C.ConfVar () a])
446+
parseIfs accS accB [] = return (accS [], accB [])
447+
parseIfs accS accB (C.MkSection (C.Name _ name) test fields : sections) | name == "if" = do
448+
test' <- C.parseConditionConfVar test
449+
fields' <- go fields
450+
-- TODO: (elseFields, sections') <- parseElseIfs sections
451+
let condTree :: C.CondBranch C.ConfVar () a
452+
condTree = C.CondBranch test' fields' Nothing
453+
parseIfs accS (accB . (condTree :)) sections
454+
parseIfs accS accB (section : sections) = do
455+
parseIfs (accS . (section :)) accB sections
456+
457+
{-
458+
parseElseIfs
459+
:: [Section Position]
460+
-> ParseResult (Maybe (CondTree ConfVar [Dependency] a), [CondBranch ConfVar [Dependency] a])
461+
parseElseIfs [] = return (Nothing, [])
462+
parseElseIfs (MkSection (Name pos name) args fields : sections) | name == "else" = do
463+
unless (null args) $
464+
parseFailure pos $
465+
"`else` section has section arguments " ++ show args
466+
elseFields <- go fields
467+
sections' <- parseIfs sections
468+
return (Just elseFields, sections')
469+
parseElseIfs (MkSection (Name _ name) test fields : sections)
470+
| hasElif == HasElif
471+
, name == "elif" = do
472+
test' <- parseConditionConfVar test
473+
fields' <- go fields
474+
(elseFields, sections') <- parseElseIfs sections
475+
-- we parse an empty 'Fields', to get empty value for a node
476+
a <- parseFieldGrammar v mempty grammar
477+
return (Just $ CondNode a (cond a) [CondBranch test' fields' elseFields], sections')
478+
parseElseIfs (MkSection (Name pos name) _ _ : sections) | name == "elif" = do
479+
parseWarning pos PWTInvalidSubsection $ "invalid subsection \"elif\". You should set cabal-version: 2.2 or larger to use elif-conditionals."
480+
(,) Nothing <$> parseIfs sections
481+
parseElseIfs sections = (,) Nothing <$> parseIfs sections
482+
-}

0 commit comments

Comments
 (0)