Skip to content

Commit 0763988

Browse files
committed
CabalSpecVersion
1 parent 907b49c commit 0763988

File tree

8 files changed

+167
-103
lines changed

8 files changed

+167
-103
lines changed

Cabal/Cabal.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ library
130130
Distribution.Backpack.ModSubst
131131
Distribution.Backpack.ModuleShape
132132
Distribution.Backpack.PreModuleShape
133+
Distribution.CabalSpecVersion
133134
Distribution.Utils.IOData
134135
Distribution.Utils.LogProgress
135136
Distribution.Utils.MapAccum
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{-# LANGUAGE FlexibleContexts, RankNTypes #-}
2+
module Distribution.CabalSpecVersion where
3+
4+
import Distribution.Parsec.Class (Parsec (..), ParsecParser)
5+
6+
-- A class to select how to parse different fields.
7+
class CabalSpecVersion v where
8+
-- | @v@ can act as own proxy
9+
cabalSpecVersion :: v
10+
11+
versionedParsec :: Parsec a => v -> ParsecParser a
12+
13+
-- given a version since something is available, do we support it?
14+
versionedAvailable :: v -> [Int] -> Bool
15+
16+
specHasElif :: v -> HasElif
17+
18+
data SpecVersionOld = SpecVersionOld
19+
data SpecVersion22 = SpecVersion22
20+
21+
instance CabalSpecVersion SpecVersionOld where
22+
cabalSpecVersion = SpecVersionOld
23+
versionedParsec _ = parsec
24+
versionedAvailable _ vs = vs < [2,1]
25+
specHasElif _ = NoElif
26+
27+
instance CabalSpecVersion SpecVersion22 where
28+
cabalSpecVersion = SpecVersion22
29+
versionedParsec _ = parsec22
30+
versionedAvailable _ _ = True
31+
specHasElif _ = HasElif
32+
33+
-------------------------------------------------------------------------------
34+
-- HasElif
35+
-------------------------------------------------------------------------------
36+
37+
data HasElif = HasElif | NoElif
38+
deriving (Eq, Show)

Cabal/Distribution/FieldGrammar.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ import Distribution.FieldGrammar.Pretty
4040
import Distribution.Parsec.Field
4141
import Distribution.Utils.Generic (spanMaybe)
4242

43-
type ParsecFieldGrammar' a = ParsecFieldGrammar a a
44-
type PrettyFieldGrammar' a = PrettyFieldGrammar a a
43+
type ParsecFieldGrammar' v a = ParsecFieldGrammar v a a
44+
type PrettyFieldGrammar' a = PrettyFieldGrammar a a
4545

4646
infixl 5 ^^^
4747

Cabal/Distribution/FieldGrammar/Parsec.hs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
{-# LANGUAGE DeriveFunctor #-}
2-
{-# LANGUAGE OverloadedStrings #-}
1+
{-# LANGUAGE DeriveFunctor #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE ScopedTypeVariables #-}
34
-- | This module provides a 'FieldGrammarParser', one way to parse
45
-- @.cabal@ -like files.
56
--
@@ -61,16 +62,18 @@ module Distribution.FieldGrammar.Parsec (
6162
runFieldParser',
6263
) where
6364

65+
import Data.List (dropWhileEnd)
66+
import Data.Ord (comparing)
67+
import Data.Set (Set)
68+
import Distribution.CabalSpecVersion
69+
import Distribution.Compat.Newtype
70+
import Distribution.Compat.Prelude
71+
import Distribution.Simple.Utils (fromUTF8BS)
72+
import Prelude ()
73+
6474
import qualified Data.ByteString as BS
65-
import Data.List (dropWhileEnd)
66-
import Data.Ord (comparing)
67-
import Data.Set (Set)
6875
import qualified Data.Set as Set
6976
import qualified Distribution.Compat.Map.Strict as Map
70-
import Distribution.Compat.Prelude
71-
import Distribution.Compat.Newtype
72-
import Distribution.Simple.Utils (fromUTF8BS)
73-
import Prelude ()
7477
import qualified Text.Parsec as P
7578
import qualified Text.Parsec.Error as P
7679

@@ -98,14 +101,14 @@ data Section ann = MkSection !(Name ann) [SectionArg ann] [Field ann]
98101
-- ParsecFieldGrammar
99102
-------------------------------------------------------------------------------
100103

101-
data ParsecFieldGrammar s a = ParsecFG
104+
data ParsecFieldGrammar v s a = ParsecFG
102105
{ fieldGrammarKnownFields :: !(Set FieldName)
103106
, fieldGrammarKnownPrefixes :: !(Set FieldName)
104107
, fieldGrammarParser :: !(Fields Position -> ParseResult a)
105108
}
106109
deriving (Functor)
107110

108-
parseFieldGrammar :: Fields Position -> ParsecFieldGrammar s a -> ParseResult a
111+
parseFieldGrammar :: Fields Position -> ParsecFieldGrammar v s a -> ParseResult a
109112
parseFieldGrammar fields grammar = do
110113
for_ (Map.toList (Map.filterWithKey isUnknownField fields)) $ \(name, nfields) ->
111114
for_ nfields $ \(MkNamelessField pos _) ->
@@ -120,10 +123,10 @@ parseFieldGrammar fields grammar = do
120123
k `Set.member` fieldGrammarKnownFields grammar
121124
|| any (`BS.isPrefixOf` k) (fieldGrammarKnownPrefixes grammar)
122125

123-
fieldGrammarKnownFieldList :: ParsecFieldGrammar s a -> [FieldName]
126+
fieldGrammarKnownFieldList :: ParsecFieldGrammar v s a -> [FieldName]
124127
fieldGrammarKnownFieldList = Set.toList . fieldGrammarKnownFields
125128

126-
instance Applicative (ParsecFieldGrammar s) where
129+
instance Applicative (ParsecFieldGrammar v s) where
127130
pure x = ParsecFG mempty mempty (\_ -> pure x)
128131
{-# INLINE pure #-}
129132

@@ -133,7 +136,7 @@ instance Applicative (ParsecFieldGrammar s) where
133136
(\fields -> f'' fields <*> x'' fields)
134137
{-# INLINE (<*>) #-}
135138

136-
instance FieldGrammar ParsecFieldGrammar where
139+
instance CabalSpecVersion v => FieldGrammar (ParsecFieldGrammar v) where
137140
blurFieldGrammar _ (ParsecFG s s' parser) = ParsecFG s s' parser
138141

139142
uniqueFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
@@ -147,7 +150,7 @@ instance FieldGrammar ParsecFieldGrammar where
147150
Just xs-> parseOne (last xs)
148151

149152
parseOne (MkNamelessField pos fls) =
150-
unpack' _pack <$> runFieldParser pos parsec fls
153+
unpack' _pack <$> runFieldParser pos (versionedParsec (cabalSpecVersion :: v)) fls
151154

152155
booleanFieldDef fn _extract def = ParsecFG (Set.singleton fn) Set.empty parser
153156
where
@@ -160,7 +163,7 @@ instance FieldGrammar ParsecFieldGrammar where
160163
-- TODO: warn about duplicate optional fields?
161164
Just xs -> parseOne (last xs)
162165

163-
parseOne (MkNamelessField pos fls) = runFieldParser pos parsec fls
166+
parseOne (MkNamelessField pos fls) = runFieldParser pos (versionedParsec (cabalSpecVersion :: v)) fls
164167

165168
optionalFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
166169
where
@@ -173,15 +176,15 @@ instance FieldGrammar ParsecFieldGrammar where
173176

174177
parseOne (MkNamelessField pos fls)
175178
| null fls = pure Nothing
176-
| otherwise = Just . (unpack' _pack) <$> runFieldParser pos parsec fls
179+
| otherwise = Just . (unpack' _pack) <$> runFieldParser pos (versionedParsec (cabalSpecVersion :: v)) fls
177180

178181
monoidalFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser
179182
where
180183
parser fields = case Map.lookup fn fields of
181184
Nothing -> pure mempty
182185
Just xs -> foldMap (unpack' _pack) <$> traverse parseOne xs
183186

184-
parseOne (MkNamelessField pos fls) = runFieldParser pos parsec fls
187+
parseOne (MkNamelessField pos fls) = runFieldParser pos (versionedParsec (cabalSpecVersion :: v)) fls
185188

186189
prefixedFields fnPfx _extract = ParsecFG mempty (Set.singleton fnPfx) (pure . parser)
187190
where
@@ -199,6 +202,7 @@ instance FieldGrammar ParsecFieldGrammar where
199202
trim :: String -> String
200203
trim = dropWhile isSpace . dropWhileEnd isSpace
201204

205+
-- TODO: use versionedAvailable to drop parsing if old field.
202206
availableSince _ = id
203207

204208
deprecatedSince (_ : _) _ grammar = grammar -- pass on non-empty version

Cabal/Distribution/PackageDescription/FieldGrammar.hs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import Distribution.Compat.Lens
4343
import Distribution.Compat.Prelude
4444
import Prelude ()
4545

46+
import Distribution.CabalSpecVersion
4647
import Distribution.Compiler (CompilerFlavor (..))
4748
import Distribution.FieldGrammar
4849
import Distribution.License (License (..))
@@ -127,7 +128,8 @@ libraryFieldGrammar n = Library n
127128
<*> monoidalFieldAla "signatures" (alaList' VCat MQuoted) L.signatures
128129
<*> booleanFieldDef "exposed" L.libExposed True
129130
<*> blurFieldGrammar L.libBuildInfo buildInfoFieldGrammar
130-
{-# SPECIALIZE libraryFieldGrammar :: Maybe UnqualComponentName -> ParsecFieldGrammar' Library #-}
131+
{-# SPECIALIZE libraryFieldGrammar :: Maybe UnqualComponentName -> ParsecFieldGrammar' SpecVersionOld Library #-}
132+
{-# SPECIALIZE libraryFieldGrammar :: Maybe UnqualComponentName -> ParsecFieldGrammar' SpecVersion22 Library #-}
131133
{-# SPECIALIZE libraryFieldGrammar :: Maybe UnqualComponentName -> PrettyFieldGrammar' Library #-}
132134

133135
-------------------------------------------------------------------------------
@@ -144,7 +146,8 @@ foreignLibFieldGrammar n = ForeignLib n
144146
<*> optionalField "lib-version-info" L.foreignLibVersionInfo
145147
<*> optionalField "lib-version-linux" L.foreignLibVersionLinux
146148
<*> monoidalFieldAla "mod-def-file" (alaList' FSep FilePathNT) L.foreignLibModDefFile
147-
{-# SPECIALIZE foreignLibFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' ForeignLib #-}
149+
{-# SPECIALIZE foreignLibFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' SpecVersionOld ForeignLib #-}
150+
{-# SPECIALIZE foreignLibFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' SpecVersion22 ForeignLib #-}
148151
{-# SPECIALIZE foreignLibFieldGrammar :: UnqualComponentName -> PrettyFieldGrammar' ForeignLib #-}
149152

150153
-------------------------------------------------------------------------------
@@ -159,7 +162,8 @@ executableFieldGrammar n = Executable n
159162
<$> optionalFieldDefAla "main-is" FilePathNT L.modulePath ""
160163
<*> monoidalField "scope" L.exeScope
161164
<*> blurFieldGrammar L.buildInfo buildInfoFieldGrammar
162-
{-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' Executable #-}
165+
{-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' SpecVersionOld Executable #-}
166+
{-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> ParsecFieldGrammar' SpecVersion22 Executable #-}
163167
{-# SPECIALIZE executableFieldGrammar :: UnqualComponentName -> PrettyFieldGrammar' Executable #-}
164168

165169
-------------------------------------------------------------------------------
@@ -398,7 +402,8 @@ buildInfoFieldGrammar = BuildInfo
398402
<*> prefixedFields "x-" L.customFieldsBI
399403
<*> monoidalFieldAla "build-depends" (alaList CommaVCat) L.targetBuildDepends
400404
<*> monoidalFieldAla "mixins" (alaList CommaVCat) L.mixins
401-
{-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' BuildInfo #-}
405+
{-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' SpecVersionOld BuildInfo #-}
406+
{-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' SpecVersion22 BuildInfo #-}
402407
{-# SPECIALIZE buildInfoFieldGrammar :: PrettyFieldGrammar' BuildInfo #-}
403408

404409
hsSourceDirsGrammar
@@ -481,7 +486,8 @@ flagFieldGrammar name = MkFlag name
481486
<$> optionalFieldDefAla "description" FreeText L.flagDescription ""
482487
<*> booleanFieldDef "default" L.flagDefault True
483488
<*> booleanFieldDef "manual" L.flagManual False
484-
{-# SPECIALIZE flagFieldGrammar :: FlagName -> ParsecFieldGrammar' Flag #-}
489+
{-# SPECIALIZE flagFieldGrammar :: FlagName -> ParsecFieldGrammar' SpecVersionOld Flag #-}
490+
{-# SPECIALIZE flagFieldGrammar :: FlagName -> ParsecFieldGrammar' SpecVersion22 Flag #-}
485491
{-# SPECIALIZE flagFieldGrammar :: FlagName -> PrettyFieldGrammar' Flag #-}
486492

487493
-------------------------------------------------------------------------------
@@ -498,7 +504,8 @@ sourceRepoFieldGrammar kind = SourceRepo kind
498504
<*> optionalFieldAla "branch" Token L.repoBranch
499505
<*> optionalFieldAla "tag" Token L.repoTag
500506
<*> optionalFieldAla "subdir" FilePathNT L.repoSubdir
501-
{-# SPECIALIZE sourceRepoFieldGrammar :: RepoKind -> ParsecFieldGrammar' SourceRepo #-}
507+
{-# SPECIALIZE sourceRepoFieldGrammar :: RepoKind -> ParsecFieldGrammar' SpecVersionOld SourceRepo #-}
508+
{-# SPECIALIZE sourceRepoFieldGrammar :: RepoKind -> ParsecFieldGrammar' SpecVersion22 SourceRepo #-}
502509
{-# SPECIALIZE sourceRepoFieldGrammar :: RepoKind ->PrettyFieldGrammar' SourceRepo #-}
503510

504511
-------------------------------------------------------------------------------
@@ -510,5 +517,6 @@ setupBInfoFieldGrammar
510517
=> Bool -> g SetupBuildInfo SetupBuildInfo
511518
setupBInfoFieldGrammar def = flip SetupBuildInfo def
512519
<$> monoidalFieldAla "setup-depends" (alaList CommaVCat) L.setupDepends
513-
{-# SPECIALIZE setupBInfoFieldGrammar :: Bool -> ParsecFieldGrammar' SetupBuildInfo #-}
520+
{-# SPECIALIZE setupBInfoFieldGrammar :: Bool -> ParsecFieldGrammar' SpecVersionOld SetupBuildInfo #-}
521+
{-# SPECIALIZE setupBInfoFieldGrammar :: Bool -> ParsecFieldGrammar' SpecVersion22 SetupBuildInfo #-}
514522
{-# SPECIALIZE setupBInfoFieldGrammar :: Bool ->PrettyFieldGrammar' SetupBuildInfo #-}

0 commit comments

Comments
 (0)