From ad1a0aa2b235b59921c3db275add099eb15754ed Mon Sep 17 00:00:00 2001 From: Finley McIlwaine Date: Wed, 8 May 2024 03:36:34 -0700 Subject: [PATCH] Remove CabalParsing class, specialize to ParsecParser Remove the `CharParsing` and `Parsing` classes, specialize all parsing logic to `Parsec`. Rename the `Distribution.Parsec.Parsec` class to `CabalParsec` to avoid ambiguity with `Text.Parsec.Parsec`. --- Cabal-described/src/Distribution/Described.hs | 4 +- Cabal-syntax/Cabal-syntax.cabal | 2 - Cabal-syntax/src/Distribution/Backpack.hs | 10 +- .../src/Distribution/Compat/CharParsing.hs | 360 ---------- .../src/Distribution/Compat/Parsing.hs | 370 ----------- Cabal-syntax/src/Distribution/Compiler.hs | 10 +- .../Distribution/FieldGrammar/FieldDescrs.hs | 19 +- .../src/Distribution/FieldGrammar/Newtypes.hs | 32 +- .../src/Distribution/FieldGrammar/Parsec.hs | 2 +- .../src/Distribution/Fields/ConfVar.hs | 5 +- Cabal-syntax/src/Distribution/License.hs | 4 +- Cabal-syntax/src/Distribution/ModuleName.hs | 18 +- .../PackageDescription/Configuration.hs | 7 +- .../PackageDescription/FieldGrammar.hs | 6 +- Cabal-syntax/src/Distribution/Parsec.hs | 622 ++++++++++++++---- Cabal-syntax/src/Distribution/SPDX/License.hs | 4 +- .../Distribution/SPDX/LicenseExceptionId.hs | 4 +- .../Distribution/SPDX/LicenseExpression.hs | 8 +- .../src/Distribution/SPDX/LicenseId.hs | 4 +- .../src/Distribution/SPDX/LicenseReference.hs | 4 +- Cabal-syntax/src/Distribution/System.hs | 10 +- Cabal-syntax/src/Distribution/Text.hs | 2 +- .../src/Distribution/Types/AbiDependency.hs | 4 +- .../src/Distribution/Types/AbiHash.hs | 4 +- .../src/Distribution/Types/BenchmarkType.hs | 4 +- .../src/Distribution/Types/BuildType.hs | 4 +- .../src/Distribution/Types/ComponentId.hs | 4 +- .../src/Distribution/Types/ComponentName.hs | 4 +- .../src/Distribution/Types/Dependency.hs | 6 +- .../src/Distribution/Types/ExeDependency.hs | 4 +- .../src/Distribution/Types/ExecutableScope.hs | 4 +- .../src/Distribution/Types/ExposedModule.hs | 4 +- Cabal-syntax/src/Distribution/Types/Flag.hs | 16 +- .../src/Distribution/Types/ForeignLib.hs | 4 +- .../Distribution/Types/ForeignLibOption.hs | 4 +- .../src/Distribution/Types/ForeignLibType.hs | 4 +- .../src/Distribution/Types/IncludeRenaming.hs | 4 +- .../InstalledPackageInfo/FieldGrammar.hs | 10 +- .../Distribution/Types/LegacyExeDependency.hs | 4 +- .../src/Distribution/Types/LibraryName.hs | 4 +- .../Distribution/Types/LibraryVisibility.hs | 4 +- Cabal-syntax/src/Distribution/Types/Mixin.hs | 6 +- Cabal-syntax/src/Distribution/Types/Module.hs | 4 +- .../src/Distribution/Types/ModuleReexport.hs | 4 +- .../src/Distribution/Types/ModuleRenaming.hs | 11 +- .../src/Distribution/Types/MungedPackageId.hs | 2 +- .../Distribution/Types/MungedPackageName.hs | 6 +- .../src/Distribution/Types/PackageId.hs | 6 +- .../src/Distribution/Types/PackageName.hs | 2 +- .../Types/PackageVersionConstraint.hs | 4 +- .../Distribution/Types/PkgconfigDependency.hs | 4 +- .../src/Distribution/Types/PkgconfigName.hs | 4 +- .../Distribution/Types/PkgconfigVersion.hs | 4 +- .../Types/PkgconfigVersionRange.hs | 6 +- .../src/Distribution/Types/SourceRepo.hs | 8 +- .../src/Distribution/Types/TestType.hs | 4 +- Cabal-syntax/src/Distribution/Types/UnitId.hs | 6 +- .../Distribution/Types/UnqualComponentName.hs | 2 +- .../src/Distribution/Types/Version.hs | 10 +- .../Types/VersionRange/Internal.hs | 22 +- Cabal-syntax/src/Distribution/Utils/Path.hs | 6 +- .../src/Language/Haskell/Extension.hs | 24 +- .../tests/UnitTests/Distribution/System.hs | 2 +- Cabal/Cabal.cabal | 2 - Cabal/src/Distribution/Simple/BuildTarget.hs | 10 +- .../Distribution/Simple/FileMonitor/Types.hs | 6 +- .../src/Distribution/Simple/Glob/Internal.hs | 10 +- Cabal/src/Distribution/Simple/Setup/Config.hs | 4 +- .../src/Distribution/Simple/Setup/Haddock.hs | 5 +- Cabal/src/Distribution/Simple/Setup/Test.hs | 7 +- Cabal/src/Distribution/Verbosity.hs | 6 +- .../src/Distribution/Solver/Types/Settings.hs | 6 +- .../Distribution/Client/BuildReports/Types.hs | 8 +- .../Client/CmdInstall/ClientInstallFlags.hs | 5 +- .../CmdInstall/ClientInstallTargetSelector.hs | 4 +- .../src/Distribution/Client/CmdOutdated.hs | 2 +- .../src/Distribution/Client/CmdUpdate.hs | 4 +- .../src/Distribution/Client/Compat/Prelude.hs | 2 +- .../src/Distribution/Client/Config.hs | 2 +- .../Distribution/Client/Dependency/Types.hs | 4 +- .../src/Distribution/Client/HttpUtils.hs | 2 +- .../Client/IndexUtils/ActiveRepos.hs | 8 +- .../Client/IndexUtils/IndexState.hs | 6 +- .../Client/IndexUtils/Timestamp.hs | 4 +- .../src/Distribution/Client/Init/Prompt.hs | 2 +- .../src/Distribution/Client/Init/Utils.hs | 2 +- .../src/Distribution/Client/Setup.hs | 7 +- .../src/Distribution/Client/TargetSelector.hs | 2 +- .../src/Distribution/Client/Targets.hs | 11 +- .../Distribution/Client/Types/AllowNewer.hs | 16 +- .../Client/Types/InstallMethod.hs | 4 +- .../Client/Types/OverwritePolicy.hs | 4 +- .../src/Distribution/Client/Types/Repo.hs | 6 +- .../src/Distribution/Client/Types/RepoName.hs | 4 +- changelog.d/pr-10081 | 16 + templates/SPDX.LicenseExceptionId.template.hs | 4 +- templates/SPDX.LicenseId.template.hs | 4 +- 97 files changed, 776 insertions(+), 1163 deletions(-) delete mode 100644 Cabal-syntax/src/Distribution/Compat/CharParsing.hs delete mode 100644 Cabal-syntax/src/Distribution/Compat/Parsing.hs create mode 100644 changelog.d/pr-10081 diff --git a/Cabal-described/src/Distribution/Described.hs b/Cabal-described/src/Distribution/Described.hs index 717fd6a5c7a..cea1a721d27 100644 --- a/Cabal-described/src/Distribution/Described.hs +++ b/Cabal-described/src/Distribution/Described.hs @@ -55,7 +55,7 @@ import Test.Tasty (TestTree, testGroup) import Test.Tasty.QuickCheck (testProperty) import Distribution.Compat.Semigroup (Semigroup (..)) -import Distribution.Parsec (Parsec, eitherParsec) +import Distribution.Parsec (CabalParsec, eitherParsec) import Distribution.Pretty (Pretty, prettyShow) import qualified Distribution.Utils.CharSet as CS @@ -105,7 +105,7 @@ import Distribution.Version (Version, VersionRange) import Language.Haskell.Extension (Extension, Language, knownLanguages) -- | Class describing the pretty/parsec format of a. -class (Pretty a, Parsec a) => Described a where +class (Pretty a, CabalParsec a) => Described a where -- | A pretty document of "regex" describing the field format describe :: proxy a -> GrammarRegex void diff --git a/Cabal-syntax/Cabal-syntax.cabal b/Cabal-syntax/Cabal-syntax.cabal index a1873228428..420baf31083 100644 --- a/Cabal-syntax/Cabal-syntax.cabal +++ b/Cabal-syntax/Cabal-syntax.cabal @@ -65,7 +65,6 @@ library Distribution.Backpack Distribution.CabalSpecVersion Distribution.Compat.Binary - Distribution.Compat.CharParsing Distribution.Compat.DList Distribution.Compat.Exception Distribution.Compat.Graph @@ -73,7 +72,6 @@ library Distribution.Compat.MonadFail Distribution.Compat.Newtype Distribution.Compat.NonEmptySet - Distribution.Compat.Parsing Distribution.Compat.Prelude Distribution.Compat.Semigroup Distribution.Compat.Typeable diff --git a/Cabal-syntax/src/Distribution/Backpack.hs b/Cabal-syntax/src/Distribution/Backpack.hs index b30028bc41c..415ded4214c 100644 --- a/Cabal-syntax/src/Distribution/Backpack.hs +++ b/Cabal-syntax/src/Distribution/Backpack.hs @@ -43,7 +43,7 @@ import Distribution.Pretty import Text.PrettyPrint (hcat) import Prelude () -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp import Distribution.ModuleName @@ -116,7 +116,7 @@ instance Pretty OpenUnitId where -- -- >>> eitherParsec "foo[Str=text-1.2.3:Data.Text.Text]" :: Either String OpenUnitId -- Right (IndefFullUnitId (ComponentId "foo") (fromList [(ModuleName "Str",OpenModule (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "text-1.2.3"})) (ModuleName "Data.Text.Text"))])) -instance Parsec OpenUnitId where +instance CabalParsec OpenUnitId where parsec = P.try parseOpenUnitId <|> fmap DefiniteUnitId parsec where parseOpenUnitId = do @@ -184,7 +184,7 @@ instance Pretty OpenModule where -- -- >>> eitherParsec "Includes2-0.1.0.0-inplace-mysql:Database.MySQL" :: Either String OpenModule -- Right (OpenModule (DefiniteUnitId (DefUnitId {unDefUnitId = UnitId "Includes2-0.1.0.0-inplace-mysql"})) (ModuleName "Database.MySQL")) -instance Parsec OpenModule where +instance CabalParsec OpenModule where parsec = parsecModuleVar <|> parsecOpenModule where parsecOpenModule = do @@ -228,7 +228,7 @@ dispOpenModuleSubstEntry (k, v) = pretty k <<>> Disp.char '=' <<>> pretty v -- | Inverse to 'dispModSubst'. -- -- @since 2.2 -parsecOpenModuleSubst :: CabalParsing m => m OpenModuleSubst +parsecOpenModuleSubst :: ParsecParser OpenModuleSubst parsecOpenModuleSubst = fmap Map.fromList . flip P.sepBy (P.char ',') @@ -237,7 +237,7 @@ parsecOpenModuleSubst = -- | Inverse to 'dispModSubstEntry'. -- -- @since 2.2 -parsecOpenModuleSubstEntry :: CabalParsing m => m (ModuleName, OpenModule) +parsecOpenModuleSubstEntry :: ParsecParser (ModuleName, OpenModule) parsecOpenModuleSubstEntry = do k <- parsec diff --git a/Cabal-syntax/src/Distribution/Compat/CharParsing.hs b/Cabal-syntax/src/Distribution/Compat/CharParsing.hs deleted file mode 100644 index 3f0d44b0a0a..00000000000 --- a/Cabal-syntax/src/Distribution/Compat/CharParsing.hs +++ /dev/null @@ -1,360 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# OPTIONS_GHC -fspec-constr -fspec-constr-count=8 #-} - ------------------------------------------------------------------------------ - ------------------------------------------------------------------------------ - --- | --- Module : Distribution.Compat.CharParsing --- Copyright : (c) Edward Kmett 2011 --- License : BSD3 --- --- Maintainer : ekmett@gmail.com --- Stability : experimental --- Portability : non-portable --- --- Parsers for character streams --- --- Originally in @parsers@ package. -module Distribution.Compat.CharParsing - ( -- * Combinators - oneOf -- :: CharParsing m => [Char] -> m Char - , noneOf -- :: CharParsing m => [Char] -> m Char - , spaces -- :: CharParsing m => m () - , space -- :: CharParsing m => m Char - , newline -- :: CharParsing m => m Char - , tab -- :: CharParsing m => m Char - , upper -- :: CharParsing m => m Char - , lower -- :: CharParsing m => m Char - , alphaNum -- :: CharParsing m => m Char - , letter -- :: CharParsing m => m Char - , digit -- :: CharParsing m => m Char - , hexDigit -- :: CharParsing m => m Char - , octDigit -- :: CharParsing m => m Char - , satisfyRange -- :: CharParsing m => Char -> Char -> m Char - - -- * Class - , CharParsing (..) - - -- * Cabal additions - , integral - , signedIntegral - , munch1 - , munch - , skipSpaces1 - , module Distribution.Compat.Parsing - ) where - -import Distribution.Compat.Prelude -import Prelude () - -import Control.Monad.Trans.Class (lift) -import Control.Monad.Trans.Identity (IdentityT (..)) -import Control.Monad.Trans.RWS.Lazy as Lazy -import Control.Monad.Trans.RWS.Strict as Strict -import Control.Monad.Trans.Reader (ReaderT (..)) -import Control.Monad.Trans.State.Lazy as Lazy -import Control.Monad.Trans.State.Strict as Strict -import Control.Monad.Trans.Writer.Lazy as Lazy -import Control.Monad.Trans.Writer.Strict as Strict -import Data.Char -import Data.Text (Text, unpack) - -import qualified Text.Parsec as Parsec - -import Distribution.Compat.Parsing - --- | @oneOf cs@ succeeds if the current character is in the supplied --- list of characters @cs@. Returns the parsed character. See also --- 'satisfy'. --- --- > vowel = oneOf "aeiou" -oneOf :: CharParsing m => [Char] -> m Char -oneOf xs = satisfy (\c -> c `elem` xs) -{-# INLINE oneOf #-} - --- | As the dual of 'oneOf', @noneOf cs@ succeeds if the current --- character is /not/ in the supplied list of characters @cs@. Returns the --- parsed character. --- --- > consonant = noneOf "aeiou" -noneOf :: CharParsing m => [Char] -> m Char -noneOf xs = satisfy (\c -> c `notElem` xs) -{-# INLINE noneOf #-} - --- | Skips /zero/ or more white space characters. See also 'skipMany'. -spaces :: CharParsing m => m () -spaces = skipMany space "white space" -{-# INLINE spaces #-} - --- | Parses a white space character (any character which satisfies 'isSpace') --- Returns the parsed character. -space :: CharParsing m => m Char -space = satisfy isSpace "space" -{-# INLINE space #-} - --- | Parses a newline character (\'\\n\'). Returns a newline character. -newline :: CharParsing m => m Char -newline = char '\n' "new-line" -{-# INLINE newline #-} - --- | Parses a tab character (\'\\t\'). Returns a tab character. -tab :: CharParsing m => m Char -tab = char '\t' "tab" -{-# INLINE tab #-} - --- | Parses an upper case letter. Returns the parsed character. -upper :: CharParsing m => m Char -upper = satisfy isUpper "uppercase letter" -{-# INLINE upper #-} - --- | Parses a lower case character. Returns the parsed character. -lower :: CharParsing m => m Char -lower = satisfy isLower "lowercase letter" -{-# INLINE lower #-} - --- | Parses a letter or digit. Returns the parsed character. -alphaNum :: CharParsing m => m Char -alphaNum = satisfy isAlphaNum "letter or digit" -{-# INLINE alphaNum #-} - --- | Parses a letter (an upper case or lower case character). Returns the --- parsed character. -letter :: CharParsing m => m Char -letter = satisfy isAlpha "letter" -{-# INLINE letter #-} - --- | Parses a digit. Returns the parsed character. -digit :: CharParsing m => m Char -digit = satisfy isDigit "digit" -{-# INLINE digit #-} - --- | Parses a hexadecimal digit (a digit or a letter between \'a\' and --- \'f\' or \'A\' and \'F\'). Returns the parsed character. -hexDigit :: CharParsing m => m Char -hexDigit = satisfy isHexDigit "hexadecimal digit" -{-# INLINE hexDigit #-} - --- | Parses an octal digit (a character between \'0\' and \'7\'). Returns --- the parsed character. -octDigit :: CharParsing m => m Char -octDigit = satisfy isOctDigit "octal digit" -{-# INLINE octDigit #-} - -satisfyRange :: CharParsing m => Char -> Char -> m Char -satisfyRange a z = satisfy (\c -> c >= a && c <= z) -{-# INLINE satisfyRange #-} - --- | Additional functionality needed to parse character streams. -class Parsing m => CharParsing m where - -- | Parse a single character of the input, with UTF-8 decoding - satisfy :: (Char -> Bool) -> m Char - - -- | @char c@ parses a single character @c@. Returns the parsed - -- character (i.e. @c@). - -- - -- /e.g./ - -- - -- @semiColon = 'char' ';'@ - char :: Char -> m Char - char c = satisfy (c ==) show [c] - {-# INLINE char #-} - - -- | @notChar c@ parses any single character other than @c@. Returns the parsed - -- character. - notChar :: Char -> m Char - notChar c = satisfy (c /=) - {-# INLINE notChar #-} - - -- | This parser succeeds for any character. Returns the parsed character. - anyChar :: m Char - anyChar = satisfy (const True) - {-# INLINE anyChar #-} - - -- | @string s@ parses a sequence of characters given by @s@. Returns - -- the parsed string (i.e. @s@). - -- - -- > divOrMod = string "div" - -- > <|> string "mod" - string :: String -> m String - string s = s <$ try (traverse_ char s) show s - {-# INLINE string #-} - - -- | @text t@ parses a sequence of characters determined by the text @t@ Returns - -- the parsed text fragment (i.e. @t@). - -- - -- Using @OverloadedStrings@: - -- - -- > divOrMod = text "div" - -- > <|> text "mod" - text :: Text -> m Text - text t = t <$ string (unpack t) - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m) => CharParsing (Lazy.StateT s m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m) => CharParsing (Strict.StateT s m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m) => CharParsing (ReaderT e m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Strict.WriterT w m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Lazy.WriterT w m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Lazy.RWST r w s m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m, Monoid w) => CharParsing (Strict.RWST r w s m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance (CharParsing m, MonadPlus m) => CharParsing (IdentityT m) where - satisfy = lift . satisfy - {-# INLINE satisfy #-} - char = lift . char - {-# INLINE char #-} - notChar = lift . notChar - {-# INLINE notChar #-} - anyChar = lift anyChar - {-# INLINE anyChar #-} - string = lift . string - {-# INLINE string #-} - text = lift . text - {-# INLINE text #-} - -instance Parsec.Stream s m Char => CharParsing (Parsec.ParsecT s u m) where - satisfy = Parsec.satisfy - char = Parsec.char - notChar c = Parsec.satisfy (/= c) - anyChar = Parsec.anyChar - string = Parsec.string - -------------------------------------------------------------------------------- --- Our additions -------------------------------------------------------------------------------- - -integral :: (CharParsing m, Integral a) => m a -integral = toNumber <$> some d "integral" - where - toNumber = foldl' (\a b -> a * 10 + b) 0 - d = f <$> satisfyRange '0' '9' - f '0' = 0 - f '1' = 1 - f '2' = 2 - f '3' = 3 - f '4' = 4 - f '5' = 5 - f '6' = 6 - f '7' = 7 - f '8' = 8 - f '9' = 9 - f _ = error "panic! integral" -{-# INLINE integral #-} - --- | Accepts negative (starting with @-@) and positive (without sign) integral --- numbers. --- --- @since 3.4.0.0 -signedIntegral :: (CharParsing m, Integral a) => m a -signedIntegral = negate <$ char '-' <*> integral <|> integral -{-# INLINE signedIntegral #-} - --- | Greedily munch characters while predicate holds. --- Require at least one character. -munch1 :: CharParsing m => (Char -> Bool) -> m String -munch1 = some . satisfy -{-# INLINE munch1 #-} - --- | Greedily munch characters while predicate holds. --- Always succeeds. -munch :: CharParsing m => (Char -> Bool) -> m String -munch = many . satisfy -{-# INLINE munch #-} - -skipSpaces1 :: CharParsing m => m () -skipSpaces1 = skipSome space -{-# INLINE skipSpaces1 #-} diff --git a/Cabal-syntax/src/Distribution/Compat/Parsing.hs b/Cabal-syntax/src/Distribution/Compat/Parsing.hs deleted file mode 100644 index 4cb8c9bca18..00000000000 --- a/Cabal-syntax/src/Distribution/Compat/Parsing.hs +++ /dev/null @@ -1,370 +0,0 @@ -{-# LANGUAGE GADTs #-} -{-# LANGUAGE UndecidableInstances #-} - ------------------------------------------------------------------------------ - ------------------------------------------------------------------------------ - --- | --- Module : Distribution.Compat.Parsing --- Copyright : (c) Edward Kmett 2011-2012 --- License : BSD3 --- --- Maintainer : ekmett@gmail.com --- Stability : experimental --- Portability : non-portable --- --- Alternative parser combinators. --- --- Originally in @parsers@ package. -module Distribution.Compat.Parsing - ( -- * Parsing Combinators - choice - , option - , optional -- from Control.Applicative, parsec optionMaybe - , skipOptional -- parsec optional - , between - , some -- from Control.Applicative, parsec many1 - , many -- from Control.Applicative - , sepBy - , sepByNonEmpty - , sepEndByNonEmpty - , sepEndBy - , endByNonEmpty - , endBy - , count - , chainl - , chainr - , chainl1 - , chainr1 - , manyTill - - -- * Parsing Class - , Parsing (..) - ) where - -import Distribution.Compat.Prelude -import Prelude () - -import Control.Applicative (optional, (<**>)) -import Control.Monad.Trans.Class (lift) -import Control.Monad.Trans.Identity (IdentityT (..)) -import Control.Monad.Trans.RWS.Lazy as Lazy -import Control.Monad.Trans.RWS.Strict as Strict -import Control.Monad.Trans.Reader (ReaderT (..)) -import Control.Monad.Trans.State.Lazy as Lazy -import Control.Monad.Trans.State.Strict as Strict -import Control.Monad.Trans.Writer.Lazy as Lazy -import Control.Monad.Trans.Writer.Strict as Strict -import Data.Foldable (asum) - -import qualified Data.List.NonEmpty as NE -import qualified Text.Parsec as Parsec - --- | @choice ps@ tries to apply the parsers in the list @ps@ in order, --- until one of them succeeds. Returns the value of the succeeding --- parser. -choice :: Alternative m => [m a] -> m a -choice = asum -{-# INLINE choice #-} - --- | @option x p@ tries to apply parser @p@. If @p@ fails without --- consuming input, it returns the value @x@, otherwise the value --- returned by @p@. --- --- > priority = option 0 (digitToInt <$> digit) -option :: Alternative m => a -> m a -> m a -option x p = p <|> pure x -{-# INLINE option #-} - --- | @skipOptional p@ tries to apply parser @p@. It will parse @p@ or nothing. --- It only fails if @p@ fails after consuming input. It discards the result --- of @p@. (Plays the role of parsec's optional, which conflicts with Applicative's optional) -skipOptional :: Alternative m => m a -> m () -skipOptional p = (() <$ p) <|> pure () -{-# INLINE skipOptional #-} - --- | @between open close p@ parses @open@, followed by @p@ and @close@. --- Returns the value returned by @p@. --- --- > braces = between (symbol "{") (symbol "}") -between :: Applicative m => m bra -> m ket -> m a -> m a -between bra ket p = bra *> p <* ket -{-# INLINE between #-} - --- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated --- by @sep@. Returns a list of values returned by @p@. --- --- > commaSep p = p `sepBy` (symbol ",") -sepBy :: Alternative m => m a -> m sep -> m [a] -sepBy p sep = toList <$> sepByNonEmpty p sep <|> pure [] -{-# INLINE sepBy #-} - --- | @sepByNonEmpty p sep@ parses /one/ or more occurrences of @p@, separated --- by @sep@. Returns a non-empty list of values returned by @p@. -sepByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a) -sepByNonEmpty p sep = (:|) <$> p <*> many (sep *> p) -{-# INLINE sepByNonEmpty #-} - --- | @sepEndByNonEmpty p sep@ parses /one/ or more occurrences of @p@, --- separated and optionally ended by @sep@. Returns a non-empty list of values --- returned by @p@. -sepEndByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a) -sepEndByNonEmpty p sep = (:|) <$> p <*> ((sep *> sepEndBy p sep) <|> pure []) - --- | @sepEndBy p sep@ parses /zero/ or more occurrences of @p@, --- separated and optionally ended by @sep@, ie. haskell style --- statements. Returns a list of values returned by @p@. --- --- > haskellStatements = haskellStatement `sepEndBy` semi -sepEndBy :: Alternative m => m a -> m sep -> m [a] -sepEndBy p sep = toList <$> sepEndByNonEmpty p sep <|> pure [] -{-# INLINE sepEndBy #-} - --- | @endByNonEmpty p sep@ parses /one/ or more occurrences of @p@, separated --- and ended by @sep@. Returns a non-empty list of values returned by @p@. -endByNonEmpty :: Alternative m => m a -> m sep -> m (NonEmpty a) -endByNonEmpty p sep = NE.some1 (p <* sep) -{-# INLINE endByNonEmpty #-} - --- | @endBy p sep@ parses /zero/ or more occurrences of @p@, separated --- and ended by @sep@. Returns a list of values returned by @p@. --- --- > cStatements = cStatement `endBy` semi -endBy :: Alternative m => m a -> m sep -> m [a] -endBy p sep = many (p <* sep) -{-# INLINE endBy #-} - --- | @count n p@ parses @n@ occurrences of @p@. If @n@ is smaller or --- equal to zero, the parser equals to @return []@. Returns a list of --- @n@ values returned by @p@. -count :: Applicative m => Int -> m a -> m [a] -count n p - | n <= 0 = pure [] - | otherwise = sequenceA (replicate n p) -{-# INLINE count #-} - --- | @chainr p op x@ parses /zero/ or more occurrences of @p@, --- separated by @op@ Returns a value obtained by a /right/ associative --- application of all functions returned by @op@ to the values returned --- by @p@. If there are no occurrences of @p@, the value @x@ is --- returned. -chainr :: Alternative m => m a -> m (a -> a -> a) -> a -> m a -chainr p op x = chainr1 p op <|> pure x -{-# INLINE chainr #-} - --- | @chainl p op x@ parses /zero/ or more occurrences of @p@, --- separated by @op@. Returns a value obtained by a /left/ associative --- application of all functions returned by @op@ to the values returned --- by @p@. If there are zero occurrences of @p@, the value @x@ is --- returned. -chainl :: Alternative m => m a -> m (a -> a -> a) -> a -> m a -chainl p op x = chainl1 p op <|> pure x -{-# INLINE chainl #-} - --- | @chainl1 p op x@ parses /one/ or more occurrences of @p@, --- separated by @op@ Returns a value obtained by a /left/ associative --- application of all functions returned by @op@ to the values returned --- by @p@. . This parser can for example be used to eliminate left --- recursion which typically occurs in expression grammars. --- --- > expr = term `chainl1` addop --- > term = factor `chainl1` mulop --- > factor = parens expr <|> integer --- > --- > mulop = (*) <$ symbol "*" --- > <|> div <$ symbol "/" --- > --- > addop = (+) <$ symbol "+" --- > <|> (-) <$ symbol "-" -chainl1 :: Alternative m => m a -> m (a -> a -> a) -> m a -chainl1 p op = scan - where - scan = p <**> rst - rst = (\f y g x -> g (f x y)) <$> op <*> p <*> rst <|> pure id -{-# INLINE chainl1 #-} - --- | @chainr1 p op x@ parses /one/ or more occurrences of @p@, --- separated by @op@ Returns a value obtained by a /right/ associative --- application of all functions returned by @op@ to the values returned --- by @p@. -chainr1 :: Alternative m => m a -> m (a -> a -> a) -> m a -chainr1 p op = scan - where - scan = p <**> rst - rst = (flip <$> op <*> scan) <|> pure id -{-# INLINE chainr1 #-} - --- | @manyTill p end@ applies parser @p@ /zero/ or more times until --- parser @end@ succeeds. Returns the list of values returned by @p@. --- This parser can be used to scan comments: --- --- > simpleComment = do{ string "")) --- > } --- --- Note the overlapping parsers @anyChar@ and @string \"-->\"@, and --- therefore the use of the 'try' combinator. -manyTill :: Alternative m => m a -> m end -> m [a] -manyTill p end = go where go = ([] <$ end) <|> ((:) <$> p <*> go) -{-# INLINE manyTill #-} - -infixr 0 - --- | Additional functionality needed to describe parsers independent of input type. -class Alternative m => Parsing m where - -- | Take a parser that may consume input, and on failure, go back to - -- where we started and fail as if we didn't consume input. - try :: m a -> m a - - -- | Give a parser a name - () :: m a -> String -> m a - - -- | A version of many that discards its input. Specialized because it - -- can often be implemented more cheaply. - skipMany :: m a -> m () - skipMany p = () <$ many p - {-# INLINE skipMany #-} - - -- | @skipSome p@ applies the parser @p@ /one/ or more times, skipping - -- its result. (aka skipMany1 in parsec) - skipSome :: m a -> m () - skipSome p = p *> skipMany p - {-# INLINE skipSome #-} - - -- | Used to emit an error on an unexpected token - unexpected :: String -> m a - - -- | This parser only succeeds at the end of the input. This is not a - -- primitive parser but it is defined using 'notFollowedBy'. - -- - -- > eof = notFollowedBy anyChar "end of input" - eof :: m () - - -- | @notFollowedBy p@ only succeeds when parser @p@ fails. This parser - -- does not consume any input. This parser can be used to implement the - -- \'longest match\' rule. For example, when recognizing keywords (for - -- example @let@), we want to make sure that a keyword is not followed - -- by a legal identifier character, in which case the keyword is - -- actually an identifier (for example @lets@). We can program this - -- behaviour as follows: - -- - -- > keywordLet = try $ string "let" <* notFollowedBy alphaNum - notFollowedBy :: Show a => m a -> m () - -instance (Parsing m, MonadPlus m) => Parsing (Lazy.StateT s m) where - try (Lazy.StateT m) = Lazy.StateT $ try . m - {-# INLINE try #-} - Lazy.StateT m l = Lazy.StateT $ \s -> m s l - {-# INLINE () #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (Lazy.StateT m) = Lazy.StateT $ - \s -> notFollowedBy (fst <$> m s) >> return ((), s) - {-# INLINE notFollowedBy #-} - -instance (Parsing m, MonadPlus m) => Parsing (Strict.StateT s m) where - try (Strict.StateT m) = Strict.StateT $ try . m - {-# INLINE try #-} - Strict.StateT m l = Strict.StateT $ \s -> m s l - {-# INLINE () #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (Strict.StateT m) = Strict.StateT $ - \s -> notFollowedBy (fst <$> m s) >> return ((), s) - {-# INLINE notFollowedBy #-} - -instance (Parsing m, MonadPlus m) => Parsing (ReaderT e m) where - try (ReaderT m) = ReaderT $ try . m - {-# INLINE try #-} - ReaderT m l = ReaderT $ \e -> m e l - {-# INLINE () #-} - skipMany (ReaderT m) = ReaderT $ skipMany . m - {-# INLINE skipMany #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (ReaderT m) = ReaderT $ notFollowedBy . m - {-# INLINE notFollowedBy #-} - -instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Strict.WriterT w m) where - try (Strict.WriterT m) = Strict.WriterT $ try m - {-# INLINE try #-} - Strict.WriterT m l = Strict.WriterT (m l) - {-# INLINE () #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (Strict.WriterT m) = - Strict.WriterT $ - notFollowedBy (fst <$> m) >>= \x -> return (x, mempty) - {-# INLINE notFollowedBy #-} - -instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Lazy.WriterT w m) where - try (Lazy.WriterT m) = Lazy.WriterT $ try m - {-# INLINE try #-} - Lazy.WriterT m l = Lazy.WriterT (m l) - {-# INLINE () #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (Lazy.WriterT m) = - Lazy.WriterT $ - notFollowedBy (fst <$> m) >>= \x -> return (x, mempty) - {-# INLINE notFollowedBy #-} - -instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Lazy.RWST r w s m) where - try (Lazy.RWST m) = Lazy.RWST $ \r s -> try (m r s) - {-# INLINE try #-} - Lazy.RWST m l = Lazy.RWST $ \r s -> m r s l - {-# INLINE () #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (Lazy.RWST m) = Lazy.RWST $ - \r s -> notFollowedBy ((\(a, _, _) -> a) <$> m r s) >>= \x -> return (x, s, mempty) - {-# INLINE notFollowedBy #-} - -instance (Parsing m, MonadPlus m, Monoid w) => Parsing (Strict.RWST r w s m) where - try (Strict.RWST m) = Strict.RWST $ \r s -> try (m r s) - {-# INLINE try #-} - Strict.RWST m l = Strict.RWST $ \r s -> m r s l - {-# INLINE () #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (Strict.RWST m) = Strict.RWST $ - \r s -> notFollowedBy ((\(a, _, _) -> a) <$> m r s) >>= \x -> return (x, s, mempty) - {-# INLINE notFollowedBy #-} - -instance (Parsing m, Monad m) => Parsing (IdentityT m) where - try = IdentityT . try . runIdentityT - {-# INLINE try #-} - IdentityT m l = IdentityT (m l) - {-# INLINE () #-} - skipMany = IdentityT . skipMany . runIdentityT - {-# INLINE skipMany #-} - unexpected = lift . unexpected - {-# INLINE unexpected #-} - eof = lift eof - {-# INLINE eof #-} - notFollowedBy (IdentityT m) = IdentityT $ notFollowedBy m - {-# INLINE notFollowedBy #-} - -instance (Parsec.Stream s m t, Show t) => Parsing (Parsec.ParsecT s u m) where - try = Parsec.try - () = (Parsec.) - skipMany = Parsec.skipMany - skipSome = Parsec.skipMany1 - unexpected = Parsec.unexpected - eof = Parsec.eof - notFollowedBy = Parsec.notFollowedBy diff --git a/Cabal-syntax/src/Distribution/Compiler.hs b/Cabal-syntax/src/Distribution/Compiler.hs index d715efbf951..5936587c14b 100644 --- a/Cabal-syntax/src/Distribution/Compiler.hs +++ b/Cabal-syntax/src/Distribution/Compiler.hs @@ -57,8 +57,8 @@ import Language.Haskell.Extension import Distribution.Version (Version, mkVersion', nullVersion) -import qualified Distribution.Compat.CharParsing as P -import Distribution.Parsec (Parsec (..)) +import Distribution.Parsec (CabalParsec (..)) +import qualified Distribution.Parsec as P import Distribution.Pretty (Pretty (..), prettyShow) import qualified System.Info (compilerName, compilerVersion) import qualified Text.PrettyPrint as Disp @@ -94,7 +94,7 @@ instance Pretty CompilerFlavor where pretty NHC = Disp.text "nhc98" pretty other = Disp.text (lowercase (show other)) -instance Parsec CompilerFlavor where +instance CabalParsec CompilerFlavor where parsec = classifyCompilerFlavor <$> component where component = do @@ -185,7 +185,7 @@ instance Pretty CompilerId where | v == nullVersion = pretty f | otherwise = pretty f <<>> Disp.char '-' <<>> pretty v -instance Parsec CompilerId where +instance CabalParsec CompilerId where parsec = do flavour <- parsec version <- (P.char '-' >> parsec) <|> return nullVersion @@ -233,7 +233,7 @@ instance Pretty AbiTag where pretty NoAbiTag = Disp.empty pretty (AbiTag tag) = Disp.text tag -instance Parsec AbiTag where +instance CabalParsec AbiTag where parsec = do tag <- P.munch (\c -> isAlphaNum c || c == '_') if null tag then return NoAbiTag else return (AbiTag tag) diff --git a/Cabal-syntax/src/Distribution/FieldGrammar/FieldDescrs.hs b/Cabal-syntax/src/Distribution/FieldGrammar/FieldDescrs.hs index e03ae749570..a3ef5f8d0a3 100644 --- a/Cabal-syntax/src/Distribution/FieldGrammar/FieldDescrs.hs +++ b/Cabal-syntax/src/Distribution/FieldGrammar/FieldDescrs.hs @@ -21,15 +21,15 @@ import Distribution.Pretty (Pretty (..), showFreeText) import Distribution.Utils.String (trim) import qualified Data.Map as Map -import qualified Distribution.Compat.CharParsing as C import qualified Distribution.Fields as P +import qualified Distribution.Parsec as C import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- strict pair data SP s = SP { pPretty :: !(s -> Disp.Doc) - , pParse :: !(forall m. P.CabalParsing m => s -> m s) + , pParse :: !(s -> P.ParsecParser s) } -- | A collection of field parsers and pretty-printers. @@ -40,7 +40,7 @@ instance Applicative (FieldDescrs s) where pure _ = F mempty f <*> x = F (mappend (runF f) (runF x)) -singletonF :: P.FieldName -> (s -> Disp.Doc) -> (forall m. P.CabalParsing m => s -> m s) -> FieldDescrs s a +singletonF :: P.FieldName -> (s -> Disp.Doc) -> (s -> P.ParsecParser s) -> FieldDescrs s a singletonF fn f g = F $ Map.singleton fn (SP f g) -- | Lookup a field value pretty-printer. @@ -48,13 +48,12 @@ fieldDescrPretty :: FieldDescrs s a -> P.FieldName -> Maybe (s -> Disp.Doc) fieldDescrPretty (F m) fn = pPretty <$> Map.lookup fn m -- | Lookup a field value parser. -fieldDescrParse :: P.CabalParsing m => FieldDescrs s a -> P.FieldName -> Maybe (s -> m s) +fieldDescrParse :: FieldDescrs s a -> P.FieldName -> Maybe (s -> P.ParsecParser s) fieldDescrParse (F m) fn = (\f -> pParse f) <$> Map.lookup fn m fieldDescrsToList - :: P.CabalParsing m - => FieldDescrs s a - -> [(P.FieldName, s -> Disp.Doc, s -> m s)] + :: FieldDescrs s a + -> [(P.FieldName, s -> Disp.Doc, s -> P.ParsecParser s)] fieldDescrsToList = map mk . Map.toList . runF where mk (name, SP ppr parse) = (name, ppr, parse) @@ -111,7 +110,7 @@ instance FieldGrammar ParsecPretty FieldDescrs where availableSince _ _ = id hiddenField _ = F mempty -parsecFreeText :: P.CabalParsing m => m String +parsecFreeText :: P.ParsecParser String parsecFreeText = dropDotLines <$ C.spaces <*> many C.anyChar where -- Example package with dot lines @@ -125,5 +124,5 @@ parsecFreeText = dropDotLines <$ C.spaces <*> many C.anyChar trim' :: String -> String trim' = dropWhileEnd (`elem` (" \t" :: String)) -class (P.Parsec a, Pretty a) => ParsecPretty a -instance (P.Parsec a, Pretty a) => ParsecPretty a +class (P.CabalParsec a, Pretty a) => ParsecPretty a +instance (P.CabalParsec a, Pretty a) => ParsecPretty a diff --git a/Cabal-syntax/src/Distribution/FieldGrammar/Newtypes.hs b/Cabal-syntax/src/Distribution/FieldGrammar/Newtypes.hs index d39e77ebbeb..c532efec965 100644 --- a/Cabal-syntax/src/Distribution/FieldGrammar/Newtypes.hs +++ b/Cabal-syntax/src/Distribution/FieldGrammar/Newtypes.hs @@ -75,7 +75,7 @@ import Text.PrettyPrint (Doc, comma, fsep, punctuate, text, vcat) import qualified Data.List.NonEmpty as NE import qualified Data.Set as Set -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Distribution.SPDX as SPDX -- | Vertical list with commas. Displayed with 'vcat' @@ -96,8 +96,8 @@ data NoCommaFSep = NoCommaFSep class Sep sep where prettySep :: Proxy sep -> [Doc] -> Doc - parseSep :: CabalParsing m => Proxy sep -> m a -> m [a] - parseSepNE :: CabalParsing m => Proxy sep -> m a -> m (NonEmpty a) + parseSep :: Proxy sep -> ParsecParser a -> ParsecParser [a] + parseSepNE :: Proxy sep -> ParsecParser a -> ParsecParser (NonEmpty a) instance Sep CommaVCat where prettySep _ = vcat . punctuate comma @@ -153,7 +153,7 @@ alaList' _ _ = List instance Newtype [a] (List sep wrapper a) -instance (Newtype a b, Sep sep, Parsec b) => Parsec (List sep b a) where +instance (Newtype a b, Sep sep, CabalParsec b) => CabalParsec (List sep b a) where parsec = pack . map (unpack :: b -> a) <$> parseSep (Proxy :: Proxy sep) parsec instance (Newtype a b, Sep sep, Pretty b) => Pretty (List sep b a) where @@ -190,7 +190,7 @@ alaSet' _ _ = Set' instance Newtype (Set a) (Set' sep wrapper a) -instance (Newtype a b, Ord a, Sep sep, Parsec b) => Parsec (Set' sep b a) where +instance (Newtype a b, Ord a, Sep sep, CabalParsec b) => CabalParsec (Set' sep b a) where parsec = pack . Set.fromList . map (unpack :: b -> a) <$> parseSep (Proxy :: Proxy sep) parsec instance (Newtype a b, Sep sep, Pretty b) => Pretty (Set' sep b a) where @@ -224,7 +224,7 @@ alaNonEmpty' _ _ = NonEmpty' instance Newtype (NonEmpty a) (NonEmpty' sep wrapper a) -instance (Newtype a b, Sep sep, Parsec b) => Parsec (NonEmpty' sep b a) where +instance (Newtype a b, Sep sep, CabalParsec b) => CabalParsec (NonEmpty' sep b a) where parsec = pack . fmap (unpack :: b -> a) <$> parseSepNE (Proxy :: Proxy sep) parsec instance (Newtype a b, Sep sep, Pretty b) => Pretty (NonEmpty' sep b a) where @@ -239,7 +239,7 @@ newtype Token = Token {getToken :: String} instance Newtype String Token -instance Parsec Token where +instance CabalParsec Token where parsec = pack <$> parsecToken instance Pretty Token where @@ -250,7 +250,7 @@ newtype Token' = Token' {getToken' :: String} instance Newtype String Token' -instance Parsec Token' where +instance CabalParsec Token' where parsec = pack <$> parsecToken' instance Pretty Token' where @@ -261,7 +261,7 @@ newtype MQuoted a = MQuoted {getMQuoted :: a} instance Newtype a (MQuoted a) -instance Parsec a => Parsec (MQuoted a) where +instance CabalParsec a => CabalParsec (MQuoted a) where parsec = pack <$> parsecMaybeQuoted parsec instance Pretty a => Pretty (MQuoted a) where @@ -272,7 +272,7 @@ newtype FilePathNT = FilePathNT {getFilePathNT :: String} instance Newtype String FilePathNT -instance Parsec FilePathNT where +instance CabalParsec FilePathNT where parsec = do token <- parsecToken if null token @@ -288,7 +288,7 @@ newtype SymbolicPathNT from to = SymbolicPathNT {getSymbolicPathNT :: SymbolicPa instance Newtype (SymbolicPath from to) (SymbolicPathNT from to) -instance Parsec (SymbolicPathNT from to) where +instance CabalParsec (SymbolicPathNT from to) where parsec = do token <- parsecToken if null token @@ -307,7 +307,7 @@ instance Newtype (RelativePath from to) (RelativePathNT from to) -- NB: we don't reject non-relative paths here; we allow them here and reject -- later (see 'Distribution.PackageDescription.Check.Paths.checkPath'). -instance Parsec (RelativePathNT from to) where +instance CabalParsec (RelativePathNT from to) where parsec = do token <- parsecToken if null token @@ -338,7 +338,7 @@ newtype SpecVersion = SpecVersion {getSpecVersion :: CabalSpecVersion} instance Newtype CabalSpecVersion SpecVersion -instance Parsec SpecVersion where +instance CabalParsec SpecVersion where parsec = do e <- parsecSpecVersion let ver :: Version @@ -423,7 +423,7 @@ newtype SpecLicense = SpecLicense {getSpecLicense :: Either SPDX.License License instance Newtype (Either SPDX.License License) SpecLicense -instance Parsec SpecLicense where +instance CabalParsec SpecLicense where parsec = do v <- askCabalSpecVersion if v >= CabalSpecV2_2 @@ -442,14 +442,14 @@ newtype TestedWith = TestedWith {getTestedWith :: (CompilerFlavor, VersionRange) instance Newtype (CompilerFlavor, VersionRange) TestedWith -instance Parsec TestedWith where +instance CabalParsec TestedWith where parsec = pack <$> parsecTestedWith instance Pretty TestedWith where pretty x = case unpack x of (compiler, vr) -> pretty compiler <+> pretty vr -parsecTestedWith :: CabalParsing m => m (CompilerFlavor, VersionRange) +parsecTestedWith :: ParsecParser (CompilerFlavor, VersionRange) parsecTestedWith = do name <- lexemeParsec ver <- parsec <|> pure anyVersion diff --git a/Cabal-syntax/src/Distribution/FieldGrammar/Parsec.hs b/Cabal-syntax/src/Distribution/FieldGrammar/Parsec.hs index 4721aa4ad08..eed78805cf5 100644 --- a/Cabal-syntax/src/Distribution/FieldGrammar/Parsec.hs +++ b/Cabal-syntax/src/Distribution/FieldGrammar/Parsec.hs @@ -153,7 +153,7 @@ warnMultipleSingularFields fn (x : xs) = do parseWarning pos PWTMultipleSingularField $ "The field " <> show fn <> " is specified more than once at positions " ++ intercalate ", " (map showPos (pos : poss)) -instance FieldGrammar Parsec ParsecFieldGrammar where +instance FieldGrammar CabalParsec ParsecFieldGrammar where blurFieldGrammar _ (ParsecFG s s' parser) = ParsecFG s s' parser uniqueFieldAla fn _pack _extract = ParsecFG (Set.singleton fn) Set.empty parser diff --git a/Cabal-syntax/src/Distribution/Fields/ConfVar.hs b/Cabal-syntax/src/Distribution/Fields/ConfVar.hs index 760e2335143..d7a3227df16 100644 --- a/Cabal-syntax/src/Distribution/Fields/ConfVar.hs +++ b/Cabal-syntax/src/Distribution/Fields/ConfVar.hs @@ -2,12 +2,11 @@ module Distribution.Fields.ConfVar (parseConditionConfVar, parseConditionConfVarFromClause) where -import Distribution.Compat.CharParsing (char, integral) import Distribution.Compat.Prelude import Distribution.Fields.Field (Field (..), SectionArg (..)) import Distribution.Fields.ParseResult import Distribution.Fields.Parser (readFields) -import Distribution.Parsec (Parsec (..), Position (..), runParsecParser) +import Distribution.Parsec (CabalParsec (..), Position (..), char, integral, runParsecParser) import Distribution.Parsec.FieldLineStream (fieldLineStreamFromBS) import Distribution.Types.Condition import Distribution.Types.ConfVar (ConfVar (..)) @@ -147,7 +146,7 @@ parser = condOr updatePosition x _ _ = x prettySectionArg = show - fromParsec :: Parsec a => Parser a + fromParsec :: CabalParsec a => Parser a fromParsec = fromParsec' parsec fromParsec' p = do diff --git a/Cabal-syntax/src/Distribution/License.hs b/Cabal-syntax/src/Distribution/License.hs index f79ef6d0549..4d30bd312c6 100644 --- a/Cabal-syntax/src/Distribution/License.hs +++ b/Cabal-syntax/src/Distribution/License.hs @@ -57,7 +57,7 @@ import Distribution.Pretty import Distribution.Version import qualified Data.Map.Strict as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Distribution.SPDX as SPDX import qualified Text.PrettyPrint as Disp @@ -224,7 +224,7 @@ instance Pretty License where pretty (UnknownLicense other) = Disp.text other pretty other = Disp.text (show other) -instance Parsec License where +instance CabalParsec License where parsec = do name <- P.munch1 isAlphaNum version <- P.optional (P.char '-' *> parsec) diff --git a/Cabal-syntax/src/Distribution/ModuleName.hs b/Cabal-syntax/src/Distribution/ModuleName.hs index 90082d29f06..ddab6582b9c 100644 --- a/Cabal-syntax/src/Distribution/ModuleName.hs +++ b/Cabal-syntax/src/Distribution/ModuleName.hs @@ -34,8 +34,8 @@ import Distribution.Pretty import Distribution.Utils.ShortText (ShortText, fromShortText, toShortText) import System.FilePath (pathSeparator) -import qualified Distribution.Compat.CharParsing as P import qualified Distribution.Compat.DList as DList +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | A valid Haskell module name. @@ -54,30 +54,30 @@ instance NFData ModuleName where instance Pretty ModuleName where pretty = Disp.text . unModuleName -instance Parsec ModuleName where +instance CabalParsec ModuleName where parsec = parsecModuleName -parsecModuleName :: forall m. CabalParsing m => m ModuleName +parsecModuleName :: ParsecParser ModuleName parsecModuleName = state0 DList.empty where - upper :: m Char + upper :: ParsecParser Char !upper = P.satisfy isUpper - ch :: m Char + ch :: ParsecParser Char !ch = P.satisfy (\c -> validModuleChar c || c == '.') - alt :: m ModuleName -> m ModuleName -> m ModuleName + alt :: ParsecParser ModuleName -> ParsecParser ModuleName -> ParsecParser ModuleName !alt = (<|>) - state0 :: DList.DList Char -> m ModuleName + state0 :: DList.DList Char -> ParsecParser ModuleName state0 acc = do c <- upper state1 (DList.snoc acc c) - state1 :: DList.DList Char -> m ModuleName + state1 :: DList.DList Char -> ParsecParser ModuleName state1 acc = state1' acc `alt` return (fromString (DList.toList acc)) - state1' :: DList.DList Char -> m ModuleName + state1' :: DList.DList Char -> ParsecParser ModuleName state1' acc = do c <- ch case c of diff --git a/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs b/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs index e811c361221..0f805899d4b 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/Configuration.hs @@ -44,13 +44,12 @@ import qualified Distribution.Types.GenericPackageDescription.Lens as L import qualified Distribution.Types.PackageDescription.Lens as L import qualified Distribution.Types.SetupBuildInfo.Lens as L -import Distribution.Compat.CharParsing hiding (char) -import qualified Distribution.Compat.CharParsing as P import Distribution.Compat.Lens import Distribution.Compiler import Distribution.PackageDescription import Distribution.PackageDescription.Utils -import Distribution.Parsec +import Distribution.Parsec hiding (char) +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.System import Distribution.Types.Component @@ -108,7 +107,7 @@ simplifyWithSysParams os arch cinfo cond = (cond', flags) -- -- | Parse a configuration condition from a string. -parseCondition :: CabalParsing m => m (Condition ConfVar) +parseCondition :: ParsecParser (Condition ConfVar) parseCondition = condOr where condOr = sepByNonEmpty condAnd (oper "||") >>= return . foldl1 COr diff --git a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs index db6b7f7607b..9a59a621a21 100644 --- a/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs @@ -86,7 +86,7 @@ import Distribution.Utils.Path import Distribution.Version (Version, VersionRange) import qualified Data.ByteString.Char8 as BS8 -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Distribution.SPDX as SPDX import qualified Distribution.Types.Lens as L @@ -837,7 +837,7 @@ newtype CompatDataDir = CompatDataDir {getCompatDataDir :: SymbolicPath Pkg (Dir instance Newtype (SymbolicPath Pkg (Dir DataDir)) CompatDataDir -instance Parsec CompatDataDir where +instance CabalParsec CompatDataDir where parsec = do token <- parsecToken when (null token) $ @@ -852,7 +852,7 @@ newtype CompatLicenseFile = CompatLicenseFile {getCompatLicenseFile :: [Relative instance Newtype [RelativePath Pkg File] CompatLicenseFile -- TODO -instance Parsec CompatLicenseFile where +instance CabalParsec CompatLicenseFile where parsec = emptyToken <|> CompatLicenseFile . unpack' (alaList FSep) <$> parsec where emptyToken = P.try $ do diff --git a/Cabal-syntax/src/Distribution/Parsec.hs b/Cabal-syntax/src/Distribution/Parsec.hs index 4c6e31e5aaa..a935d4da705 100644 --- a/Cabal-syntax/src/Distribution/Parsec.hs +++ b/Cabal-syntax/src/Distribution/Parsec.hs @@ -6,7 +6,7 @@ {-# LANGUAGE ScopedTypeVariables #-} module Distribution.Parsec - ( Parsec (..) + ( CabalParsec (..) , ParsecParser (..) , runParsecParser , runParsecParser' @@ -18,14 +18,14 @@ module Distribution.Parsec , eitherParsec , explicitEitherParsec , explicitEitherParsec' - - -- * CabalParsing and diagnostics - , CabalParsing (..) + , parsecHaskellString + , askCabalSpecVersion -- ** Warnings , PWarnType (..) , PWarning (..) , showPWarning + , parsecWarning -- ** Errors , PError (..) @@ -52,11 +52,56 @@ module Distribution.Parsec , parsecLeadingOptCommaList , parsecStandard , parsecUnqualComponentName + + -- * Parsers based on @parsers@ package + , manyTill + , eof + , notChar + , anyChar + , option + , skipOptional + , endByNonEmpty + , endBy + , count + , chainr + , chainl + , noneOf + , newline + , tab + , lower + , alphaNum + , letter + , digit + , hexDigit + , octDigit + , satisfyRange + , integral + , signedIntegral + , munch + , unexpected + , sepByNonEmpty + , satisfy + , char + , () + , munch1 + , string + , skipSpaces1 + , sepBy + , optional + , try + , space + , spaces + , between + , choice + , notFollowedBy ) where +import Control.Applicative (optional, (<**>)) import Data.ByteString (ByteString) -import Data.Char (digitToInt, intToDigit) +import Data.Char (digitToInt, intToDigit, isHexDigit, isLower, isOctDigit) +import Data.Foldable (asum) import Data.List (transpose) +import qualified Data.List.NonEmpty as NE import Distribution.CabalSpecVersion import Distribution.Compat.Prelude import Distribution.Parsec.Error (PError (..), showPError) @@ -66,9 +111,9 @@ import Distribution.Parsec.Warning (PWarnType (..), PWarning (..), showPWarning) import Numeric (showIntAtBase) import Prelude () -import qualified Distribution.Compat.CharParsing as P import qualified Distribution.Compat.DList as DList import qualified Distribution.Compat.MonadFail as Fail + import qualified Text.Parsec as Parsec ------------------------------------------------------------------------------- @@ -78,25 +123,15 @@ import qualified Text.Parsec as Parsec -- | Class for parsing with @parsec@. Mainly used for @.cabal@ file fields. -- -- For parsing @.cabal@ like file structure, see "Distribution.Fields". -class Parsec a where - parsec :: CabalParsing m => m a - --- | Parsing class which --- --- * can report Cabal parser warnings. --- --- * knows @cabal-version@ we work with -class (P.CharParsing m, MonadPlus m, Fail.MonadFail m) => CabalParsing m where - parsecWarning :: PWarnType -> String -> m () +class CabalParsec a where + parsec :: ParsecParser a - parsecHaskellString :: m String - parsecHaskellString = stringLiteral - - askCabalSpecVersion :: m CabalSpecVersion +parsecHaskellString :: ParsecParser String +parsecHaskellString = stringLiteral -- | 'parsec' /could/ consume trailing spaces, this function /will/ consume. -lexemeParsec :: (CabalParsing m, Parsec a) => m a -lexemeParsec = parsec <* P.spaces +lexemeParsec :: CabalParsec a => ParsecParser a +lexemeParsec = parsec <* spaces newtype ParsecParser a = PP { unPP @@ -154,40 +189,62 @@ instance MonadPlus ParsecParser where mplus = (<|>) instance Fail.MonadFail ParsecParser where - fail = P.unexpected - -instance P.Parsing ParsecParser where - try p = PP $ \v -> P.try (unPP p v) - p d = PP $ \v -> unPP p v P. d - skipMany p = PP $ \v -> P.skipMany (unPP p v) - skipSome p = PP $ \v -> P.skipSome (unPP p v) - unexpected = liftParsec . P.unexpected - eof = liftParsec P.eof - notFollowedBy p = PP $ \v -> P.notFollowedBy (unPP p v) - -instance P.CharParsing ParsecParser where - satisfy = liftParsec . P.satisfy - char = liftParsec . P.char - notChar = liftParsec . P.notChar - anyChar = liftParsec P.anyChar - string = liftParsec . P.string - -instance CabalParsing ParsecParser where - parsecWarning t w = liftParsec $ do - spos <- Parsec.getPosition - Parsec.modifyState - (PWarning t (Position (Parsec.sourceLine spos) (Parsec.sourceColumn spos)) w :) - askCabalSpecVersion = PP pure + fail = liftParsec . Parsec.unexpected + +try :: ParsecParser a -> ParsecParser a +try p = PP $ \v -> Parsec.try (unPP p v) + +() :: ParsecParser a -> String -> ParsecParser a +p d = PP $ \v -> unPP p v Parsec. d + +skipMany :: ParsecParser a -> ParsecParser () +skipMany p = PP $ \v -> Parsec.skipMany (unPP p v) + +skipSome :: ParsecParser a -> ParsecParser () +skipSome p = PP $ \v -> Parsec.skipMany1 (unPP p v) + +unexpected :: String -> ParsecParser a +unexpected = liftParsec . Parsec.unexpected + +eof :: ParsecParser () +eof = liftParsec Parsec.eof + +notFollowedBy :: Show a => ParsecParser a -> ParsecParser () +notFollowedBy p = PP $ \v -> Parsec.notFollowedBy (unPP p v) + +satisfy :: (Char -> Bool) -> ParsecParser Char +satisfy = liftParsec . Parsec.satisfy + +char :: Char -> ParsecParser Char +char = liftParsec . Parsec.char + +notChar :: Char -> ParsecParser Char +notChar c = liftParsec $ Parsec.satisfy (/= c) + +anyChar :: ParsecParser Char +anyChar = liftParsec Parsec.anyChar + +string :: String -> ParsecParser String +string = liftParsec . Parsec.string + +parsecWarning :: PWarnType -> String -> ParsecParser () +parsecWarning t w = liftParsec $ do + spos <- Parsec.getPosition + Parsec.modifyState + (PWarning t (Position (Parsec.sourceLine spos) (Parsec.sourceColumn spos)) w :) + +askCabalSpecVersion :: ParsecParser CabalSpecVersion +askCabalSpecVersion = PP pure -- | Parse a 'String' with 'lexemeParsec'. -simpleParsec :: Parsec a => String -> Maybe a +simpleParsec :: CabalParsec a => String -> Maybe a simpleParsec = either (const Nothing) Just . runParsecParser lexemeParsec "" . fieldLineStreamFromString -- | Like 'simpleParsec' but for 'ByteString' -simpleParsecBS :: Parsec a => ByteString -> Maybe a +simpleParsecBS :: CabalParsec a => ByteString -> Maybe a simpleParsecBS = either (const Nothing) Just . runParsecParser lexemeParsec "" @@ -196,7 +253,7 @@ simpleParsecBS = -- | Parse a 'String' with 'lexemeParsec' using specific 'CabalSpecVersion'. -- -- @since 3.4.0.0 -simpleParsec' :: Parsec a => CabalSpecVersion -> String -> Maybe a +simpleParsec' :: CabalParsec a => CabalSpecVersion -> String -> Maybe a simpleParsec' spec = either (const Nothing) Just . runParsecParser' spec lexemeParsec "" @@ -206,21 +263,21 @@ simpleParsec' spec = -- Fail if there are any warnings. -- -- @since 3.4.0.0 -simpleParsecW' :: Parsec a => CabalSpecVersion -> String -> Maybe a +simpleParsecW' :: CabalParsec a => CabalSpecVersion -> String -> Maybe a simpleParsecW' spec = either (const Nothing) (\(x, ws) -> if null ws then Just x else Nothing) . runParsecParser' spec ((,) <$> lexemeParsec <*> liftParsec Parsec.getState) "" . fieldLineStreamFromString -- | Parse a 'String' with 'lexemeParsec'. -eitherParsec :: Parsec a => String -> Either String a +eitherParsec :: CabalParsec a => String -> Either String a eitherParsec = explicitEitherParsec parsec -- | Parse a 'String' with given 'ParsecParser'. Trailing whitespace is accepted. explicitEitherParsec :: ParsecParser a -> String -> Either String a explicitEitherParsec parser = either (Left . show) Right - . runParsecParser (parser <* P.spaces) "" + . runParsecParser (parser <* spaces) "" . fieldLineStreamFromString -- | Parse a 'String' with given 'ParsecParser' and 'CabalSpecVersion'. Trailing whitespace is accepted. @@ -230,7 +287,7 @@ explicitEitherParsec parser = explicitEitherParsec' :: CabalSpecVersion -> ParsecParser a -> String -> Either String a explicitEitherParsec' spec parser = either (Left . show) Right - . runParsecParser' spec (parser <* P.spaces) "" + . runParsecParser' spec (parser <* spaces) "" . fieldLineStreamFromString -- | Run 'ParsecParser' with 'cabalSpecLatest'. @@ -241,13 +298,13 @@ runParsecParser = runParsecParser' cabalSpecLatest -- -- @since 3.0.0.0 runParsecParser' :: CabalSpecVersion -> ParsecParser a -> FilePath -> FieldLineStream -> Either Parsec.ParseError a -runParsecParser' v p n = Parsec.runParser (unPP p v <* P.eof) [] n +runParsecParser' v p n = Parsec.runParser (unPP p v <* Parsec.eof) [] n -instance Parsec a => Parsec (Identity a) where +instance CabalParsec a => CabalParsec (Identity a) where parsec = Identity <$> parsec -instance Parsec Bool where - parsec = P.munch1 isAlpha >>= postprocess +instance CabalParsec Bool where + parsec = munch1 isAlpha >>= postprocess where postprocess str | str == "True" = pure True @@ -261,14 +318,14 @@ instance Parsec Bool where "Boolean values are case sensitive, use 'True' or 'False'." -- | @[^ ,]@ -parsecToken :: CabalParsing m => m String -parsecToken = parsecHaskellString <|> ((P.munch1 (\x -> not (isSpace x) && x /= ',') P. "identifier") >>= checkNotDoubleDash) +parsecToken :: ParsecParser String +parsecToken = parsecHaskellString <|> ((munch1 (\x -> not (isSpace x) && x /= ',') "identifier") >>= checkNotDoubleDash) -- | @[^ ]@ -parsecToken' :: CabalParsing m => m String -parsecToken' = parsecHaskellString <|> ((P.munch1 (not . isSpace) P. "token") >>= checkNotDoubleDash) +parsecToken' :: ParsecParser String +parsecToken' = parsecHaskellString <|> ((munch1 (not . isSpace) "token") >>= checkNotDoubleDash) -checkNotDoubleDash :: CabalParsing m => String -> m String +checkNotDoubleDash :: String -> ParsecParser String checkNotDoubleDash s = do when (s == "--") $ parsecWarning PWTDoubleDash $ @@ -280,29 +337,29 @@ checkNotDoubleDash s = do return s -parsecFilePath :: CabalParsing m => m FilePath +parsecFilePath :: ParsecParser FilePath parsecFilePath = parsecToken -- | Parse a benchmark/test-suite types. -parsecStandard :: (CabalParsing m, Parsec ver) => (ver -> String -> a) -> m a +parsecStandard :: CabalParsec ver => (ver -> String -> a) -> ParsecParser a parsecStandard f = do - cs <- some $ P.try (component <* P.char '-') + cs <- some $ try (component <* char '-') ver <- parsec let name = map toLower (intercalate "-" cs) return $! f ver name where component = do - cs <- P.munch1 isAlphaNum + cs <- munch1 isAlphaNum if all isDigit cs then fail "all digit component" else return cs -- each component must contain an alphabetic character, to avoid -- ambiguity in identifiers like foo-1 (the 1 is the version number). -parsecCommaList :: CabalParsing m => m a -> m [a] -parsecCommaList p = P.sepBy (p <* P.spaces) (P.char ',' *> P.spaces P. "comma") +parsecCommaList :: ParsecParser a -> ParsecParser [a] +parsecCommaList p = sepBy (p <* spaces) (char ',' *> spaces "comma") -parsecCommaNonEmpty :: CabalParsing m => m a -> m (NonEmpty a) -parsecCommaNonEmpty p = P.sepByNonEmpty (p <* P.spaces) (P.char ',' *> P.spaces P. "comma") +parsecCommaNonEmpty :: ParsecParser a -> ParsecParser (NonEmpty a) +parsecCommaNonEmpty p = sepByNonEmpty (p <* spaces) (char ',' *> spaces "comma") -- | Like 'parsecCommaList' but accept leading or trailing comma. -- @@ -311,33 +368,33 @@ parsecCommaNonEmpty p = P.sepByNonEmpty (p <* P.spaces) (P.char ',' *> P.spaces -- (comma p)* -- leading comma -- (p comma)* -- trailing comma -- @ -parsecLeadingCommaList :: CabalParsing m => m a -> m [a] +parsecLeadingCommaList :: ParsecParser a -> ParsecParser [a] parsecLeadingCommaList p = do - c <- P.optional comma + c <- optional comma case c of - Nothing -> toList <$> P.sepEndByNonEmpty lp comma <|> pure [] - Just _ -> toList <$> P.sepByNonEmpty lp comma + Nothing -> toList <$> sepEndByNonEmpty lp comma <|> pure [] + Just _ -> toList <$> sepByNonEmpty lp comma where - lp = p <* P.spaces - comma = P.char ',' *> P.spaces P. "comma" + lp = p <* spaces + comma = char ',' *> spaces "comma" -- | -- -- @since 3.4.0.0 -parsecLeadingCommaNonEmpty :: CabalParsing m => m a -> m (NonEmpty a) +parsecLeadingCommaNonEmpty :: ParsecParser a -> ParsecParser (NonEmpty a) parsecLeadingCommaNonEmpty p = do - c <- P.optional comma + c <- optional comma case c of - Nothing -> P.sepEndByNonEmpty lp comma - Just _ -> P.sepByNonEmpty lp comma + Nothing -> sepEndByNonEmpty lp comma + Just _ -> sepByNonEmpty lp comma where - lp = p <* P.spaces - comma = P.char ',' *> P.spaces P. "comma" + lp = p <* spaces + comma = char ',' *> spaces "comma" -parsecOptCommaList :: CabalParsing m => m a -> m [a] -parsecOptCommaList p = P.sepBy (p <* P.spaces) (P.optional comma) +parsecOptCommaList :: ParsecParser a -> ParsecParser [a] +parsecOptCommaList p = sepBy (p <* spaces) (optional comma) where - comma = P.char ',' *> P.spaces + comma = char ',' *> spaces -- | Like 'parsecOptCommaList' but -- @@ -352,32 +409,32 @@ parsecOptCommaList p = P.sepBy (p <* P.spaces) (P.optional comma) -- @ -- -- @since 3.0.0.0 -parsecLeadingOptCommaList :: CabalParsing m => m a -> m [a] +parsecLeadingOptCommaList :: ParsecParser a -> ParsecParser [a] parsecLeadingOptCommaList p = do - c <- P.optional comma + c <- optional comma case c of Nothing -> sepEndBy1Start <|> pure [] - Just _ -> toList <$> P.sepByNonEmpty lp comma + Just _ -> toList <$> sepByNonEmpty lp comma where - lp = p <* P.spaces - comma = P.char ',' *> P.spaces P. "comma" + lp = p <* spaces + comma = char ',' *> spaces "comma" sepEndBy1Start = do x <- lp - c <- P.optional comma + c <- optional comma case c of Nothing -> (x :) <$> many lp - Just _ -> (x :) <$> P.sepEndBy lp comma + Just _ -> (x :) <$> sepEndBy lp comma -- | Content isn't unquoted -parsecQuoted :: CabalParsing m => m a -> m a -parsecQuoted = P.between (P.char '"') (P.char '"') +parsecQuoted :: ParsecParser a -> ParsecParser a +parsecQuoted = between (char '"') (char '"') -- | @parsecMaybeQuoted p = 'parsecQuoted' p <|> p@. -parsecMaybeQuoted :: CabalParsing m => m a -> m a +parsecMaybeQuoted :: ParsecParser a -> ParsecParser a parsecMaybeQuoted p = parsecQuoted p <|> p -parsecUnqualComponentName :: forall m. CabalParsing m => m String +parsecUnqualComponentName :: ParsecParser String parsecUnqualComponentName = state0 DList.empty where -- @@ -412,7 +469,7 @@ parsecUnqualComponentName = state0 DList.empty -- putPretty $ fromTM re -- @ - state0 :: DList.DList Char -> m String + state0 :: DList.DList Char -> ParsecParser String state0 acc = do c <- ch -- <|> fail ("Invalid component, after " ++ DList.toList acc) case () of @@ -422,10 +479,10 @@ parsecUnqualComponentName = state0 DList.empty | c == '-' -> fail ("Empty component, after " ++ DList.toList acc) | otherwise -> fail ("Internal error, after " ++ DList.toList acc) - state1 :: DList.DList Char -> m String + state1 :: DList.DList Char -> ParsecParser String state1 acc = state1' acc `alt` return (DList.toList acc) - state1' :: DList.DList Char -> m String + state1' :: DList.DList Char -> ParsecParser String state1' acc = do c <- ch case () of @@ -434,103 +491,103 @@ parsecUnqualComponentName = state0 DList.empty | c == '-' -> state0 (DList.snoc acc c) | otherwise -> fail ("Internal error, after " ++ DList.toList acc) - ch :: m Char - !ch = P.satisfy (\c -> isAlphaNum c || c == '-') + ch :: ParsecParser Char + !ch = satisfy (\c -> isAlphaNum c || c == '-') - alt :: m String -> m String -> m String + alt :: ParsecParser String -> ParsecParser String -> ParsecParser String !alt = (<|>) -stringLiteral :: forall m. P.CharParsing m => m String +stringLiteral :: ParsecParser String stringLiteral = lit where - lit :: m String + lit :: ParsecParser String lit = foldr (maybe id (:)) "" - <$> P.between (P.char '"') (P.char '"' P. "end of string") (many stringChar) - P. "string" + <$> between (char '"') (char '"' "end of string") (many stringChar) + "string" - stringChar :: m (Maybe Char) + stringChar :: ParsecParser (Maybe Char) stringChar = Just <$> stringLetter <|> stringEscape - P. "string character" + "string character" - stringLetter :: m Char - stringLetter = P.satisfy (\c -> (c /= '"') && (c /= '\\') && (c > '\026')) + stringLetter :: ParsecParser Char + stringLetter = satisfy (\c -> (c /= '"') && (c /= '\\') && (c > '\026')) - stringEscape :: m (Maybe Char) - stringEscape = P.char '\\' *> esc + stringEscape :: ParsecParser (Maybe Char) + stringEscape = char '\\' *> esc where - esc :: m (Maybe Char) + esc :: ParsecParser (Maybe Char) esc = Nothing <$ escapeGap <|> Nothing <$ escapeEmpty <|> Just <$> escapeCode - escapeEmpty, escapeGap :: m Char - escapeEmpty = P.char '&' - escapeGap = P.skipSpaces1 *> (P.char '\\' P. "end of string gap") + escapeEmpty, escapeGap :: ParsecParser Char + escapeEmpty = char '&' + escapeGap = skipSpaces1 *> (char '\\' "end of string gap") -escapeCode :: forall m. P.CharParsing m => m Char -escapeCode = (charEsc <|> charNum <|> charAscii <|> charControl) P. "escape code" +escapeCode :: ParsecParser Char +escapeCode = (charEsc <|> charNum <|> charAscii <|> charControl) "escape code" where - charControl, charNum :: m Char - charControl = (\c -> toEnum (fromEnum c - fromEnum '@')) <$> (P.char '^' *> (P.upper <|> P.char '@')) + charControl, charNum :: ParsecParser Char + charControl = (\c -> toEnum (fromEnum c - fromEnum '@')) <$> (char '^' *> (upper <|> char '@')) charNum = toEnum <$> num where - num :: m Int + num :: ParsecParser Int num = bounded 10 maxchar - <|> (P.char 'o' *> bounded 8 maxchar) - <|> (P.char 'x' *> bounded 16 maxchar) + <|> (char 'o' *> bounded 8 maxchar) + <|> (char 'x' *> bounded 16 maxchar) maxchar = fromEnum (maxBound :: Char) - bounded :: Int -> Int -> m Int + bounded :: Int -> Int -> ParsecParser Int bounded base bnd = foldl' (\x d -> base * x + digitToInt d) 0 <$> bounded' (take base thedigits) (map digitToInt $ showIntAtBase base intToDigit bnd "") where - thedigits :: [m Char] - thedigits = map P.char ['0' .. '9'] ++ map P.oneOf (transpose [['A' .. 'F'], ['a' .. 'f']]) + thedigits :: [ParsecParser Char] + thedigits = map char ['0' .. '9'] ++ map oneOf (transpose [['A' .. 'F'], ['a' .. 'f']]) - toomuch :: m a - toomuch = P.unexpected "out-of-range numeric escape sequence" + toomuch :: ParsecParser a + toomuch = unexpected "out-of-range numeric escape sequence" - bounded', bounded'' :: [m Char] -> [Int] -> m [Char] + bounded', bounded'' :: [ParsecParser Char] -> [Int] -> ParsecParser [Char] bounded' dps@(zero : _) bds = - P.skipSome zero *> ([] <$ P.notFollowedBy (P.choice dps) <|> bounded'' dps bds) + skipSome zero *> ([] <$ notFollowedBy (choice dps) <|> bounded'' dps bds) <|> bounded'' dps bds bounded' [] _ = error "bounded called with base 0" - bounded'' dps [] = [] <$ P.notFollowedBy (P.choice dps) <|> toomuch + bounded'' dps [] = [] <$ notFollowedBy (choice dps) <|> toomuch bounded'' dps (bd : bds) = - let anyd :: m Char - anyd = P.choice dps + let anyd :: ParsecParser Char + anyd = choice dps - nomore :: m () - nomore = P.notFollowedBy anyd <|> toomuch + nomore :: ParsecParser () + nomore = notFollowedBy anyd <|> toomuch (low, ex, high) = case splitAt bd dps of (low', ex' : high') -> (low', ex', high') (_, _) -> error "escapeCode: Logic error" - in ((:) <$> P.choice low <*> atMost (length bds) anyd) <* nomore + in ((:) <$> choice low <*> atMost (length bds) anyd) <* nomore <|> ((:) <$> ex <*> ([] <$ nomore <|> bounded'' dps bds)) <|> if not (null bds) - then (:) <$> P.choice high <*> atMost (length bds - 1) anyd <* nomore + then (:) <$> choice high <*> atMost (length bds - 1) anyd <* nomore else empty atMost n p | n <= 0 = pure [] | otherwise = ((:) <$> p <*> atMost (n - 1) p) <|> pure [] - charEsc :: m Char - charEsc = P.choice $ parseEsc <$> escMap + charEsc :: ParsecParser Char + charEsc = choice $ parseEsc <$> escMap - parseEsc (c, code) = code <$ P.char c + parseEsc (c, code) = code <$ char c escMap = zip "abfnrtv\\\"\'" "\a\b\f\n\r\t\v\\\"\'" - charAscii :: m Char - charAscii = P.choice $ parseAscii <$> asciiMap + charAscii :: ParsecParser Char + charAscii = choice $ parseAscii <$> asciiMap - parseAscii (asc, code) = P.try $ code <$ P.string asc + parseAscii (asc, code) = try $ code <$ string asc asciiMap = zip (ascii3codes ++ ascii2codes) (ascii3 ++ ascii2) ascii2codes, ascii3codes :: [String] ascii2codes = @@ -574,3 +631,282 @@ escapeCode = (charEsc <|> charNum <|> charAscii <|> charControl) P. "escape c ascii2, ascii3 :: String ascii2 = "\BS\HT\LF\VT\FF\CR\SO\SI\EM\FS\GS\RS\US\SP" ascii3 = "\NUL\SOH\STX\ETX\EOT\ENQ\ACK\BEL\DLE\DC1\DC2\DC3\DC4\NAK\SYN\ETB\CAN\SUB\ESC\DEL" + +------------------------------------------------------------------------------- +-- Parsers based on the @parsers@ package +------------------------------------------------------------------------------- + +-- | @choice ps@ tries to apply the parsers in the list @ps@ in order, +-- until one of them succeeds. Returns the value of the succeeding +-- parser. +choice :: [ParsecParser a] -> ParsecParser a +choice = asum +{-# INLINE choice #-} + +-- | @option x p@ tries to apply parser @p@. If @p@ fails without +-- consuming input, it returns the value @x@, otherwise the value +-- returned by @p@. +-- +-- > priority = option 0 (digitToInt <$> digit) +option :: a -> ParsecParser a -> ParsecParser a +option x p = p <|> pure x +{-# INLINE option #-} + +-- | @skipOptional p@ tries to apply parser @p@. It will parse @p@ or nothing. +-- It only fails if @p@ fails after consuming input. It discards the result +-- of @p@. (Plays the role of parsec's optional, which conflicts with Applicative's optional) +skipOptional :: ParsecParser a -> ParsecParser () +skipOptional p = (() <$ p) <|> pure () +{-# INLINE skipOptional #-} + +-- | @between open close p@ parses @open@, followed by @p@ and @close@. +-- Returns the value returned by @p@. +-- +-- > braces = between (symbol "{") (symbol "}") +between :: Applicative m => m bra -> m ket -> m a -> m a +between bra ket p = bra *> p <* ket +{-# INLINE between #-} + +-- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated +-- by @sep@. Returns a list of values returned by @p@. +-- +-- > commaSep p = p `sepBy` (symbol ",") +sepBy :: ParsecParser a -> ParsecParser sep -> ParsecParser [a] +sepBy p sep = toList <$> sepByNonEmpty p sep <|> pure [] +{-# INLINE sepBy #-} + +-- | @sepByNonEmpty p sep@ parses /one/ or more occurrences of @p@, separated +-- by @sep@. Returns a non-empty list of values returned by @p@. +sepByNonEmpty :: ParsecParser a -> ParsecParser sep -> ParsecParser (NonEmpty a) +sepByNonEmpty p sep = (:|) <$> p <*> many (sep *> p) +{-# INLINE sepByNonEmpty #-} + +-- | @sepEndByNonEmpty p sep@ parses /one/ or more occurrences of @p@, +-- separated and optionally ended by @sep@. Returns a non-empty list of values +-- returned by @p@. +sepEndByNonEmpty :: ParsecParser a -> ParsecParser sep -> ParsecParser (NonEmpty a) +sepEndByNonEmpty p sep = (:|) <$> p <*> ((sep *> sepEndBy p sep) <|> pure []) + +-- | @sepEndBy p sep@ parses /zero/ or more occurrences of @p@, +-- separated and optionally ended by @sep@, ie. haskell style +-- statements. Returns a list of values returned by @p@. +-- +-- > haskellStatements = haskellStatement `sepEndBy` semi +sepEndBy :: ParsecParser a -> ParsecParser sep -> ParsecParser [a] +sepEndBy p sep = toList <$> sepEndByNonEmpty p sep <|> pure [] +{-# INLINE sepEndBy #-} + +-- | @endByNonEmpty p sep@ parses /one/ or more occurrences of @p@, separated +-- and ended by @sep@. Returns a non-empty list of values returned by @p@. +endByNonEmpty :: ParsecParser a -> ParsecParser sep -> ParsecParser (NonEmpty a) +endByNonEmpty p sep = NE.some1 (p <* sep) +{-# INLINE endByNonEmpty #-} + +-- | @endBy p sep@ parses /zero/ or more occurrences of @p@, separated +-- and ended by @sep@. Returns a list of values returned by @p@. +-- +-- > cStatements = cStatement `endBy` semi +endBy :: ParsecParser a -> ParsecParser sep -> ParsecParser [a] +endBy p sep = many (p <* sep) +{-# INLINE endBy #-} + +-- | @count n p@ parses @n@ occurrences of @p@. If @n@ is smaller or +-- equal to zero, the parser equals to @return []@. Returns a list of +-- @n@ values returned by @p@. +count :: Applicative m => Int -> m a -> m [a] +count n p + | n <= 0 = pure [] + | otherwise = sequenceA (replicate n p) +{-# INLINE count #-} + +-- | @chainr p op x@ parses /zero/ or more occurrences of @p@, +-- separated by @op@ Returns a value obtained by a /right/ associative +-- application of all functions returned by @op@ to the values returned +-- by @p@. If there are no occurrences of @p@, the value @x@ is +-- returned. +chainr :: ParsecParser a -> ParsecParser (a -> a -> a) -> a -> ParsecParser a +chainr p op x = chainr1 p op <|> pure x +{-# INLINE chainr #-} + +-- | @chainl p op x@ parses /zero/ or more occurrences of @p@, +-- separated by @op@. Returns a value obtained by a /left/ associative +-- application of all functions returned by @op@ to the values returned +-- by @p@. If there are zero occurrences of @p@, the value @x@ is +-- returned. +chainl :: ParsecParser a -> ParsecParser (a -> a -> a) -> a -> ParsecParser a +chainl p op x = chainl1 p op <|> pure x +{-# INLINE chainl #-} + +-- | @chainl1 p op x@ parses /one/ or more occurrences of @p@, +-- separated by @op@ Returns a value obtained by a /left/ associative +-- application of all functions returned by @op@ to the values returned +-- by @p@. . This parser can for example be used to eliminate left +-- recursion which typically occurs in expression grammars. +-- +-- > expr = term `chainl1` addop +-- > term = factor `chainl1` mulop +-- > factor = parens expr <|> integer +-- > +-- > mulop = (*) <$ symbol "*" +-- > <|> div <$ symbol "/" +-- > +-- > addop = (+) <$ symbol "+" +-- > <|> (-) <$ symbol "-" +chainl1 :: ParsecParser a -> ParsecParser (a -> a -> a) -> ParsecParser a +chainl1 p op = scan + where + scan = p <**> rst + rst = (\f y g x -> g (f x y)) <$> op <*> p <*> rst <|> pure id +{-# INLINE chainl1 #-} + +-- | @chainr1 p op x@ parses /one/ or more occurrences of @p@, +-- separated by @op@ Returns a value obtained by a /right/ associative +-- application of all functions returned by @op@ to the values returned +-- by @p@. +chainr1 :: ParsecParser a -> ParsecParser (a -> a -> a) -> ParsecParser a +chainr1 p op = scan + where + scan = p <**> rst + rst = (flip <$> op <*> scan) <|> pure id +{-# INLINE chainr1 #-} + +-- | @manyTill p end@ applies parser @p@ /zero/ or more times until +-- parser @end@ succeeds. Returns the list of values returned by @p@. +-- This parser can be used to scan comments: +-- +-- > simpleComment = do{ string "")) +-- > } +-- +-- Note the overlapping parsers @anyChar@ and @string \"-->\"@, and +-- therefore the use of the 'try' combinator. +manyTill :: ParsecParser a -> ParsecParser end -> ParsecParser [a] +manyTill p end = go where go = ([] <$ end) <|> ((:) <$> p <*> go) +{-# INLINE manyTill #-} + +-- | @oneOf cs@ succeeds if the current character is in the supplied +-- list of characters @cs@. Returns the parsed character. See also +-- 'satisfy'. +-- +-- > vowel = oneOf "aeiou" +oneOf :: [Char] -> ParsecParser Char +oneOf xs = liftParsec $ Parsec.satisfy (\c -> c `elem` xs) +{-# INLINE oneOf #-} + +-- | As the dual of 'oneOf', @noneOf cs@ succeeds if the current +-- character is /not/ in the supplied list of characters @cs@. Returns the +-- parsed character. +-- +-- > consonant = noneOf "aeiou" +noneOf :: [Char] -> ParsecParser Char +noneOf xs = liftParsec $ Parsec.satisfy (\c -> c `notElem` xs) +{-# INLINE noneOf #-} + +-- | Skips /zero/ or more white space characters. See also 'skipMany'. +spaces :: ParsecParser () +spaces = skipMany space "white space" +{-# INLINE spaces #-} + +-- | Parses a white space character (any character which satisfies 'isSpace') +-- Returns the parsed character. +space :: ParsecParser Char +space = satisfy isSpace "space" +{-# INLINE space #-} + +-- | Parses a newline character (\'\\n\'). Returns a newline character. +newline :: ParsecParser Char +newline = char '\n' "new-line" +{-# INLINE newline #-} + +-- | Parses a tab character (\'\\t\'). Returns a tab character. +tab :: ParsecParser Char +tab = char '\t' "tab" +{-# INLINE tab #-} + +-- | Parses an upper case letter. Returns the parsed character. +upper :: ParsecParser Char +upper = satisfy isUpper "uppercase letter" +{-# INLINE upper #-} + +-- | Parses a lower case character. Returns the parsed character. +lower :: ParsecParser Char +lower = satisfy isLower "lowercase letter" +{-# INLINE lower #-} + +-- | Parses a letter or digit. Returns the parsed character. +alphaNum :: ParsecParser Char +alphaNum = satisfy isAlphaNum "letter or digit" +{-# INLINE alphaNum #-} + +-- | Parses a letter (an upper case or lower case character). Returns the +-- parsed character. +letter :: ParsecParser Char +letter = satisfy isAlpha "letter" +{-# INLINE letter #-} + +-- | Parses a digit. Returns the parsed character. +digit :: ParsecParser Char +digit = satisfy isDigit "digit" +{-# INLINE digit #-} + +-- | Parses a hexadecimal digit (a digit or a letter between \'a\' and +-- \'f\' or \'A\' and \'F\'). Returns the parsed character. +hexDigit :: ParsecParser Char +hexDigit = satisfy isHexDigit "hexadecimal digit" +{-# INLINE hexDigit #-} + +-- | Parses an octal digit (a character between \'0\' and \'7\'). Returns +-- the parsed character. +octDigit :: ParsecParser Char +octDigit = satisfy isOctDigit "octal digit" +{-# INLINE octDigit #-} + +satisfyRange :: Char -> Char -> ParsecParser Char +satisfyRange a z = satisfy (\c -> c >= a && c <= z) +{-# INLINE satisfyRange #-} + +------------------------------------------------------------------------------- +-- Our additions +------------------------------------------------------------------------------- + +integral :: Integral a => ParsecParser a +integral = toNumber <$> some d "integral" + where + toNumber = foldl' (\a b -> a * 10 + b) 0 + d = f <$> satisfyRange '0' '9' + f '0' = 0 + f '1' = 1 + f '2' = 2 + f '3' = 3 + f '4' = 4 + f '5' = 5 + f '6' = 6 + f '7' = 7 + f '8' = 8 + f '9' = 9 + f _ = error "panic! integral" +{-# INLINE integral #-} + +-- | Accepts negative (starting with @-@) and positive (without sign) integral +-- numbers. +-- +-- @since 3.4.0.0 +signedIntegral :: Integral a => ParsecParser a +signedIntegral = negate <$ char '-' <*> integral <|> integral +{-# INLINE signedIntegral #-} + +-- | Greedily munch characters while predicate holds. +-- Require at least one character. +munch1 :: (Char -> Bool) -> ParsecParser String +munch1 = some . satisfy +{-# INLINE munch1 #-} + +-- | Greedily munch characters while predicate holds. +-- Always succeeds. +munch :: (Char -> Bool) -> ParsecParser String +munch = many . satisfy +{-# INLINE munch #-} + +skipSpaces1 :: ParsecParser () +skipSpaces1 = skipSome space +{-# INLINE skipSpaces1 #-} diff --git a/Cabal-syntax/src/Distribution/SPDX/License.hs b/Cabal-syntax/src/Distribution/SPDX/License.hs index af271e9115a..a3fdba2473f 100644 --- a/Cabal-syntax/src/Distribution/SPDX/License.hs +++ b/Cabal-syntax/src/Distribution/SPDX/License.hs @@ -12,7 +12,7 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.SPDX.LicenseExpression -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | Declared license. @@ -60,5 +60,5 @@ instance Pretty License where -- -- >>> eitherParsec "NONE" :: Either String License -- Right NONE -instance Parsec License where +instance CabalParsec License where parsec = NONE <$ P.try (P.string "NONE") <|> License <$> parsec diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs index 6246d8df41d..60dfcce7322 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseExceptionId.hs @@ -23,7 +23,7 @@ import Distribution.SPDX.LicenseListVersion import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary import qualified Data.Map.Strict as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp ------------------------------------------------------------------------------- @@ -116,7 +116,7 @@ instance Structured LicenseExceptionId where instance Pretty LicenseExceptionId where pretty = Disp.text . licenseExceptionId -instance Parsec LicenseExceptionId where +instance CabalParsec LicenseExceptionId where parsec = do n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' v <- askCabalSpecVersion diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseExpression.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseExpression.hs index c77314746f8..8524103ce3a 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseExpression.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseExpression.hs @@ -18,7 +18,7 @@ import Distribution.SPDX.LicenseListVersion import Distribution.SPDX.LicenseReference import Distribution.Utils.Generic (isAsciiAlphaNum) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | SPDX License Expression. @@ -81,7 +81,7 @@ instance Pretty SimpleLicenseExpression where pretty (ELicenseIdPlus i) = pretty i <<>> Disp.char '+' pretty (ELicenseRef r) = pretty r -instance Parsec SimpleLicenseExpression where +instance CabalParsec SimpleLicenseExpression where parsec = idstring >>= simple where simple n @@ -101,7 +101,7 @@ instance Parsec SimpleLicenseExpression where then return (ELicenseIdPlus l) else return (ELicenseId l) -idstring :: P.CharParsing m => m String +idstring :: ParsecParser String idstring = P.munch1 $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' -- returns suffix part @@ -110,7 +110,7 @@ isPrefixOfMaybe pfx s | pfx `isPrefixOf` s = Just (drop (length pfx) s) | otherwise = Nothing -instance Parsec LicenseExpression where +instance CabalParsec LicenseExpression where parsec = expr where expr = compoundOr diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs index 5af7fd86e8b..6a9d0b4b1ab 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseId.hs @@ -26,7 +26,7 @@ import Distribution.SPDX.LicenseListVersion import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary import qualified Data.Map.Strict as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp ------------------------------------------------------------------------------- @@ -671,7 +671,7 @@ instance Pretty LicenseId where -- >>> eitherParsec "BSD3" :: Either String LicenseId -- Left "...Unknown SPDX license identifier: 'BSD3' Do you mean BSD-3-Clause?" -- -instance Parsec LicenseId where +instance CabalParsec LicenseId where parsec = do n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' v <- askCabalSpecVersion diff --git a/Cabal-syntax/src/Distribution/SPDX/LicenseReference.hs b/Cabal-syntax/src/Distribution/SPDX/LicenseReference.hs index 949d6c4d15d..61f93e9ccee 100644 --- a/Cabal-syntax/src/Distribution/SPDX/LicenseReference.hs +++ b/Cabal-syntax/src/Distribution/SPDX/LicenseReference.hs @@ -16,7 +16,7 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.Utils.Generic (isAsciiAlphaNum) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | A user defined license reference denoted by @LicenseRef-[idstring]@ (for a license not on the SPDX License List); @@ -45,7 +45,7 @@ instance Pretty LicenseRef where pretty (LicenseRef (Just d) l) = Disp.text "DocumentRef-" <<>> Disp.text d <<>> Disp.char ':' <<>> Disp.text "LicenseRef-" <<>> Disp.text l -instance Parsec LicenseRef where +instance CabalParsec LicenseRef where parsec = name <|> doc where name = do diff --git a/Cabal-syntax/src/Distribution/System.hs b/Cabal-syntax/src/Distribution/System.hs index e1e75aa2315..99675362528 100644 --- a/Cabal-syntax/src/Distribution/System.hs +++ b/Cabal-syntax/src/Distribution/System.hs @@ -56,7 +56,7 @@ import qualified System.Info (arch, os) import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | How strict to be when classifying strings into the 'OS' and 'Arch' enums. @@ -159,7 +159,7 @@ instance Pretty OS where pretty (OtherOS name) = Disp.text name pretty other = Disp.text (lowercase (show other)) -instance Parsec OS where +instance CabalParsec OS where parsec = classifyOS Compat <$> parsecIdent classifyOS :: ClassificationStrictness -> String -> OS @@ -265,7 +265,7 @@ instance Pretty Arch where pretty (OtherArch name) = Disp.text name pretty other = Disp.text (lowercase (show other)) -instance Parsec Arch where +instance CabalParsec Arch where parsec = classifyArch Strict <$> parsecIdent classifyArch :: ClassificationStrictness -> String -> Arch @@ -297,7 +297,7 @@ instance NFData Platform where rnf = genericRnf instance Pretty Platform where pretty (Platform arch os) = pretty arch <<>> Disp.char '-' <<>> pretty os -instance Parsec Platform where +instance CabalParsec Platform where -- TODO: there are ambiguous platforms like: `arch-word-os` -- which could be parsed as -- * Platform "arch-word" "os" @@ -326,7 +326,7 @@ buildPlatform = Platform buildArch buildOS -- Utils: -parsecIdent :: CabalParsing m => m String +parsecIdent :: ParsecParser String parsecIdent = (:) <$> firstChar <*> rest where firstChar = P.satisfy isAlpha diff --git a/Cabal-syntax/src/Distribution/Text.hs b/Cabal-syntax/src/Distribution/Text.hs index 0589e35261e..8f4b7715856 100644 --- a/Cabal-syntax/src/Distribution/Text.hs +++ b/Cabal-syntax/src/Distribution/Text.hs @@ -9,5 +9,5 @@ import Distribution.Pretty display :: Pretty a => a -> String display = prettyShow -simpleParse :: Parsec a => String -> Maybe a +simpleParse :: CabalParsec a => String -> Maybe a simpleParse = simpleParsec diff --git a/Cabal-syntax/src/Distribution/Types/AbiDependency.hs b/Cabal-syntax/src/Distribution/Types/AbiDependency.hs index 2f380d15af2..0b3732dd511 100644 --- a/Cabal-syntax/src/Distribution/Types/AbiDependency.hs +++ b/Cabal-syntax/src/Distribution/Types/AbiDependency.hs @@ -9,8 +9,8 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P import qualified Distribution.Package as Package +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | An ABI dependency is a dependency on a library which also @@ -33,7 +33,7 @@ instance Pretty AbiDependency where pretty (AbiDependency uid abi) = pretty uid <<>> Disp.char '=' <<>> pretty abi -instance Parsec AbiDependency where +instance CabalParsec AbiDependency where parsec = do uid <- parsec _ <- P.char '=' diff --git a/Cabal-syntax/src/Distribution/Types/AbiHash.hs b/Cabal-syntax/src/Distribution/Types/AbiHash.hs index a1be416c4ba..3611a0b4002 100644 --- a/Cabal-syntax/src/Distribution/Types/AbiHash.hs +++ b/Cabal-syntax/src/Distribution/Types/AbiHash.hs @@ -12,8 +12,8 @@ import Distribution.Compat.Prelude import Distribution.Utils.ShortText import Prelude () -import qualified Distribution.Compat.CharParsing as P import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Text.PrettyPrint (text) @@ -59,5 +59,5 @@ instance NFData AbiHash where rnf = genericRnf instance Pretty AbiHash where pretty = text . unAbiHash -instance Parsec AbiHash where +instance CabalParsec AbiHash where parsec = fmap mkAbiHash (P.munch isAlphaNum) diff --git a/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs b/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs index 9dd3fad3ff9..e1f1a622fc7 100644 --- a/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs +++ b/Cabal-syntax/src/Distribution/Types/BenchmarkType.hs @@ -11,7 +11,7 @@ module Distribution.Types.BenchmarkType import Distribution.Compat.Prelude import Prelude () -import Distribution.Parsec +import Distribution.Parsec hiding (char) import Distribution.Pretty import Distribution.Version import Text.PrettyPrint (char, text) @@ -38,7 +38,7 @@ instance Pretty BenchmarkType where pretty (BenchmarkTypeExe ver) = text "exitcode-stdio-" <<>> pretty ver pretty (BenchmarkTypeUnknown name ver) = text name <<>> char '-' <<>> pretty ver -instance Parsec BenchmarkType where +instance CabalParsec BenchmarkType where parsec = parsecStandard $ \ver name -> case name of "exitcode-stdio" -> BenchmarkTypeExe ver _ -> BenchmarkTypeUnknown name ver diff --git a/Cabal-syntax/src/Distribution/Types/BuildType.hs b/Cabal-syntax/src/Distribution/Types/BuildType.hs index b94279eaf2e..e964e751332 100644 --- a/Cabal-syntax/src/Distribution/Types/BuildType.hs +++ b/Cabal-syntax/src/Distribution/Types/BuildType.hs @@ -14,7 +14,7 @@ import Distribution.CabalSpecVersion (CabalSpecVersion (..)) import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | The type of build system used by this package. @@ -42,7 +42,7 @@ knownBuildTypes = [Simple, Configure, Make, Custom, Hooks] instance Pretty BuildType where pretty = Disp.text . show -instance Parsec BuildType where +instance CabalParsec BuildType where parsec = do name <- P.munch1 isAlphaNum case name of diff --git a/Cabal-syntax/src/Distribution/Types/ComponentId.hs b/Cabal-syntax/src/Distribution/Types/ComponentId.hs index 47cf1d97ee3..a1b517ee714 100644 --- a/Cabal-syntax/src/Distribution/Types/ComponentId.hs +++ b/Cabal-syntax/src/Distribution/Types/ComponentId.hs @@ -15,7 +15,7 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import Text.PrettyPrint (text) -- | A 'ComponentId' uniquely identifies the transitive source @@ -63,7 +63,7 @@ instance Structured ComponentId instance Pretty ComponentId where pretty = text . unComponentId -instance Parsec ComponentId where +instance CabalParsec ComponentId where parsec = mkComponentId `fmap` P.munch1 abi_char where abi_char c = isAlphaNum c || c `elem` "-_." diff --git a/Cabal-syntax/src/Distribution/Types/ComponentName.hs b/Cabal-syntax/src/Distribution/Types/ComponentName.hs index 01ed6f7655f..646ffcb5e8c 100644 --- a/Cabal-syntax/src/Distribution/Types/ComponentName.hs +++ b/Cabal-syntax/src/Distribution/Types/ComponentName.hs @@ -18,7 +18,7 @@ import Distribution.Pretty import Distribution.Types.LibraryName import Distribution.Types.UnqualComponentName -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- Libraries live in a separate namespace, so must distinguish @@ -61,7 +61,7 @@ instance Pretty ComponentName where pretty (CTestName str) = Disp.text "test:" <<>> pretty str pretty (CBenchName str) = Disp.text "bench:" <<>> pretty str -instance Parsec ComponentName where +instance CabalParsec ComponentName where -- note: this works as lib/flib/... all start with different character! parsec = parseComposite <|> parseLib where diff --git a/Cabal-syntax/src/Distribution/Types/Dependency.hs b/Cabal-syntax/src/Distribution/Types/Dependency.hs index 10d0506b57e..5843ec1a015 100644 --- a/Cabal-syntax/src/Distribution/Types/Dependency.hs +++ b/Cabal-syntax/src/Distribution/Types/Dependency.hs @@ -18,8 +18,6 @@ import Distribution.Types.VersionRange (isAnyVersionLight) import Distribution.Version (VersionRange, anyVersion, simplifyVersionRange) import Distribution.CabalSpecVersion -import Distribution.Compat.CharParsing (char, spaces) -import Distribution.Compat.Parsing (between, option) import Distribution.Parsec import Distribution.Pretty import Distribution.Types.LibraryName @@ -138,7 +136,7 @@ instance Pretty Dependency where -- -- >>> map (`simpleParsec'` "mylib:sub") [CabalSpecV2_4, CabalSpecV3_0] :: [Maybe Dependency] -- [Nothing,Just (Dependency (PackageName "mylib") (OrLaterVersion (mkVersion [0])) (fromNonEmpty (LSubLibName (UnqualComponentName "sub") :| [])))] -instance Parsec Dependency where +instance CabalParsec Dependency where parsec = do name <- parsec @@ -158,7 +156,7 @@ instance Parsec Dependency where (spaces *> char '}') (NES.fromNonEmpty <$> parsecCommaNonEmpty parseLib) -versionGuardMultilibs :: CabalParsing m => m () +versionGuardMultilibs :: ParsecParser () versionGuardMultilibs = do csv <- askCabalSpecVersion when (csv < CabalSpecV3_0) $ diff --git a/Cabal-syntax/src/Distribution/Types/ExeDependency.hs b/Cabal-syntax/src/Distribution/Types/ExeDependency.hs index 17a79703fcc..238cc877611 100644 --- a/Cabal-syntax/src/Distribution/Types/ExeDependency.hs +++ b/Cabal-syntax/src/Distribution/Types/ExeDependency.hs @@ -16,7 +16,7 @@ import Distribution.Types.PackageName import Distribution.Types.UnqualComponentName import Distribution.Version (VersionRange, anyVersion, isAnyVersion) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP -- | Describes a dependency on an executable from a package @@ -60,7 +60,7 @@ instance Pretty ExeDependency where -- -- >>> simpleParsec "happy :happy >= 1.19.12" :: Maybe ExeDependency -- Nothing -instance Parsec ExeDependency where +instance CabalParsec ExeDependency where parsec = do name <- parsec _ <- P.char ':' diff --git a/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs b/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs index 1221fae1c1a..c4726c0c918 100644 --- a/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs +++ b/Cabal-syntax/src/Distribution/Types/ExecutableScope.hs @@ -12,7 +12,7 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp data ExecutableScope @@ -24,7 +24,7 @@ instance Pretty ExecutableScope where pretty ExecutablePublic = Disp.text "public" pretty ExecutablePrivate = Disp.text "private" -instance Parsec ExecutableScope where +instance CabalParsec ExecutableScope where parsec = P.try pub <|> pri where pub = ExecutablePublic <$ P.string "public" diff --git a/Cabal-syntax/src/Distribution/Types/ExposedModule.hs b/Cabal-syntax/src/Distribution/Types/ExposedModule.hs index 4afd03a3263..5b2d367a53b 100644 --- a/Cabal-syntax/src/Distribution/Types/ExposedModule.hs +++ b/Cabal-syntax/src/Distribution/Types/ExposedModule.hs @@ -11,7 +11,7 @@ import Distribution.ModuleName import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp data ExposedModule = ExposedModule @@ -29,7 +29,7 @@ instance Pretty ExposedModule where Nothing -> Disp.empty ] -instance Parsec ExposedModule where +instance CabalParsec ExposedModule where parsec = do m <- parsecMaybeQuoted parsec P.spaces diff --git a/Cabal-syntax/src/Distribution/Types/Flag.hs b/Cabal-syntax/src/Distribution/Types/Flag.hs index eff71748d9f..9d16367749f 100644 --- a/Cabal-syntax/src/Distribution/Types/Flag.hs +++ b/Cabal-syntax/src/Distribution/Types/Flag.hs @@ -42,7 +42,7 @@ import Distribution.Parsec import Distribution.Pretty import qualified Data.Map as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- ----------------------------------------------------------------------------- @@ -111,7 +111,7 @@ instance Structured FlagName instance Pretty FlagName where pretty = Disp.text . unFlagName -instance Parsec FlagName where +instance CabalParsec FlagName where -- Note: we don't check that FlagName doesn't have leading dash, -- cabal check will do that. parsec = mkFlagName . lowercase <$> parsec' @@ -278,7 +278,7 @@ instance Pretty FlagAssignment where -- Nothing -- -- @since 3.4.0.0 -instance Parsec FlagAssignment where +instance CabalParsec FlagAssignment where parsec = parsecFlagAssignment -- | Pretty-prints a flag assignment. @@ -286,7 +286,7 @@ dispFlagAssignment :: FlagAssignment -> Disp.Doc dispFlagAssignment = Disp.hsep . map (Disp.text . showFlagValue) . unFlagAssignment -- | Parses a flag assignment. -parsecFlagAssignment :: CabalParsing m => m FlagAssignment +parsecFlagAssignment :: ParsecParser FlagAssignment parsecFlagAssignment = mkFlagAssignment <$> sepByEnding (onFlag <|> offFlag) P.skipSpaces1 where onFlag = do @@ -298,7 +298,7 @@ parsecFlagAssignment = mkFlagAssignment <$> sepByEnding (onFlag <|> offFlag) P.s f <- parsec return (f, False) - sepByEnding :: CabalParsing m => m a -> m b -> m [a] + sepByEnding :: ParsecParser a -> ParsecParser b -> ParsecParser [a] sepByEnding p sep = afterSeparator where element = (:) <$> p <*> afterElement @@ -310,7 +310,7 @@ parsecFlagAssignment = mkFlagAssignment <$> sepByEnding (onFlag <|> offFlag) P.s -- The flags have to explicitly start with minus or plus. -- -- @since 3.4.0.0 -parsecFlagAssignmentNonEmpty :: CabalParsing m => m FlagAssignment +parsecFlagAssignmentNonEmpty :: ParsecParser FlagAssignment parsecFlagAssignmentNonEmpty = mkFlagAssignment <$> sepByEnding1 (onFlag <|> offFlag) P.skipSpaces1 where onFlag = do @@ -322,7 +322,7 @@ parsecFlagAssignmentNonEmpty = mkFlagAssignment <$> sepByEnding1 (onFlag <|> off f <- parsec return (f, False) - sepByEnding1 :: CabalParsing m => m a -> m b -> m [a] + sepByEnding1 :: ParsecParser a -> ParsecParser b -> ParsecParser [a] sepByEnding1 p sep = element where element = (:) <$> p <*> afterElement @@ -359,7 +359,7 @@ legacyShowFlagValue (f, False) = '-' : unFlagName f -- We need this as far as we support custom setups older than 2.2.0.0 -- -- @since 3.4.0.0 -legacyParsecFlagAssignment :: CabalParsing m => m FlagAssignment +legacyParsecFlagAssignment :: ParsecParser FlagAssignment legacyParsecFlagAssignment = mkFlagAssignment <$> P.sepBy (onFlag <|> offFlag) P.skipSpaces1 diff --git a/Cabal-syntax/src/Distribution/Types/ForeignLib.hs b/Cabal-syntax/src/Distribution/Types/ForeignLib.hs index 0da75b06cc6..45a44262287 100644 --- a/Cabal-syntax/src/Distribution/Types/ForeignLib.hs +++ b/Cabal-syntax/src/Distribution/Types/ForeignLib.hs @@ -31,7 +31,7 @@ import Distribution.Utils.Path import Distribution.Version import Data.Monoid -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp import qualified Text.Read as Read @@ -91,7 +91,7 @@ instance Pretty LibVersionInfo where pretty (LibVersionInfo c r a) = Disp.hcat $ Disp.punctuate (Disp.char ':') $ map Disp.int [c, r, a] -instance Parsec LibVersionInfo where +instance CabalParsec LibVersionInfo where parsec = do c <- P.integral (r, a) <- P.option (0, 0) $ do diff --git a/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs b/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs index 5ed65410e70..7474b369a26 100644 --- a/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs +++ b/Cabal-syntax/src/Distribution/Types/ForeignLibOption.hs @@ -12,7 +12,7 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp data ForeignLibOption @@ -27,7 +27,7 @@ data ForeignLibOption instance Pretty ForeignLibOption where pretty ForeignLibStandalone = Disp.text "standalone" -instance Parsec ForeignLibOption where +instance CabalParsec ForeignLibOption where parsec = do name <- P.munch1 (\c -> isAlphaNum c || c == '-') case name of diff --git a/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs b/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs index 23617b80c48..9b4a1358c4c 100644 --- a/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs +++ b/Cabal-syntax/src/Distribution/Types/ForeignLibType.hs @@ -15,7 +15,7 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | What kind of foreign library is to be built? @@ -34,7 +34,7 @@ instance Pretty ForeignLibType where pretty ForeignLibNativeStatic = Disp.text "native-static" pretty ForeignLibTypeUnknown = Disp.text "unknown" -instance Parsec ForeignLibType where +instance CabalParsec ForeignLibType where parsec = do name <- P.munch1 (\c -> isAlphaNum c || c == '-') return $ case name of diff --git a/Cabal-syntax/src/Distribution/Types/IncludeRenaming.hs b/Cabal-syntax/src/Distribution/Types/IncludeRenaming.hs index c8cb70d91f1..4534d917dc7 100644 --- a/Cabal-syntax/src/Distribution/Types/IncludeRenaming.hs +++ b/Cabal-syntax/src/Distribution/Types/IncludeRenaming.hs @@ -12,8 +12,8 @@ import Prelude () import Distribution.Types.ModuleRenaming -import qualified Distribution.Compat.CharParsing as P import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Text.PrettyPrint (text) import qualified Text.PrettyPrint as Disp @@ -50,7 +50,7 @@ instance Pretty IncludeRenaming where else text "requires" <+> pretty req_rn ) -instance Parsec IncludeRenaming where +instance CabalParsec IncludeRenaming where parsec = do prov_rn <- parsec req_rn <- P.option defaultRenaming $ P.try $ do diff --git a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index 7578907b590..e2558f26173 100644 --- a/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal-syntax/src/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -30,7 +30,7 @@ import Distribution.Version import qualified Data.Char as Char import qualified Data.Map as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Distribution.SPDX as SPDX import qualified Text.PrettyPrint as Disp @@ -201,7 +201,7 @@ newtype ExposedModules = ExposedModules {getExposedModules :: [ExposedModule]} instance Newtype [ExposedModule] ExposedModules -instance Parsec ExposedModules where +instance CabalParsec ExposedModules where parsec = ExposedModules <$> parsecOptCommaList parsec instance Pretty ExposedModules where @@ -214,7 +214,7 @@ instance Newtype String CompatPackageKey instance Pretty CompatPackageKey where pretty = Disp.text . getCompatPackageKey -instance Parsec CompatPackageKey where +instance CabalParsec CompatPackageKey where parsec = CompatPackageKey <$> P.munch1 uid_char where uid_char c = Char.isAlphaNum c || c `elem` ("-_.=[],:<>+" :: String) @@ -226,7 +226,7 @@ instance Newtype [(ModuleName, OpenModule)] InstWith instance Pretty InstWith where pretty = dispOpenModuleSubst . Map.fromList . getInstWith -instance Parsec InstWith where +instance CabalParsec InstWith where parsec = InstWith . Map.toList <$> parsecOpenModuleSubst -- | SPDX License expression or legacy license. Lenient parser, accepts either. @@ -234,7 +234,7 @@ newtype SpecLicenseLenient = SpecLicenseLenient {getSpecLicenseLenient :: Either instance Newtype (Either SPDX.License License) SpecLicenseLenient -instance Parsec SpecLicenseLenient where +instance CabalParsec SpecLicenseLenient where parsec = fmap SpecLicenseLenient $ Left <$> P.try parsec <|> Right <$> parsec instance Pretty SpecLicenseLenient where diff --git a/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs b/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs index 7acf028d0b3..06bba7512ae 100644 --- a/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs +++ b/Cabal-syntax/src/Distribution/Types/LegacyExeDependency.hs @@ -12,7 +12,7 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.Version (VersionRange, anyVersion) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | Describes a legacy `build-tools`-style dependency on an executable @@ -36,7 +36,7 @@ instance Pretty LegacyExeDependency where pretty (LegacyExeDependency name ver) = Disp.text name <+> pretty ver -instance Parsec LegacyExeDependency where +instance CabalParsec LegacyExeDependency where parsec = do name <- parsecMaybeQuoted nameP P.spaces diff --git a/Cabal-syntax/src/Distribution/Types/LibraryName.hs b/Cabal-syntax/src/Distribution/Types/LibraryName.hs index 2b8f53f4f89..7989e028fd8 100644 --- a/Cabal-syntax/src/Distribution/Types/LibraryName.hs +++ b/Cabal-syntax/src/Distribution/Types/LibraryName.hs @@ -21,7 +21,7 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.Types.UnqualComponentName -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp data LibraryName @@ -42,7 +42,7 @@ prettyLibraryNameComponent :: LibraryName -> Disp.Doc prettyLibraryNameComponent LMainLibName = Disp.text "lib" prettyLibraryNameComponent (LSubLibName str) = Disp.text "lib:" <<>> pretty str -parsecLibraryNameComponent :: CabalParsing m => m LibraryName +parsecLibraryNameComponent :: ParsecParser LibraryName parsecLibraryNameComponent = do _ <- P.string "lib" parseComposite <|> parseSingle diff --git a/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs b/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs index bf113488a5c..c4dc740e5cf 100644 --- a/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs +++ b/Cabal-syntax/src/Distribution/Types/LibraryVisibility.hs @@ -12,7 +12,7 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | Multi-lib visibility @@ -29,7 +29,7 @@ instance Pretty LibraryVisibility where pretty LibraryVisibilityPublic = Disp.text "public" pretty LibraryVisibilityPrivate = Disp.text "private" -instance Parsec LibraryVisibility where +instance CabalParsec LibraryVisibility where parsec = do name <- P.munch1 isAlpha case name of diff --git a/Cabal-syntax/src/Distribution/Types/Mixin.hs b/Cabal-syntax/src/Distribution/Types/Mixin.hs index 63fa6e30fd5..8c44b9e76b7 100644 --- a/Cabal-syntax/src/Distribution/Types/Mixin.hs +++ b/Cabal-syntax/src/Distribution/Types/Mixin.hs @@ -18,7 +18,7 @@ import Distribution.Types.LibraryName import Distribution.Types.PackageName import Distribution.Types.UnqualComponentName -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP -- | @@ -57,7 +57,7 @@ instance Pretty Mixin where -- -- >>> map (`simpleParsec'` "mylib:sub") [CabalSpecV3_0, CabalSpecV3_4] :: [Maybe Mixin] -- [Nothing,Just (Mixin {mixinPackageName = PackageName "mylib", mixinLibraryName = LSubLibName (UnqualComponentName "sub"), mixinIncludeRenaming = IncludeRenaming {includeProvidesRn = DefaultRenaming, includeRequiresRn = DefaultRenaming}})] -instance Parsec Mixin where +instance CabalParsec Mixin where parsec = do pn <- parsec ln <- P.option LMainLibName $ do @@ -68,7 +68,7 @@ instance Parsec Mixin where incl <- parsec return (mkMixin pn ln incl) -versionGuardMultilibs :: CabalParsing m => m () +versionGuardMultilibs :: ParsecParser () versionGuardMultilibs = do csv <- askCabalSpecVersion when (csv < CabalSpecV3_4) $ diff --git a/Cabal-syntax/src/Distribution/Types/Module.hs b/Cabal-syntax/src/Distribution/Types/Module.hs index e9febeff070..6a10befdbb4 100644 --- a/Cabal-syntax/src/Distribution/Types/Module.hs +++ b/Cabal-syntax/src/Distribution/Types/Module.hs @@ -9,9 +9,9 @@ module Distribution.Types.Module import Distribution.Compat.Prelude import Prelude () -import qualified Distribution.Compat.CharParsing as P import Distribution.ModuleName import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.Types.UnitId import qualified Text.PrettyPrint as Disp @@ -35,7 +35,7 @@ instance Pretty Module where pretty (Module uid mod_name) = pretty uid <<>> Disp.text ":" <<>> pretty mod_name -instance Parsec Module where +instance CabalParsec Module where parsec = do uid <- parsec _ <- P.char ':' diff --git a/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs b/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs index 0dae6002c3c..eca241e8ae4 100644 --- a/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs +++ b/Cabal-syntax/src/Distribution/Types/ModuleReexport.hs @@ -13,7 +13,7 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.Types.PackageName -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- ----------------------------------------------------------------------------- @@ -38,7 +38,7 @@ instance Pretty ModuleReexport where then Disp.empty else Disp.text "as" <+> pretty newname -instance Parsec ModuleReexport where +instance CabalParsec ModuleReexport where parsec = do mpkgname <- P.optional (P.try $ parsec <* P.char ':') origname <- parsec diff --git a/Cabal-syntax/src/Distribution/Types/ModuleRenaming.hs b/Cabal-syntax/src/Distribution/Types/ModuleRenaming.hs index 022a321a055..26913029d36 100644 --- a/Cabal-syntax/src/Distribution/Types/ModuleRenaming.hs +++ b/Cabal-syntax/src/Distribution/Types/ModuleRenaming.hs @@ -19,7 +19,7 @@ import Distribution.Pretty import qualified Data.Map as Map import qualified Data.Set as Set -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import Text.PrettyPrint (comma, hsep, parens, punctuate, text) -- | Renaming applied to the modules provided by a package. @@ -83,7 +83,7 @@ instance Pretty ModuleRenaming where | orig == new = pretty orig | otherwise = pretty orig <+> text "as" <+> pretty new -instance Parsec ModuleRenaming where +instance CabalParsec ModuleRenaming where parsec = do csv <- askCabalSpecVersion if csv >= CabalSpecV3_0 @@ -102,12 +102,11 @@ instance Parsec ModuleRenaming where P.space *> fail "space after parenthesis, use cabal-version: 3.0 or higher" moduleRenamingParsec - :: CabalParsing m - => (forall a. m a -> m a) + :: (forall a. ParsecParser a -> ParsecParser a) -- ^ between parens - -> m ModuleName + -> ParsecParser ModuleName -- ^ module name parser - -> m ModuleRenaming + -> ParsecParser ModuleRenaming moduleRenamingParsec bp mn = -- NB: try not necessary as the first token is obvious P.choice [parseRename, parseHiding, return DefaultRenaming] diff --git a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs index f1e0904586d..f04b0080341 100644 --- a/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/MungedPackageId.hs @@ -64,7 +64,7 @@ instance Pretty MungedPackageId where -- -- >>> simpleParsec "foo-bar.4-2" :: Maybe MungedPackageId -- Nothing -instance Parsec MungedPackageId where +instance CabalParsec MungedPackageId where parsec = do PackageIdentifier pn v <- parsec return $ MungedPackageId (decodeCompatPackageName pn) v diff --git a/Cabal-syntax/src/Distribution/Types/MungedPackageName.hs b/Cabal-syntax/src/Distribution/Types/MungedPackageName.hs index 78b648993d4..841c864f03d 100644 --- a/Cabal-syntax/src/Distribution/Types/MungedPackageName.hs +++ b/Cabal-syntax/src/Distribution/Types/MungedPackageName.hs @@ -16,7 +16,7 @@ import Distribution.Types.LibraryName import Distribution.Types.PackageName import Distribution.Types.UnqualComponentName -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | A combination of a package and component name used in various legacy @@ -87,7 +87,7 @@ instance Pretty MungedPackageName where -- -- >>> simpleParsec "z-servant-zz" :: Maybe MungedPackageName -- Just (MungedPackageName (PackageName "z-servant-zz") LMainLibName) -instance Parsec MungedPackageName where +instance CabalParsec MungedPackageName where parsec = decodeCompatPackageName' <$> parsecUnqualComponentName ------------------------------------------------------------------------------- @@ -136,7 +136,7 @@ zdashcode s = go s (Nothing :: Maybe Int) [] go ('z' : z) (Just n) r = go z (Just (n + 1)) ('z' : r) go (c : z) _ r = go z Nothing (c : r) -parseZDashCode :: CabalParsing m => m [String] +parseZDashCode :: ParsecParser [String] parseZDashCode = do ns <- toList <$> P.sepByNonEmpty (some (P.satisfy (/= '-'))) (P.char '-') return (go ns) diff --git a/Cabal-syntax/src/Distribution/Types/PackageId.hs b/Cabal-syntax/src/Distribution/Types/PackageId.hs index b5c4764ad22..b2d39ca8056 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageId.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageId.hs @@ -9,13 +9,13 @@ module Distribution.Types.PackageId import Distribution.Compat.Prelude import Prelude () -import Distribution.Parsec (Parsec (..), simpleParsec) +import Distribution.Parsec (CabalParsec (..), simpleParsec) import Distribution.Pretty import Distribution.Types.PackageName import Distribution.Version (Version, nullVersion) import qualified Data.List.NonEmpty as NE -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | Type alias so we can use the shorter name PackageId. @@ -59,7 +59,7 @@ instance Pretty PackageIdentifier where -- -- >>> simpleParsec "1.2.3" :: Maybe PackageIdentifier -- Nothing -instance Parsec PackageIdentifier where +instance CabalParsec PackageIdentifier where parsec = do xs' <- P.sepByNonEmpty component (P.char '-') (v, xs) <- case simpleParsec (NE.last xs') of diff --git a/Cabal-syntax/src/Distribution/Types/PackageName.hs b/Cabal-syntax/src/Distribution/Types/PackageName.hs index 4cf9d1aeb59..47d72e5ddcf 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageName.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageName.hs @@ -69,7 +69,7 @@ instance Structured PackageName instance Pretty PackageName where pretty = Disp.text . unPackageName -instance Parsec PackageName where +instance CabalParsec PackageName where parsec = mkPackageName <$> parsecUnqualComponentName instance NFData PackageName where diff --git a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs index 9c328378d07..48036ae02e9 100644 --- a/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs +++ b/Cabal-syntax/src/Distribution/Types/PackageVersionConstraint.hs @@ -18,7 +18,7 @@ import Distribution.Types.Version import Distribution.Types.VersionRange.Internal import Distribution.Version (simplifyVersionRange) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P -- | A version constraint on a package. Different from 'ExeDependency' and -- 'Dependency' since it does not specify the need for a component, not even @@ -51,7 +51,7 @@ instance Pretty PackageVersionConstraint where -- -- >>> simpleParsec "foo-2.0" :: Maybe PackageVersionConstraint -- Just (PackageVersionConstraint (PackageName "foo") (ThisVersion (mkVersion [2,0]))) -instance Parsec PackageVersionConstraint where +instance CabalParsec PackageVersionConstraint where parsec = do PackageIdentifier name ver <- parsec if ver == nullVersion diff --git a/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs b/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs index 695d3a3a184..bce46ccd61a 100644 --- a/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs +++ b/Cabal-syntax/src/Distribution/Types/PkgconfigDependency.hs @@ -14,7 +14,7 @@ import Distribution.Types.PkgconfigVersionRange import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P -- | Describes a dependency on a pkg-config library -- @@ -33,7 +33,7 @@ instance Pretty PkgconfigDependency where pretty (PkgconfigDependency name PcAnyVersion) = pretty name pretty (PkgconfigDependency name ver) = pretty name <+> pretty ver -instance Parsec PkgconfigDependency where +instance CabalParsec PkgconfigDependency where parsec = do name <- parsec P.spaces diff --git a/Cabal-syntax/src/Distribution/Types/PkgconfigName.hs b/Cabal-syntax/src/Distribution/Types/PkgconfigName.hs index c3a93dd27c1..d5d7bd42682 100644 --- a/Cabal-syntax/src/Distribution/Types/PkgconfigName.hs +++ b/Cabal-syntax/src/Distribution/Types/PkgconfigName.hs @@ -15,7 +15,7 @@ import Prelude () import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | A pkg-config library name @@ -58,7 +58,7 @@ instance Structured PkgconfigName instance Pretty PkgconfigName where pretty = Disp.text . unPkgconfigName -instance Parsec PkgconfigName where +instance CabalParsec PkgconfigName where parsec = mkPkgconfigName <$> P.munch1 isNameChar where -- https://gitlab.haskell.org/ghc/ghc/issues/17752 diff --git a/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs b/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs index dc328c44dda..a99325017a3 100644 --- a/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs +++ b/Cabal-syntax/src/Distribution/Types/PkgconfigVersion.hs @@ -16,7 +16,7 @@ import Distribution.Utils.Generic (isAsciiAlphaNum) import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP -- | @pkg-config@ versions. @@ -48,7 +48,7 @@ instance Pretty PkgconfigVersion where -- -- >>> simpleParsec "0.3.5+ds" :: Maybe PkgconfigVersion -- Nothing -instance Parsec PkgconfigVersion where +instance CabalParsec PkgconfigVersion where parsec = PkgconfigVersion . BS8.pack <$> P.munch1 predicate where predicate c = isAsciiAlphaNum c || c == '.' || c == '-' diff --git a/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs b/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs index fe74f70c7be..7a4471732e0 100644 --- a/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs +++ b/Cabal-syntax/src/Distribution/Types/PkgconfigVersionRange.hs @@ -24,7 +24,7 @@ import Distribution.Types.VersionInterval import Distribution.Types.VersionRange import qualified Data.ByteString.Char8 as BS8 -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP -- | @since 3.0 @@ -63,7 +63,7 @@ instance Pretty PkgconfigVersionRange where parens True = PP.parens parens False = id -instance Parsec PkgconfigVersionRange where +instance CabalParsec PkgconfigVersionRange where -- note: the wildcard is used in some places, e.g -- http://hackage.haskell.org/package/bindings-libzip-0.10.1/bindings-libzip.cabal -- @@ -77,7 +77,7 @@ instance Parsec PkgconfigVersionRange where else versionRangeToPkgconfigVersionRange <$> versionRangeParser P.integral csv -- "modern" parser of @pkg-config@ package versions. -pkgconfigParser :: CabalParsing m => m PkgconfigVersionRange +pkgconfigParser :: ParsecParser PkgconfigVersionRange pkgconfigParser = P.spaces >> expr where -- every parser here eats trailing space diff --git a/Cabal-syntax/src/Distribution/Types/SourceRepo.hs b/Cabal-syntax/src/Distribution/Types/SourceRepo.hs index 16a0fc60e0e..4ea3eb44555 100644 --- a/Cabal-syntax/src/Distribution/Types/SourceRepo.hs +++ b/Cabal-syntax/src/Distribution/Types/SourceRepo.hs @@ -21,7 +21,7 @@ import Distribution.Parsec import Distribution.Pretty import qualified Data.Map.Strict as M -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- ------------------------------------------------------------ @@ -132,7 +132,7 @@ instance Binary KnownRepoType instance Structured KnownRepoType instance NFData KnownRepoType where rnf = genericRnf -instance Parsec KnownRepoType where +instance CabalParsec KnownRepoType where parsec = do str <- P.munch1 isIdent maybe @@ -166,7 +166,7 @@ instance Pretty RepoKind where pretty RepoThis = Disp.text "this" pretty (RepoKindUnknown other) = Disp.text other -instance Parsec RepoKind where +instance CabalParsec RepoKind where parsec = classifyRepoKind <$> P.munch1 isIdent classifyRepoKind :: String -> RepoKind @@ -175,7 +175,7 @@ classifyRepoKind name = case lowercase name of "this" -> RepoThis _ -> RepoKindUnknown name -instance Parsec RepoType where +instance CabalParsec RepoType where parsec = classifyRepoType <$> P.munch1 isIdent instance Pretty RepoType where diff --git a/Cabal-syntax/src/Distribution/Types/TestType.hs b/Cabal-syntax/src/Distribution/Types/TestType.hs index 6ac0866d6f1..7659cb88460 100644 --- a/Cabal-syntax/src/Distribution/Types/TestType.hs +++ b/Cabal-syntax/src/Distribution/Types/TestType.hs @@ -13,7 +13,7 @@ import Distribution.Compat.Prelude import Distribution.Version import Prelude () -import Distribution.Parsec +import Distribution.Parsec hiding (char) import Distribution.Pretty import Text.PrettyPrint (char, text) @@ -49,7 +49,7 @@ instance Pretty TestType where pretty (TestTypeLib ver) = text "detailed-" <<>> pretty ver pretty (TestTypeUnknown name ver) = text name <<>> char '-' <<>> pretty ver -instance Parsec TestType where +instance CabalParsec TestType where parsec = parsecStandard $ \ver name -> case name of "exitcode-stdio" -> TestTypeExe ver "detailed" -> TestTypeLib ver diff --git a/Cabal-syntax/src/Distribution/Types/UnitId.hs b/Cabal-syntax/src/Distribution/Types/UnitId.hs index 36a1d003b2e..4c0901987a9 100644 --- a/Cabal-syntax/src/Distribution/Types/UnitId.hs +++ b/Cabal-syntax/src/Distribution/Types/UnitId.hs @@ -19,8 +19,8 @@ import Distribution.Compat.Prelude import Distribution.Utils.ShortText import Prelude () -import qualified Distribution.Compat.CharParsing as P import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.Types.ComponentId import Distribution.Types.PackageId @@ -76,7 +76,7 @@ instance Pretty UnitId where -- | The textual format for 'UnitId' coincides with the format -- GHC accepts for @-package-id@. -instance Parsec UnitId where +instance CabalParsec UnitId where parsec = mkUnitId <$> P.munch1 isUnitChar where -- https://gitlab.haskell.org/ghc/ghc/issues/17752 @@ -124,7 +124,7 @@ instance Structured DefUnitId -- Workaround for a GHC 8.0.1 bug, see -- https://github.com/haskell/cabal/issues/4793#issuecomment-334258288 -instance Parsec DefUnitId where +instance CabalParsec DefUnitId where parsec = DefUnitId <$> parsec -- | Unsafely create a 'DefUnitId' from a 'UnitId'. Your responsibility diff --git a/Cabal-syntax/src/Distribution/Types/UnqualComponentName.hs b/Cabal-syntax/src/Distribution/Types/UnqualComponentName.hs index 3879cdd2169..f0fb3b9c89b 100644 --- a/Cabal-syntax/src/Distribution/Types/UnqualComponentName.hs +++ b/Cabal-syntax/src/Distribution/Types/UnqualComponentName.hs @@ -72,7 +72,7 @@ instance Structured UnqualComponentName instance Pretty UnqualComponentName where pretty = showToken . unUnqualComponentName -instance Parsec UnqualComponentName where +instance CabalParsec UnqualComponentName where parsec = mkUnqualComponentName <$> parsecUnqualComponentName instance NFData UnqualComponentName where diff --git a/Cabal-syntax/src/Distribution/Types/Version.hs b/Cabal-syntax/src/Distribution/Types/Version.hs index 90ad33b1048..40b6557b51a 100644 --- a/Cabal-syntax/src/Distribution/Types/Version.hs +++ b/Cabal-syntax/src/Distribution/Types/Version.hs @@ -24,7 +24,7 @@ import Distribution.Parsec import Distribution.Pretty import qualified Data.Version as Base -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp import qualified Text.Read as Read @@ -98,7 +98,7 @@ instance Pretty Version where (map Disp.int $ versionNumbers ver) ) -instance Parsec Version where +instance CabalParsec Version where parsec = mkVersion <$> toList <$> P.sepByNonEmpty versionDigitParser (P.char '.') <* tags where tags = do @@ -110,10 +110,10 @@ instance Parsec Version where -- | An integral without leading zeroes. -- -- @since 3.0 -versionDigitParser :: CabalParsing m => m Int +versionDigitParser :: ParsecParser Int versionDigitParser = (some d >>= toNumber) P. "version digit (integral without leading zeroes)" where - toNumber :: CabalParsing m => [Int] -> m Int + toNumber :: [Int] -> ParsecParser Int toNumber [0] = return 0 toNumber (0 : _) = P.unexpected "Version digit with leading zero" toNumber xs @@ -124,7 +124,7 @@ versionDigitParser = (some d >>= toNumber) P. "version digit (integral withou | length xs > 9 = P.unexpected "At most 9 numbers are allowed per version number part" | otherwise = return $ foldl' (\a b -> a * 10 + b) 0 xs - d :: P.CharParsing m => m Int + d :: ParsecParser Int d = f <$> P.satisfyRange '0' '9' f c = ord c - ord '0' diff --git a/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs b/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs index 7d7101d8660..3a6b06f3395 100644 --- a/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs +++ b/Cabal-syntax/src/Distribution/Types/VersionRange/Internal.hs @@ -45,8 +45,8 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.Utils.Generic (unsnoc) -import qualified Distribution.Compat.CharParsing as P import qualified Distribution.Compat.DList as DList +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp data VersionRange @@ -331,7 +331,7 @@ prettyVersionRange16 vr = prettyVersionRange vr -- -- >>> map (`simpleParsecW'` "== 1.2.*") [CabalSpecV1_4, CabalSpecV1_6] :: [Maybe VersionRange] -- [Nothing,Just (IntersectVersionRanges (OrLaterVersion (mkVersion [1,2])) (EarlierVersion (mkVersion [1,3])))] -instance Parsec VersionRange where +instance CabalParsec VersionRange where parsec = askCabalSpecVersion >>= versionRangeParser versionDigitParser -- | 'VersionRange' parser parametrised by version digit parser. @@ -341,7 +341,7 @@ instance Parsec VersionRange where -- versions, 'PkgConfigVersionRange'. -- -- @since 3.0 -versionRangeParser :: forall m. CabalParsing m => m Int -> CabalSpecVersion -> m VersionRange +versionRangeParser :: ParsecParser Int -> CabalSpecVersion -> ParsecParser VersionRange versionRangeParser digitParser csv = expr where expr = do @@ -489,7 +489,7 @@ versionRangeParser digitParser csv = expr , prettyShow (foldr1 unionVersionRanges (fmap op vs)) ] - verSet :: CabalParsing m => m (NonEmpty Version) + verSet :: ParsecParser (NonEmpty Version) verSet = do _ <- P.char '{' P.spaces @@ -498,27 +498,27 @@ versionRangeParser digitParser csv = expr pure vs -- a plain version without tags or wildcards - verPlain :: CabalParsing m => m Version + verPlain :: ParsecParser Version verPlain = mkVersion <$> toList <$> P.sepByNonEmpty digitParser (P.char '.') -- either wildcard or normal version - verOrWild :: CabalParsing m => m (Bool, Version) + verOrWild :: ParsecParser (Bool, Version) verOrWild = do x <- digitParser verLoop (DList.singleton x) -- trailing: wildcard (.y.*) or normal version (optional tags) (.y.z-tag) - verLoop :: CabalParsing m => DList.DList Int -> m (Bool, Version) + verLoop :: DList.DList Int -> ParsecParser (Bool, Version) verLoop acc = verLoop' acc <|> (tags *> pure (False, mkVersion (DList.toList acc))) - verLoop' :: CabalParsing m => DList.DList Int -> m (Bool, Version) + verLoop' :: DList.DList Int -> ParsecParser (Bool, Version) verLoop' acc = do _ <- P.char '.' - let digit = digitParser >>= verLoop . DList.snoc acc + let dig = digitParser >>= verLoop . DList.snoc acc let wild = (True, mkVersion (DList.toList acc)) <$ P.char '*' - digit <|> wild + dig <|> wild parens p = P.between ((P.char '(' P. "opening paren") >> P.spaces) @@ -528,7 +528,7 @@ versionRangeParser digitParser csv = expr P.spaces return a - tags :: CabalParsing m => m () + tags :: ParsecParser () tags = do ts <- many $ P.char '-' *> some (P.satisfy isAlphaNum) case ts of diff --git a/Cabal-syntax/src/Distribution/Utils/Path.hs b/Cabal-syntax/src/Distribution/Utils/Path.hs index 765b0ac6143..c9e570d622c 100644 --- a/Cabal-syntax/src/Distribution/Utils/Path.hs +++ b/Cabal-syntax/src/Distribution/Utils/Path.hs @@ -78,7 +78,7 @@ import Distribution.Parsec import Distribution.Pretty import Distribution.Utils.Generic (isAbsoluteOnAnyPlatform) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified System.Directory as Directory import qualified System.FilePath as FilePath @@ -360,7 +360,7 @@ tryMakeRelativeToWorkingDir mbWorkDir (SymbolicPath fp) = do ------------------------------------------------------------------------------- -instance Parsec (SymbolicPathX 'OnlyRelative from to) where +instance CabalParsec (SymbolicPathX 'OnlyRelative from to) where parsec = do token <- parsecToken if null token @@ -370,7 +370,7 @@ instance Parsec (SymbolicPathX 'OnlyRelative from to) where then P.unexpected "absolute FilePath" else return (SymbolicPath token) -instance Parsec (SymbolicPathX 'AllowAbsolute from to) where +instance CabalParsec (SymbolicPathX 'AllowAbsolute from to) where parsec = do token <- parsecToken if null token diff --git a/Cabal-syntax/src/Language/Haskell/Extension.hs b/Cabal-syntax/src/Language/Haskell/Extension.hs index 22082d6d0b3..2ad77aa61d3 100644 --- a/Cabal-syntax/src/Language/Haskell/Extension.hs +++ b/Cabal-syntax/src/Language/Haskell/Extension.hs @@ -31,7 +31,7 @@ import Data.Array (Array, Ix (inRange), accumArray, bounds, (!)) import Distribution.Parsec import Distribution.Pretty -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- ------------------------------------------------------------ @@ -74,7 +74,7 @@ instance Pretty Language where pretty (UnknownLanguage other) = Disp.text other pretty other = Disp.text (show other) -instance Parsec Language where +instance CabalParsec Language where parsec = classifyLanguage <$> P.munch1 isAlphaNum classifyLanguage :: String -> Language @@ -578,23 +578,23 @@ instance Pretty Extension where pretty (EnableExtension ke) = Disp.text (show ke) pretty (DisableExtension ke) = Disp.text ("No" ++ show ke) -instance Parsec Extension where +instance CabalParsec Extension where parsec = classifyExtension <$> P.munch1 isAlphaNum instance Pretty KnownExtension where pretty ke = Disp.text (show ke) classifyExtension :: String -> Extension -classifyExtension string = - case classifyKnownExtension string of +classifyExtension str = + case classifyKnownExtension str of Just ext -> EnableExtension ext Nothing -> - case string of - 'N' : 'o' : string' -> - case classifyKnownExtension string' of + case str of + 'N' : 'o' : str' -> + case classifyKnownExtension str' of Just ext -> DisableExtension ext - Nothing -> UnknownExtension string - _ -> UnknownExtension string + Nothing -> UnknownExtension str + _ -> UnknownExtension str -- | 'read' for 'KnownExtension's is really really slow so for the Text -- instance @@ -607,9 +607,9 @@ classifyExtension string = -- also allow us to do case insensitive matches in future if we prefer. classifyKnownExtension :: String -> Maybe KnownExtension classifyKnownExtension "" = Nothing -classifyKnownExtension string@(c : _) +classifyKnownExtension str@(c : _) | inRange (bounds knownExtensionTable) c = - lookup string (knownExtensionTable ! c) + lookup str (knownExtensionTable ! c) | otherwise = Nothing knownExtensionTable :: Array Char [(String, KnownExtension)] diff --git a/Cabal-tests/tests/UnitTests/Distribution/System.hs b/Cabal-tests/tests/UnitTests/Distribution/System.hs index d09b1b7f61b..97ed073a123 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/System.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/System.hs @@ -11,7 +11,7 @@ import Test.Tasty.QuickCheck (testProperty) import Test.QuickCheck (Property, (===)) import Test.QuickCheck.Instances.Cabal () -textRoundtrip :: (Show a, Eq a, Pretty a, Parsec a) => a -> Property +textRoundtrip :: (Show a, Eq a, Pretty a, CabalParsec a) => a -> Property textRoundtrip x = simpleParsec (prettyShow x) === Just x tests :: [TestTree] diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index e6a978234c2..5c181d5dd2c 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -177,7 +177,6 @@ library Distribution.Backpack, Distribution.CabalSpecVersion, Distribution.Compat.Binary, - Distribution.Compat.CharParsing, Distribution.Compat.DList, Distribution.Compat.Exception, Distribution.Compat.Graph, @@ -185,7 +184,6 @@ library Distribution.Compat.MonadFail, Distribution.Compat.Newtype, Distribution.Compat.NonEmptySet, - Distribution.Compat.Parsing, Distribution.Compat.Prelude, Distribution.Compat.Semigroup, Distribution.Compat.Typeable, diff --git a/Cabal/src/Distribution/Simple/BuildTarget.hs b/Cabal/src/Distribution/Simple/BuildTarget.hs index cb5293b18b3..430fbae1497 100644 --- a/Cabal/src/Distribution/Simple/BuildTarget.hs +++ b/Cabal/src/Distribution/Simple/BuildTarget.hs @@ -50,11 +50,11 @@ import Distribution.Types.LocalBuildInfo import Distribution.Types.TargetInfo import Distribution.Types.UnqualComponentName -import qualified Distribution.Compat.CharParsing as P import Distribution.ModuleName import Distribution.Package import Distribution.PackageDescription import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.Simple.Errors import Distribution.Simple.LocalBuildInfo @@ -218,7 +218,7 @@ readUserBuildTarget targetstr = Left _ -> Left (UserBuildTargetUnrecognised targetstr) Right tgt -> Right tgt where - parseTargetApprox :: CabalParsing m => m UserBuildTarget + parseTargetApprox :: ParsecParser UserBuildTarget parseTargetApprox = do -- read one, two, or three tokens, where last could be "hs-string" ts <- tokens @@ -227,17 +227,17 @@ readUserBuildTarget targetstr = (a, Just (b, Nothing)) -> UserBuildTargetDouble a b (a, Just (b, Just c)) -> UserBuildTargetTriple a b c - tokens :: CabalParsing m => m (String, Maybe (String, Maybe String)) + tokens :: ParsecParser (String, Maybe (String, Maybe String)) tokens = (\s -> (s, Nothing)) <$> parsecHaskellString <|> (,) <$> token <*> P.optional (P.char ':' *> tokens2) - tokens2 :: CabalParsing m => m (String, Maybe String) + tokens2 :: ParsecParser (String, Maybe String) tokens2 = (\s -> (s, Nothing)) <$> parsecHaskellString <|> (,) <$> token <*> P.optional (P.char ':' *> (parsecHaskellString <|> token)) - token :: CabalParsing m => m String + token :: ParsecParser String token = P.munch1 (\x -> not (isSpace x) && x /= ':') data UserBuildTargetProblem diff --git a/Cabal/src/Distribution/Simple/FileMonitor/Types.hs b/Cabal/src/Distribution/Simple/FileMonitor/Types.hs index 17ca3198882..3197c8658ed 100644 --- a/Cabal/src/Distribution/Simple/FileMonitor/Types.hs +++ b/Cabal/src/Distribution/Simple/FileMonitor/Types.hs @@ -36,8 +36,8 @@ import Distribution.Simple.Glob.Internal ( Glob (..) ) -import qualified Distribution.Compat.CharParsing as P import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import qualified Text.PrettyPrint as Disp @@ -193,7 +193,7 @@ monitorFileHashedSearchPath notFoundAtPaths foundAtPath = instance Pretty RootedGlob where pretty (RootedGlob root pathglob) = pretty root Disp.<> pretty pathglob -instance Parsec RootedGlob where +instance CabalParsec RootedGlob where parsec = do root <- parsec case root of @@ -205,7 +205,7 @@ instance Pretty FilePathRoot where pretty (FilePathRoot root) = Disp.text root pretty FilePathHomeDir = Disp.char '~' Disp.<> Disp.char '/' -instance Parsec FilePathRoot where +instance CabalParsec FilePathRoot where parsec = root <|> P.try home <|> P.try drive <|> pure FilePathRelative where root = FilePathRoot "/" <$ P.char '/' diff --git a/Cabal/src/Distribution/Simple/Glob/Internal.hs b/Cabal/src/Distribution/Simple/Glob/Internal.hs index 13661cf97d5..8c15a5d3e27 100644 --- a/Cabal/src/Distribution/Simple/Glob/Internal.hs +++ b/Cabal/src/Distribution/Simple/Glob/Internal.hs @@ -20,8 +20,8 @@ module Distribution.Simple.Glob.Internal where import Distribution.Compat.Prelude import Prelude () -import qualified Distribution.Compat.CharParsing as P import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import qualified Text.PrettyPrint as Disp @@ -73,17 +73,17 @@ instance Pretty Glob where pretty (GlobFile glob) = dispGlobPieces glob pretty GlobDirTrailing = Disp.empty -instance Parsec Glob where +instance CabalParsec Glob where parsec = parsecPath where - parsecPath :: CabalParsing m => m Glob + parsecPath :: ParsecParser Glob parsecPath = do glob <- parsecGlob dirSep *> (GlobDir glob <$> parsecPath <|> pure (GlobDir glob GlobDirTrailing)) <|> pure (GlobFile glob) -- We could support parsing recursive directory search syntax -- @**@ here too, rather than just in 'parseFileGlob' - dirSep :: CabalParsing m => m () + dirSep :: ParsecParser () dirSep = () <$ P.char '/' <|> P.try @@ -93,7 +93,7 @@ instance Parsec Glob where P.notFollowedBy (P.satisfy isGlobEscapedChar) ) - parsecGlob :: CabalParsing m => m GlobPieces + parsecGlob :: ParsecParser GlobPieces parsecGlob = some parsecPiece where parsecPiece = P.choice [literal, wildcard, union] diff --git a/Cabal/src/Distribution/Simple/Setup/Config.hs b/Cabal/src/Distribution/Simple/Setup/Config.hs index 14e76c7d769..c24ff0bfcdf 100644 --- a/Cabal/src/Distribution/Simple/Setup/Config.hs +++ b/Cabal/src/Distribution/Simple/Setup/Config.hs @@ -46,13 +46,13 @@ module Distribution.Simple.Setup.Config import Distribution.Compat.Prelude hiding (get) import Prelude () -import qualified Distribution.Compat.CharParsing as P import Distribution.Compat.Semigroup (Last' (..), Option' (..)) import Distribution.Compat.Stack import Distribution.Compiler import Distribution.ModuleName import Distribution.PackageDescription -import Distribution.Parsec +import Distribution.Parsec hiding (option) +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.ReadE import Distribution.Simple.Command hiding (boolOpt, boolOpt') diff --git a/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/Cabal/src/Distribution/Simple/Setup/Haddock.hs index 402544ce511..cecea5caf31 100644 --- a/Cabal/src/Distribution/Simple/Setup/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Setup/Haddock.hs @@ -46,8 +46,7 @@ module Distribution.Simple.Setup.Haddock import Distribution.Compat.Prelude hiding (get) import Prelude () -import qualified Distribution.Compat.CharParsing as P -import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.Simple.Command hiding (boolOpt, boolOpt') import Distribution.Simple.Flag @@ -85,7 +84,7 @@ instance Pretty HaddockTarget where pretty ForHackage = Disp.text "for-hackage" pretty ForDevelopment = Disp.text "for-development" -instance Parsec HaddockTarget where +instance P.CabalParsec HaddockTarget where parsec = P.choice [ P.try $ P.string "for-hackage" >> return ForHackage diff --git a/Cabal/src/Distribution/Simple/Setup/Test.hs b/Cabal/src/Distribution/Simple/Setup/Test.hs index e4c2706eed6..0564c4a742c 100644 --- a/Cabal/src/Distribution/Simple/Setup/Test.hs +++ b/Cabal/src/Distribution/Simple/Setup/Test.hs @@ -40,8 +40,7 @@ module Distribution.Simple.Setup.Test import Distribution.Compat.Prelude hiding (get) import Prelude () -import qualified Distribution.Compat.CharParsing as P -import Distribution.Parsec +import qualified Distribution.Parsec as P import Distribution.Pretty import Distribution.ReadE import Distribution.Simple.Command hiding (boolOpt, boolOpt') @@ -72,7 +71,7 @@ knownTestShowDetails = [minBound .. maxBound] instance Pretty TestShowDetails where pretty = Disp.text . lowercase . show -instance Parsec TestShowDetails where +instance P.CabalParsec TestShowDetails where parsec = maybe (fail "invalid TestShowDetails") return . classify =<< ident where ident = P.munch1 (\c -> isAlpha c || c == '_' || c == '-') @@ -216,7 +215,7 @@ testOptions' showOrParseArgs = ", " (map prettyShow knownTestShowDetails) ) - (fmap toFlag parsec) + (fmap toFlag P.parsec) ) (flagToList . fmap prettyShow) ) diff --git a/Cabal/src/Distribution/Verbosity.hs b/Cabal/src/Distribution/Verbosity.hs index bab48bbed21..b6dfe0694e6 100644 --- a/Cabal/src/Distribution/Verbosity.hs +++ b/Cabal/src/Distribution/Verbosity.hs @@ -84,7 +84,7 @@ import Distribution.Utils.Generic (isAsciiAlpha) import Distribution.Verbosity.Internal import qualified Data.Set as Set -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP data Verbosity = Verbosity @@ -193,13 +193,13 @@ intToVerbosity _ = Nothing -- Right (Verbosity {vLevel = Deafening, vFlags = fromList [VCallStack,VCallSite,VNoWrap,VStderr], vQuiet = False}) -- -- /Note:/ this parser will eat trailing spaces. -instance Parsec Verbosity where +instance CabalParsec Verbosity where parsec = parsecVerbosity instance Pretty Verbosity where pretty = PP.text . showForCabal -parsecVerbosity :: CabalParsing m => m Verbosity +parsecVerbosity :: ParsecParser Verbosity parsecVerbosity = parseIntVerbosity <|> parseStringVerbosity where parseIntVerbosity = do diff --git a/cabal-install-solver/src/Distribution/Solver/Types/Settings.hs b/cabal-install-solver/src/Distribution/Solver/Types/Settings.hs index 4b7fe65b769..a10eec4a74f 100644 --- a/cabal-install-solver/src/Distribution/Solver/Types/Settings.hs +++ b/cabal-install-solver/src/Distribution/Solver/Types/Settings.hs @@ -21,9 +21,9 @@ import Prelude () import Distribution.Simple.Setup ( BooleanFlag(..) ) import Distribution.Pretty ( Pretty(pretty) ) -import Distribution.Parsec ( Parsec(parsec) ) +import Distribution.Parsec ( CabalParsec(parsec) ) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP newtype ReorderGoals = ReorderGoals Bool @@ -99,7 +99,7 @@ instance Pretty OnlyConstrained where pretty OnlyConstrainedAll = PP.text "all" pretty OnlyConstrainedNone = PP.text "none" -instance Parsec OnlyConstrained where +instance CabalParsec OnlyConstrained where parsec = P.choice [ P.string "all" >> return OnlyConstrainedAll , P.string "none" >> return OnlyConstrainedNone diff --git a/cabal-install/src/Distribution/Client/BuildReports/Types.hs b/cabal-install/src/Distribution/Client/BuildReports/Types.hs index 576d058c4bf..cb38ff1cc15 100644 --- a/cabal-install/src/Distribution/Client/BuildReports/Types.hs +++ b/cabal-install/src/Distribution/Client/BuildReports/Types.hs @@ -23,7 +23,7 @@ module Distribution.Client.BuildReports.Types import Distribution.Client.Compat.Prelude import Prelude () -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp import Distribution.Compiler (CompilerId (..)) @@ -46,7 +46,7 @@ instance Pretty ReportLevel where pretty AnonymousReports = Disp.text "anonymous" pretty DetailedReports = Disp.text "detailed" -instance Parsec ReportLevel where +instance CabalParsec ReportLevel where parsec = do name <- P.munch1 isAlpha case lowercase name of @@ -120,7 +120,7 @@ instance Pretty InstallOutcome where pretty InstallFailed = Disp.text "InstallFailed" pretty InstallOk = Disp.text "InstallOk" -instance Parsec InstallOutcome where +instance CabalParsec InstallOutcome where parsec = do name <- P.munch1 isAlpha case name of @@ -148,7 +148,7 @@ instance Pretty Outcome where pretty Failed = Disp.text "Failed" pretty Ok = Disp.text "Ok" -instance Parsec Outcome where +instance CabalParsec Outcome where parsec = do name <- P.munch1 isAlpha case name of diff --git a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs index d5bbd5309f7..c5bfa84b8eb 100644 --- a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs +++ b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallFlags.hs @@ -11,6 +11,7 @@ module Distribution.Client.CmdInstall.ClientInstallFlags import Distribution.Client.Compat.Prelude import Prelude () +import Distribution.Parsec (ParsecParser) import Distribution.ReadE ( parsecToReadE , succeedReadE @@ -35,7 +36,7 @@ import Distribution.Client.Types.OverwritePolicy ( OverwritePolicy (..) ) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P data ClientInstallFlags = ClientInstallFlags { cinstInstallLibs :: Flag Bool @@ -113,7 +114,7 @@ clientInstallOptions _ = $ reqArg "DIR" (succeedReadE Flag) flagToList ] -parsecInstallMethod :: CabalParsing m => m InstallMethod +parsecInstallMethod :: ParsecParser InstallMethod parsecInstallMethod = do name <- P.munch1 isAlpha case name of diff --git a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallTargetSelector.hs b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallTargetSelector.hs index 7879602a913..23128f97d34 100644 --- a/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallTargetSelector.hs +++ b/cabal-install/src/Distribution/Client/CmdInstall/ClientInstallTargetSelector.hs @@ -14,8 +14,8 @@ import Network.URI (URI, parseURI) import Distribution.Client.Errors import Distribution.Client.TargetSelector import Distribution.Client.Types -import Distribution.Compat.CharParsing (char, optional) import Distribution.Package +import Distribution.Parsec (ParsecParser, char, optional) import Distribution.Simple.LocalBuildInfo (ComponentName (CExeName)) import Distribution.Simple.Utils (dieWithException) @@ -33,7 +33,7 @@ parseWithoutProjectTargetSelector verbosity input = Just uri -> return (WoURI uri) Nothing -> dieWithException verbosity $ ProjectTargetSelector input err where - parser :: CabalParsing m => m WithoutProjectTargetSelector + parser :: ParsecParser WithoutProjectTargetSelector parser = do pid <- parsec cn <- optional (char ':' *> parsec) diff --git a/cabal-install/src/Distribution/Client/CmdOutdated.hs b/cabal-install/src/Distribution/Client/CmdOutdated.hs index ed40a1a85e6..6dc625ca2fa 100644 --- a/cabal-install/src/Distribution/Client/CmdOutdated.hs +++ b/cabal-install/src/Distribution/Client/CmdOutdated.hs @@ -74,7 +74,6 @@ import Distribution.Utils.Generic ) import Distribution.Client.HttpUtils -import qualified Distribution.Compat.CharParsing as P import Distribution.Package ( PackageName , packageVersion @@ -85,6 +84,7 @@ import Distribution.PackageDescription import Distribution.PackageDescription.Configuration ( finalizePD ) +import qualified Distribution.Parsec as P import Distribution.ReadE ( parsecToReadE ) diff --git a/cabal-install/src/Distribution/Client/CmdUpdate.hs b/cabal-install/src/Distribution/Client/CmdUpdate.hs index c388ba39871..055887d173a 100644 --- a/cabal-install/src/Distribution/Client/CmdUpdate.hs +++ b/cabal-install/src/Distribution/Client/CmdUpdate.hs @@ -87,7 +87,7 @@ import Distribution.Verbosity ) import qualified Data.Maybe as Unsafe (fromJust) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp import qualified Data.ByteString.Lazy as BS @@ -152,7 +152,7 @@ data UpdateRequest = UpdateRequest instance Pretty UpdateRequest where pretty (UpdateRequest n s) = pretty n <<>> Disp.comma <<>> pretty s -instance Parsec UpdateRequest where +instance CabalParsec UpdateRequest where parsec = do name <- parsec state <- P.char ',' *> parsec <|> pure IndexStateHead diff --git a/cabal-install/src/Distribution/Client/Compat/Prelude.hs b/cabal-install/src/Distribution/Client/Compat/Prelude.hs index 42d048c9b61..37378bf9884 100644 --- a/cabal-install/src/Distribution/Client/Compat/Prelude.hs +++ b/cabal-install/src/Distribution/Client/Compat/Prelude.hs @@ -18,6 +18,6 @@ import Distribution.Client.Compat.Orphans () import Distribution.Compat.Prelude.Internal import Prelude () -import Distribution.Parsec as X (CabalParsing, Parsec (..), eitherParsec, explicitEitherParsec, simpleParsec) +import Distribution.Parsec as X (CabalParsec (..), eitherParsec, explicitEitherParsec, simpleParsec) import Distribution.Pretty as X (Pretty (..), prettyShow) import Distribution.Verbosity as X (Verbosity) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index d9b91c959d0..d76ce855932 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -125,7 +125,6 @@ import Distribution.Client.ReplFlags import Distribution.Client.Version ( cabalInstallVersion ) -import qualified Distribution.Compat.CharParsing as P import Distribution.Compat.Environment ( getEnvironment ) @@ -158,6 +157,7 @@ import qualified Distribution.Deprecated.ParseUtils as ParseUtils ( Field (..) ) import Distribution.Parsec (ParsecParser, parsecFilePath, parsecOptCommaList, parsecToken) +import qualified Distribution.Parsec as P import Distribution.Simple.Command ( CommandUI (commandOptions) , ShowOrParseArgs (..) diff --git a/cabal-install/src/Distribution/Client/Dependency/Types.hs b/cabal-install/src/Distribution/Client/Dependency/Types.hs index 78f97662008..0762ed69ea5 100644 --- a/cabal-install/src/Distribution/Client/Dependency/Types.hs +++ b/cabal-install/src/Distribution/Client/Dependency/Types.hs @@ -11,7 +11,7 @@ import Prelude () import Text.PrettyPrint (text) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P -- | All the solvers that can be selected. data PreSolver = AlwaysModular @@ -30,7 +30,7 @@ instance Structured Solver instance Pretty PreSolver where pretty AlwaysModular = text "modular" -instance Parsec PreSolver where +instance CabalParsec PreSolver where parsec = do name <- P.munch1 isAlpha case map toLower name of diff --git a/cabal-install/src/Distribution/Client/HttpUtils.hs b/cabal-install/src/Distribution/Client/HttpUtils.hs index cad511ef9f8..dd68118c1b7 100644 --- a/cabal-install/src/Distribution/Client/HttpUtils.hs +++ b/cabal-install/src/Distribution/Client/HttpUtils.hs @@ -127,7 +127,7 @@ import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy.Char8 as LBS8 import qualified Data.Char as Char import Distribution.Client.Errors -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P ------------------------------------------------------------------------------ -- Downloading a URI, given an HttpTransport diff --git a/cabal-install/src/Distribution/Client/IndexUtils/ActiveRepos.hs b/cabal-install/src/Distribution/Client/IndexUtils/ActiveRepos.hs index daa4ec86355..f8c7bb00e13 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils/ActiveRepos.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils/ActiveRepos.hs @@ -17,7 +17,7 @@ import Prelude () import Distribution.Parsec (parsecLeadingCommaNonEmpty) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- $setup @@ -71,7 +71,7 @@ instance Pretty ActiveRepos where -- -- >>> simpleParsec "hackage.haskell.org, :rest, head.hackage:override" :: Maybe ActiveRepos -- Just (ActiveRepos [ActiveRepo (RepoName {unRepoName = "hackage.haskell.org"}) CombineStrategyMerge,ActiveRepoRest CombineStrategyMerge,ActiveRepo (RepoName {unRepoName = "head.hackage"}) CombineStrategyOverride]) -instance Parsec ActiveRepos where +instance CabalParsec ActiveRepos where parsec = ActiveRepos [] <$ P.try (P.string ":none") <|> do @@ -95,7 +95,7 @@ instance Pretty ActiveRepoEntry where pretty (ActiveRepo r s) = pretty r <<>> Disp.colon <<>> pretty s -instance Parsec ActiveRepoEntry where +instance CabalParsec ActiveRepoEntry where parsec = leadColon <|> leadRepo where leadColon = do @@ -132,7 +132,7 @@ instance Pretty CombineStrategy where pretty CombineStrategyMerge = Disp.text "merge" pretty CombineStrategyOverride = Disp.text "override" -instance Parsec CombineStrategy where +instance CabalParsec CombineStrategy where parsec = P.choice [ CombineStrategySkip <$ P.string "skip" diff --git a/cabal-install/src/Distribution/Client/IndexUtils/IndexState.hs b/cabal-install/src/Distribution/Client/IndexUtils/IndexState.hs index 0e9cb6a73d3..644176ab428 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils/IndexState.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils/IndexState.hs @@ -25,7 +25,7 @@ import Distribution.Client.Types.RepoName (RepoName (..)) import Distribution.Parsec (parsecLeadingCommaNonEmpty) import qualified Data.Map.Strict as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- $setup @@ -72,7 +72,7 @@ instance Pretty TotalIndexState where -- -- >>> simpleParsec "hackage.haskell.org 2020-02-04T12:34:56Z" :: Maybe TotalIndexState -- Just (TIS IndexStateHead (fromList [(RepoName {unRepoName = "hackage.haskell.org"},IndexStateTime (TS 1580819696))])) -instance Parsec TotalIndexState where +instance CabalParsec TotalIndexState where parsec = normalise . foldl' add headTotalIndexState <$> parsecLeadingCommaNonEmpty single0 where single0 = startsWithRepoName <|> TokTimestamp <$> parsec @@ -138,7 +138,7 @@ instance Pretty RepoIndexState where pretty IndexStateHead = Disp.text "HEAD" pretty (IndexStateTime ts) = pretty ts -instance Parsec RepoIndexState where +instance CabalParsec RepoIndexState where parsec = parseHead <|> parseTime where parseHead = IndexStateHead <$ P.string "HEAD" diff --git a/cabal-install/src/Distribution/Client/IndexUtils/Timestamp.hs b/cabal-install/src/Distribution/Client/IndexUtils/Timestamp.hs index 10034472277..1fce0e91dee 100644 --- a/cabal-install/src/Distribution/Client/IndexUtils/Timestamp.hs +++ b/cabal-install/src/Distribution/Client/IndexUtils/Timestamp.hs @@ -28,7 +28,7 @@ import Data.Time (UTCTime (..), fromGregorianValid, makeTimeOfDayValid, showGreg import Data.Time.Clock.POSIX (posixSecondsToUTCTime, utcTimeToPOSIXSeconds) import qualified Codec.Archive.Tar.Entry as Tar -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- | UNIX timestamp (expressed in seconds since unix epoch, i.e. 1970). @@ -84,7 +84,7 @@ instance Structured Timestamp instance Pretty Timestamp where pretty = Disp.text . showTimestamp -instance Parsec Timestamp where +instance CabalParsec Timestamp where parsec = parsePosix <|> parseUTC where -- \| Parses unix timestamps, e.g. @"\@1474626019"@ diff --git a/cabal-install/src/Distribution/Client/Init/Prompt.hs b/cabal-install/src/Distribution/Client/Init/Prompt.hs index 7464a0d0145..900a02a7223 100644 --- a/cabal-install/src/Distribution/Client/Init/Prompt.hs +++ b/cabal-install/src/Distribution/Client/Init/Prompt.hs @@ -54,7 +54,7 @@ promptYesNo = -- | Create a prompt with optional default value that returns a value -- of some Text instance. -prompt :: (Interactive m, Parsec t, Pretty t) => String -> DefaultPrompt t -> m t +prompt :: (Interactive m, CabalParsec t, Pretty t) => String -> DefaultPrompt t -> m t prompt = promptDefault eitherParsec prettyShow -- | Create a prompt from a prompt string and a String representation diff --git a/cabal-install/src/Distribution/Client/Init/Utils.hs b/cabal-install/src/Distribution/Client/Init/Utils.hs index 12605a669a0..b709ee243d0 100644 --- a/cabal-install/src/Distribution/Client/Init/Utils.hs +++ b/cabal-install/src/Distribution/Client/Init/Utils.hs @@ -22,7 +22,7 @@ module Distribution.Client.Init.Utils , addLibDepToTest ) where -import Distribution.Client.Compat.Prelude hiding (Parsec, empty, many, putStrLn, readFile) +import Distribution.Client.Compat.Prelude hiding (CabalParsec, empty, many, putStrLn, readFile) import Distribution.Utils.Generic (isInfixOf, safeLast) import qualified Prelude () diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 8fea76bae3b..8608cbc3138 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -137,7 +137,6 @@ import Distribution.Client.GlobalFlags , withRepoContext ) import Distribution.Client.ManpageFlags (ManpageFlags, defaultManpageFlags, manpageOptions) -import qualified Distribution.Compat.CharParsing as P import Distribution.FieldGrammar.Newtypes (SpecVersion (..)) import Distribution.PackageDescription ( BuildType (..) @@ -147,8 +146,10 @@ import Distribution.PackageDescription ) import Distribution.PackageDescription.Check (CheckExplanationIDString) import Distribution.Parsec - ( parsecCommaList + ( ParsecParser + , parsecCommaList ) +import qualified Distribution.Parsec as P import Distribution.ReadE ( ReadE (..) , parsecToReadE @@ -1035,7 +1036,7 @@ writeGhcEnvironmentFilesPolicyPrinter = \case (Flag WriteGhcEnvironmentFilesOnlyForGhc844AndNewer) -> ["ghc8.4.4+"] NoFlag -> [] -relaxDepsParser :: CabalParsing m => m (Maybe RelaxDeps) +relaxDepsParser :: ParsecParser (Maybe RelaxDeps) relaxDepsParser = do rs <- P.sepBy parsec (P.char ',') if null rs diff --git a/cabal-install/src/Distribution/Client/TargetSelector.hs b/cabal-install/src/Distribution/Client/TargetSelector.hs index 8dabe33f22a..16725cad04b 100644 --- a/cabal-install/src/Distribution/Client/TargetSelector.hs +++ b/cabal-install/src/Distribution/Client/TargetSelector.hs @@ -2533,7 +2533,7 @@ matchInexactly cannonicalise key xs = -- the map of canonicalised keys to groups of inexact matches m' = Map.mapKeysWith (++) cannonicalise m -matchParse :: Parsec a => String -> Match a +matchParse :: CabalParsec a => String -> Match a matchParse = maybe mzero return . simpleParsec ------------------------------ diff --git a/cabal-install/src/Distribution/Client/Targets.hs b/cabal-install/src/Distribution/Client/Targets.hs index 1a37c9c73b9..fae3de0f0f6 100644 --- a/cabal-install/src/Distribution/Client/Targets.hs +++ b/cabal-install/src/Distribution/Client/Targets.hs @@ -86,6 +86,7 @@ import Distribution.Types.PackageVersionConstraint import Distribution.PackageDescription ( GenericPackageDescription ) +import Distribution.Parsec (ParsecParser) import Distribution.Simple.Utils ( dieWithException , lowercase @@ -105,7 +106,7 @@ import qualified Data.ByteString.Lazy as BS import qualified Data.Map as Map import Distribution.Client.Errors import qualified Distribution.Client.GZipUtils as GZipUtils -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import Distribution.Utils.Path (makeSymbolicPath) import Network.URI ( URI (..) @@ -678,7 +679,7 @@ instance Pretty UserConstraint where pretty (UserConstraint scope prop) = dispPackageConstraint $ PackageConstraint (fromUserConstraintScope scope) prop -instance Parsec UserConstraint where +instance CabalParsec UserConstraint where parsec = do scope <- parseConstraintScope P.spaces @@ -693,7 +694,7 @@ instance Parsec UserConstraint where ] return (UserConstraint scope prop) where - parseConstraintScope :: forall m. CabalParsing m => m UserConstraintScope + parseConstraintScope :: ParsecParser UserConstraintScope parseConstraintScope = do pn <- parsec P.choice @@ -702,13 +703,13 @@ instance Parsec UserConstraint where , return (UserQualified UserQualToplevel pn) ] where - withDot :: PackageName -> m UserConstraintScope + withDot :: PackageName -> ParsecParser UserConstraintScope withDot pn | pn == mkPackageName "any" = UserAnyQualifier <$> parsec | pn == mkPackageName "setup" = UserAnySetupQualifier <$> parsec | otherwise = P.unexpected $ "constraint scope: " ++ unPackageName pn - withColon :: PackageName -> m UserConstraintScope + withColon :: PackageName -> ParsecParser UserConstraintScope withColon pn = UserQualified (UserQualSetup pn) <$ P.string "setup." diff --git a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs index 0a5700174b8..421493453a3 100644 --- a/cabal-install/src/Distribution/Client/Types/AllowNewer.hs +++ b/cabal-install/src/Distribution/Client/Types/AllowNewer.hs @@ -15,12 +15,12 @@ module Distribution.Client.Types.AllowNewer import Distribution.Client.Compat.Prelude import Prelude () -import Distribution.Parsec (parsecLeadingCommaNonEmpty) +import Distribution.Parsec (ParsecParser, parsecLeadingCommaNonEmpty) import Distribution.Types.PackageId (PackageId, PackageIdentifier (..)) import Distribution.Types.PackageName (PackageName, mkPackageName) import Distribution.Types.Version (nullVersion) -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- $setup @@ -98,17 +98,17 @@ instance Pretty RelaxedDep where RelaxDepModNone -> pretty subj RelaxDepModCaret -> Disp.char '^' Disp.<> pretty subj -instance Parsec RelaxedDep where +instance CabalParsec RelaxedDep where parsec = P.char '*' *> relaxedDepStarP <|> (parsec >>= relaxedDepPkgidP) -- continuation after * -relaxedDepStarP :: CabalParsing m => m RelaxedDep +relaxedDepStarP :: ParsecParser RelaxedDep relaxedDepStarP = RelaxedDep RelaxDepScopeAll <$ P.char ':' <*> modP <*> parsec <|> pure (RelaxedDep RelaxDepScopeAll RelaxDepModNone RelaxDepSubjectAll) -- continuation after package identifier -relaxedDepPkgidP :: CabalParsing m => PackageIdentifier -> m RelaxedDep +relaxedDepPkgidP :: PackageIdentifier -> ParsecParser RelaxedDep relaxedDepPkgidP pid@(PackageIdentifier pn v) | pn == mkPackageName "all" , v == nullVersion = @@ -120,14 +120,14 @@ relaxedDepPkgidP pid@(PackageIdentifier pn v) | otherwise = RelaxedDep (RelaxDepScopePackageId pid) <$ P.char ':' <*> modP <*> parsec -modP :: P.CharParsing m => m RelaxDepMod +modP :: P.ParsecParser RelaxDepMod modP = RelaxDepModCaret <$ P.char '^' <|> pure RelaxDepModNone instance Pretty RelaxDepSubject where pretty RelaxDepSubjectAll = Disp.text "*" pretty (RelaxDepSubjectPkg pn) = pretty pn -instance Parsec RelaxDepSubject where +instance CabalParsec RelaxDepSubject where parsec = RelaxDepSubjectAll <$ P.char '*' <|> pkgn where pkgn = do @@ -170,7 +170,7 @@ instance Pretty RelaxDeps where -- -- >>> simpleParsec "" :: Maybe RelaxDeps -- Nothing -instance Parsec RelaxDeps where +instance CabalParsec RelaxDeps where parsec = do xs <- parsecLeadingCommaNonEmpty parsec pure $ case toList xs of diff --git a/cabal-install/src/Distribution/Client/Types/InstallMethod.hs b/cabal-install/src/Distribution/Client/Types/InstallMethod.hs index b7b24aecf08..fa94824327d 100644 --- a/cabal-install/src/Distribution/Client/Types/InstallMethod.hs +++ b/cabal-install/src/Distribution/Client/Types/InstallMethod.hs @@ -5,7 +5,7 @@ module Distribution.Client.Types.InstallMethod where import Distribution.Client.Compat.Prelude import Prelude () -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP data InstallMethod @@ -20,7 +20,7 @@ instance Structured InstallMethod instance Semigroup InstallMethod where _ <> x = x -instance Parsec InstallMethod where +instance CabalParsec InstallMethod where parsec = do name <- P.munch1 isAlpha case name of diff --git a/cabal-install/src/Distribution/Client/Types/OverwritePolicy.hs b/cabal-install/src/Distribution/Client/Types/OverwritePolicy.hs index e992224243a..d9590c5a0e2 100644 --- a/cabal-install/src/Distribution/Client/Types/OverwritePolicy.hs +++ b/cabal-install/src/Distribution/Client/Types/OverwritePolicy.hs @@ -5,7 +5,7 @@ module Distribution.Client.Types.OverwritePolicy where import Distribution.Client.Compat.Prelude import Prelude () -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as PP data OverwritePolicy @@ -17,7 +17,7 @@ data OverwritePolicy instance Binary OverwritePolicy instance Structured OverwritePolicy -instance Parsec OverwritePolicy where +instance CabalParsec OverwritePolicy where parsec = do name <- P.munch1 isAlpha case name of diff --git a/cabal-install/src/Distribution/Client/Types/Repo.hs b/cabal-install/src/Distribution/Client/Types/Repo.hs index b5606725432..27b8104d96a 100644 --- a/cabal-install/src/Distribution/Client/Types/Repo.hs +++ b/cabal-install/src/Distribution/Client/Types/Repo.hs @@ -27,7 +27,7 @@ import Distribution.Simple.Utils (toUTF8BS) import Distribution.Client.HashValue (hashValue, showHashValue, truncateHash) import qualified Data.ByteString.Lazy.Char8 as LBS -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp import Distribution.Client.Types.RepoName @@ -70,7 +70,7 @@ instance Pretty RemoteRepo where <<>> Disp.text (uriToString id (remoteRepoURI r) []) -- | Note: serialised format represents 'RemoteRepo' only partially. -instance Parsec RemoteRepo where +instance CabalParsec RemoteRepo where parsec = do name <- parsec _ <- P.char ':' @@ -108,7 +108,7 @@ instance Binary LocalRepo instance Structured LocalRepo -- | Note: doesn't parse 'localRepoSharedCache' field. -instance Parsec LocalRepo where +instance CabalParsec LocalRepo where parsec = do n <- parsec _ <- P.char ':' diff --git a/cabal-install/src/Distribution/Client/Types/RepoName.hs b/cabal-install/src/Distribution/Client/Types/RepoName.hs index 1a9b8012aa9..daa7ab1cae4 100644 --- a/cabal-install/src/Distribution/Client/Types/RepoName.hs +++ b/cabal-install/src/Distribution/Client/Types/RepoName.hs @@ -7,7 +7,7 @@ module Distribution.Client.Types.RepoName import Distribution.Client.Compat.Prelude import Prelude () -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp -- $setup @@ -33,7 +33,7 @@ instance Pretty RepoName where -- -- >>> simpleParsec "0123" :: Maybe RepoName -- Nothing -instance Parsec RepoName where +instance CabalParsec RepoName where parsec = RepoName <$> parser where parser = (:) <$> lead <*> rest diff --git a/changelog.d/pr-10081 b/changelog.d/pr-10081 new file mode 100644 index 00000000000..bbdf30fa77c --- /dev/null +++ b/changelog.d/pr-10081 @@ -0,0 +1,16 @@ +synopsis: Remove the `CabalParsing`, `CharParsing`, and `Parsing` classes +packages: Cabal-syntax +prs: #10081 +issues: #10080 + +description: { + +- The `CabalParsing` class has been removed. All bindings which were previously + overloaded in `CabalParsing` will have been specialized to `ParsecParser`. +- The `Distribution.Parsec.Parsec` class is renamed to + `Distribution.Parsec.CabalParsec` to avoid ambiguity with + `Text.Parsec.Parsec`. +- The `CharParsing` and `Parsing` classes and modules have been removed, and + their methods are moved into `Distribution.Parsec`. + +} diff --git a/templates/SPDX.LicenseExceptionId.template.hs b/templates/SPDX.LicenseExceptionId.template.hs index c2fcd1462b9..a2774f36e0a 100644 --- a/templates/SPDX.LicenseExceptionId.template.hs +++ b/templates/SPDX.LicenseExceptionId.template.hs @@ -22,7 +22,7 @@ import Distribution.SPDX.LicenseListVersion import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary import qualified Data.Map.Strict as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp ------------------------------------------------------------------------------- @@ -49,7 +49,7 @@ instance Structured LicenseExceptionId where instance Pretty LicenseExceptionId where pretty = Disp.text . licenseExceptionId -instance Parsec LicenseExceptionId where +instance CabalParsec LicenseExceptionId where parsec = do n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' v <- askCabalSpecVersion diff --git a/templates/SPDX.LicenseId.template.hs b/templates/SPDX.LicenseId.template.hs index 6ee2bf6ede3..29ef9801ffe 100644 --- a/templates/SPDX.LicenseId.template.hs +++ b/templates/SPDX.LicenseId.template.hs @@ -25,7 +25,7 @@ import Distribution.SPDX.LicenseListVersion import qualified Data.Binary.Get as Binary import qualified Data.Binary.Put as Binary import qualified Data.Map.Strict as Map -import qualified Distribution.Compat.CharParsing as P +import qualified Distribution.Parsec as P import qualified Text.PrettyPrint as Disp ------------------------------------------------------------------------------- @@ -61,7 +61,7 @@ instance Pretty LicenseId where -- >>> eitherParsec "BSD3" :: Either String LicenseId -- Left "...Unknown SPDX license identifier: 'BSD3' Do you mean BSD-3-Clause?" -- -instance Parsec LicenseId where +instance CabalParsec LicenseId where parsec = do n <- some $ P.satisfy $ \c -> isAsciiAlphaNum c || c == '-' || c == '.' v <- askCabalSpecVersion