language-thrift 0.10.0.0 → 0.11.0.0
raw patch · 5 files changed
+85/−68 lines, 5 filesdep ~containersdep ~megaparsecPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: containers, megaparsec
API changes (from Hackage documentation)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Const a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.ConstValue a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Definition a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Enum a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.EnumDef a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Field a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Function a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Header a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Include a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Namespace a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Program a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Senum a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Service a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Struct a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Type a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.TypeReference a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty (Language.Thrift.Internal.AST.Typedef a)
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty Language.Thrift.Internal.AST.FieldRequiredness
- Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Pretty Language.Thrift.Internal.AST.TypeAnnotation
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Const a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.ConstValue a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Definition a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Enum a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.EnumDef a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Field a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Function a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Header a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Include a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Namespace a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Program a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Senum a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Service a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Struct a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Type a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.TypeReference a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty (Language.Thrift.Internal.AST.Typedef a)
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Language.Thrift.Internal.AST.FieldRequiredness
+ Language.Thrift.Pretty: instance Text.PrettyPrint.ANSI.Leijen.Internal.Pretty Language.Thrift.Internal.AST.TypeAnnotation
- Language.Thrift.AST: ConstDefinition :: (Const srcAnnot) -> Definition srcAnnot
+ Language.Thrift.AST: ConstDefinition :: Const srcAnnot -> Definition srcAnnot
- Language.Thrift.AST: EnumType :: (Enum srcAnnot) -> Type srcAnnot
+ Language.Thrift.AST: EnumType :: Enum srcAnnot -> Type srcAnnot
- Language.Thrift.AST: HeaderInclude :: (Include srcAnnot) -> Header srcAnnot
+ Language.Thrift.AST: HeaderInclude :: Include srcAnnot -> Header srcAnnot
- Language.Thrift.AST: HeaderNamespace :: (Namespace srcAnnot) -> Header srcAnnot
+ Language.Thrift.AST: HeaderNamespace :: Namespace srcAnnot -> Header srcAnnot
- Language.Thrift.AST: ListType :: (TypeReference srcAnnot) -> [TypeAnnotation] -> srcAnnot -> TypeReference srcAnnot
+ Language.Thrift.AST: ListType :: TypeReference srcAnnot -> [TypeAnnotation] -> srcAnnot -> TypeReference srcAnnot
- Language.Thrift.AST: MapType :: (TypeReference srcAnnot) -> (TypeReference srcAnnot) -> [TypeAnnotation] -> srcAnnot -> TypeReference srcAnnot
+ Language.Thrift.AST: MapType :: TypeReference srcAnnot -> TypeReference srcAnnot -> [TypeAnnotation] -> srcAnnot -> TypeReference srcAnnot
- Language.Thrift.AST: SenumType :: (Senum srcAnnot) -> Type srcAnnot
+ Language.Thrift.AST: SenumType :: Senum srcAnnot -> Type srcAnnot
- Language.Thrift.AST: ServiceDefinition :: (Service srcAnnot) -> Definition srcAnnot
+ Language.Thrift.AST: ServiceDefinition :: Service srcAnnot -> Definition srcAnnot
- Language.Thrift.AST: SetType :: (TypeReference srcAnnot) -> [TypeAnnotation] -> srcAnnot -> TypeReference srcAnnot
+ Language.Thrift.AST: SetType :: TypeReference srcAnnot -> [TypeAnnotation] -> srcAnnot -> TypeReference srcAnnot
- Language.Thrift.AST: StructType :: (Struct srcAnnot) -> Type srcAnnot
+ Language.Thrift.AST: StructType :: Struct srcAnnot -> Type srcAnnot
- Language.Thrift.AST: TypeDefinition :: (Type srcAnnot) -> Definition srcAnnot
+ Language.Thrift.AST: TypeDefinition :: Type srcAnnot -> Definition srcAnnot
- Language.Thrift.AST: TypedefType :: (Typedef srcAnnot) -> Type srcAnnot
+ Language.Thrift.AST: TypedefType :: Typedef srcAnnot -> Type srcAnnot
- Language.Thrift.Parser: parse :: (Stream s, Token s ~ Char) => FilePath -> s -> Either (ParseError Char Dec) (Program SourcePos)
+ Language.Thrift.Parser: parse :: (Stream s, Token s ~ Char) => FilePath -> s -> Either (ParseErrorBundle s Void) (Program SourcePos)
- Language.Thrift.Parser: parseFromFile :: FilePath -> IO (Either (ParseError Char Dec) (Program SourcePos))
+ Language.Thrift.Parser: parseFromFile :: FilePath -> IO (Either (ParseErrorBundle Text Void) (Program SourcePos))
- Language.Thrift.Parser: runParser :: Stream s => Parser s a -> Parsec Dec s a
+ Language.Thrift.Parser: runParser :: Stream s => Parser s a -> Parsec Void s a
- Language.Thrift.Parser: thriftIDL :: (Stream s, Token s ~ Char) => Parsec Dec s (Program SourcePos)
+ Language.Thrift.Parser: thriftIDL :: (Stream s, Token s ~ Char) => Parsec Void s (Program SourcePos)
- Language.Thrift.Parser: type Parser s = StateT State (Parsec Dec s)
+ Language.Thrift.Parser: type Parser s = StateT State (Parsec Void s)
Files
- CHANGES.md +5/−0
- language-thrift.cabal +26/−23
- src/Language/Thrift/Parser.hs +50/−43
- test/Language/Thrift/ParserSpec.hs +2/−1
- test/TestUtils.hs +2/−1
CHANGES.md view
@@ -1,3 +1,8 @@+0.11.0.0 (2019-10-01)+=====================++- Port to Megaparsec 7.+ 0.10.0.0 (2016-09-25) =====================
language-thrift.cabal view
@@ -1,11 +1,14 @@--- This file has been generated from package.yaml by hpack version 0.14.1.+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.2. -- -- see: https://github.com/sol/hpack+--+-- hash: 4e717e225f20a4779ba92b55f6212040c7138271b8a10c8e4e0d5a62351472a9 name: language-thrift-version: 0.10.0.0+version: 0.11.0.0 bug-reports: https://github.com/abhinav/language-thrift/issues-cabal-version: >= 1.10 build-type: Simple license: BSD3 license-file: LICENSE@@ -16,7 +19,6 @@ <http://thrift.apache.org/docs/idl Thrift IDL format>. category: Language author: Abhinav Gupta- extra-source-files: CHANGES.md examples/generateHaskellTypes.hs@@ -34,13 +36,13 @@ src ghc-options: -Wall build-depends:- base >= 4.7 && < 5,- ansi-wl-pprint >= 0.6 && < 0.7,- containers >= 0.5 && < 0.6,- megaparsec >= 5.0 && < 6.0,- scientific >= 0.3 && < 0.4,- semigroups >= 0.18 && < 0.19,- text >= 1.2,+ ansi-wl-pprint >=0.6 && <0.7,+ base >=4.7 && <5,+ containers >=0.5 && <0.7,+ megaparsec >=7.0 && <8.0,+ scientific >=0.3 && <0.4,+ semigroups >=0.18 && <0.19,+ text >=1.2, transformers exposed-modules: Language.Thrift.AST@@ -57,22 +59,22 @@ type: exitcode-stdio-1.0 main-is: Main.hs hs-source-dirs:- src,+ src test ghc-options: -Wall build-depends:- base >= 4.7 && < 5,- ansi-wl-pprint >= 0.6 && < 0.7,- containers >= 0.5 && < 0.6,- megaparsec >= 5.0 && < 6.0,- scientific >= 0.3 && < 0.4,- semigroups >= 0.18 && < 0.19,- text >= 1.2,- transformers,- hspec >= 2.0,- hspec-discover >= 2.1,+ QuickCheck >=2.5,+ ansi-wl-pprint >=0.6 && <0.7,+ base >=4.7 && <5,+ containers >=0.5 && <0.7,+ hspec >=2.0,+ hspec-discover >=2.1, language-thrift,- QuickCheck >= 2.5+ megaparsec >=7.0 && <8.0,+ scientific >=0.3 && <0.4,+ semigroups >=0.18 && <0.19,+ text >=1.2,+ transformers other-modules: Language.Thrift.AST Language.Thrift.Internal.AST@@ -85,4 +87,5 @@ Language.Thrift.ParserSpec Spec TestUtils+ Paths_language_thrift default-language: Haskell2010
src/Language/Thrift/Parser.hs view
@@ -65,15 +65,19 @@ import Control.Applicative import Control.Monad import Control.Monad.Trans.State (StateT)+import Data.Functor (($>))+import Data.Proxy (Proxy (Proxy)) import Data.Scientific (floatingOrInteger) import Data.Text (Text)+import Data.Void (Void) -import qualified Control.Monad.Trans.State as State-import qualified Data.List.NonEmpty as NonEmpty-import qualified Data.Text as Text-import qualified Data.Text.IO as Text-import qualified Text.Megaparsec as P-import qualified Text.Megaparsec.Lexer as PL+import qualified Control.Monad.Trans.State as State+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Text as Text+import qualified Data.Text.IO as Text+import qualified Text.Megaparsec as P+import qualified Text.Megaparsec.Char as PC+import qualified Text.Megaparsec.Char.Lexer as PL import Language.Thrift.Internal.Reserved (isReserved) @@ -81,23 +85,23 @@ -- | Keeps track of the last docstring seen by the system so that we can -- attach it to entities.-data State = State+newtype State = State { stateDocstring :: T.Docstring } deriving (Show, Eq) -- | Underlying Parser type.-type Parser s = StateT State (P.Parsec P.Dec s)+type Parser s = StateT State (P.Parsec Void s) -- | Evaluates the underlying parser with a default state and get the Megaparsec -- parser.-runParser :: P.Stream s => Parser s a -> P.Parsec P.Dec s a+runParser :: P.Stream s => Parser s a -> P.Parsec Void s a runParser p = State.evalStateT p (State Nothing) -- | Parses the Thrift file at the given path. parseFromFile :: FilePath- -> IO (Either (P.ParseError Char P.Dec) (T.Program P.SourcePos))+ -> IO (Either (P.ParseErrorBundle Text Void) (T.Program P.SourcePos)) parseFromFile path = P.runParser thriftIDL path <$> Text.readFile path -- | @parse name contents@ parses the contents of a Thrift document with name@@ -105,13 +109,13 @@ parse :: (P.Stream s, P.Token s ~ Char) => FilePath- -> s -> Either (P.ParseError Char P.Dec) (T.Program P.SourcePos)+ -> s -> Either (P.ParseErrorBundle s Void) (T.Program P.SourcePos) parse = P.parse thriftIDL -- | Megaparsec parser that is able to parse full Thrift documents. thriftIDL :: (P.Stream s, P.Token s ~ Char)- => P.Parsec P.Dec s (T.Program P.SourcePos)+ => P.Parsec Void s (T.Program P.SourcePos) thriftIDL = runParser program @@ -140,20 +144,20 @@ State.modify' (\st -> st { stateDocstring = Just s}) skipSpace = P.choice- [ P.newline *> clearDocstring- , P.skipSome P.spaceChar+ [ PC.newline *> clearDocstring+ , P.skipSome PC.spaceChar ] skipComments = P.choice- [ P.char '#' *> skipLine- , P.try (P.string "//") *> skipLine- , P.try (P.string "/*") *> skipCStyleComment+ [ PC.char '#' *> skipLine+ , P.try (string "//") *> skipLine+ , P.try (string "/*") *> skipCStyleComment ] *> clearDocstring - skipLine = void P.eol <|> P.eof <|> (P.anyChar *> skipLine)+ skipLine = void PC.eol <|> P.eof <|> (P.anySingle *> skipLine) skipCStyleComment = P.choice- [ P.try (P.string "*/") *> pure ()+ [ P.try (string "*/") $> () , P.skipSome (noneOf "/*") *> skipCStyleComment , oneOf "/*" *> skipCStyleComment ]@@ -192,17 +196,17 @@ -- docstring :: (P.Stream s, P.Token s ~ Char) => Parser s Text docstring = do- P.try (P.string "/**") >> P.skipMany hspace+ P.try (string "/**") >> P.skipMany hspace indent <- fromIntegral . P.unPos <$> PL.indentLevel isNewLine <- maybeEOL chunks <- loop isNewLine (indent - 1) [] return $! Text.intercalate "\n" chunks where- maybeEOL = (P.eol >> return True) <|> return False+ maybeEOL = (PC.eol >> return True) <|> return False commentChar = noneOf "*\r\n" <|>- P.try (P.char '*' <* P.notFollowedBy (P.char '/'))+ P.try (PC.char '*' <* P.notFollowedBy (PC.char '/')) loop shouldDedent maxDedent chunks = do when shouldDedent $@@ -210,8 +214,8 @@ finishComment <|> readDocLine where finishComment = do- P.try (P.skipMany hspace <* P.string "*/")- void $ optional P.spaceChar+ P.try (P.skipMany hspace <* string "*/")+ void $ optional PC.spaceChar return $! reverse chunks readDocLine = do -- Lines could have aligned *s at the start.@@ -227,7 +231,7 @@ -- -- So if foo starts with "*", we don't want to drop that. when shouldDedent . void $- optional $ P.try (P.char '*' >> optional hspace)+ optional $ P.try (PC.char '*' >> optional hspace) line <- Text.pack <$> P.many commentChar @@ -238,8 +242,8 @@ loop True maxDedent (line:chunks) -symbolic :: (P.Stream s, P.Token s ~ Char) => Char -> Parser s ()-symbolic c = void $ PL.symbol whiteSpace [c]+symbolic :: forall s. (P.Stream s, P.Token s ~ Char) => Char -> Parser s ()+symbolic c = void $ PL.symbol whiteSpace (P.tokenToChunk (Proxy :: Proxy s) c) token :: (P.Stream s, P.Token s ~ Char) => Parser s a -> Parser s a token = PL.lexeme whiteSpace@@ -271,8 +275,8 @@ reserved name = errorUnlessReserved name >> P.label name $ token $ P.try $ do- void (P.string name)- P.notFollowedBy (P.alphaNumChar <|> oneOf "_.")+ void (string name)+ P.notFollowedBy (PC.alphaNumChar <|> oneOf "_.") -- | A string literal. @"hello"@@@ -282,19 +286,19 @@ stringLiteral :: (P.Stream s, P.Token s ~ Char) => Char -> Parser s Text stringLiteral q = fmap Text.pack $- P.char q >> P.manyTill PL.charLiteral (P.char q)+ PC.char q >> P.manyTill PL.charLiteral (PC.char q) integer :: (P.Stream s, P.Token s ~ Char) => Parser s Integer-integer = token PL.integer+integer = token PL.decimal -- | An identifier in a Thrift file. identifier :: (P.Stream s, P.Token s ~ Char) => Parser s Text identifier = P.label "identifier" $ token $ do name <- (:)- <$> (P.letterChar <|> P.char '_')- <*> many (P.alphaNumChar <|> oneOf "_.")+ <$> (PC.letterChar <|> PC.char '_')+ <*> many (PC.alphaNumChar <|> oneOf "_.") when (isReserved name) $ P.unexpected (P.Label (NonEmpty.fromList name)) return (Text.pack name)@@ -360,7 +364,7 @@ -- -- The position will be retrieved BEFORE the parser itself is executed. withPosition :: P.Stream s => Parser s (P.SourcePos -> a) -> Parser s a-withPosition p = P.getPosition >>= \pos -> p <*> pure pos+withPosition p = P.getSourcePos >>= \pos -> p <*> pure pos -- | Convenience wrapper for parsers that expect a docstring and a position.@@ -370,7 +374,7 @@ -- > parseFoo = withDocstring $ Foo <$> parseBar withDocstring :: P.Stream s => Parser s (T.Docstring -> P.SourcePos -> a) -> Parser s a withDocstring p = lastDocstring >>= \s -> do- pos <- P.getPosition+ pos <- P.getSourcePos p <*> pure s <*> pure pos @@ -463,8 +467,8 @@ fieldRequiredness :: (P.Stream s, P.Token s ~ Char) => Parser s T.FieldRequiredness fieldRequiredness = P.choice- [ reserved "required" *> pure T.Required- , reserved "optional" *> pure T.Optional+ [ reserved "required" $> T.Required+ , reserved "optional" $> T.Optional ] @@ -520,7 +524,7 @@ constantValue :: (P.Stream s, P.Token s ~ Char) => Parser s (T.ConstValue P.SourcePos) constantValue = withPosition $ P.choice- [ P.try (P.string "0x") >> T.ConstInt <$> token PL.hexadecimal+ [ P.try (string "0x") >> T.ConstInt <$> token PL.hexadecimal , either T.ConstFloat T.ConstInt <$> token signedNumber , T.ConstLiteral <$> literal@@ -529,7 +533,7 @@ , T.ConstMap <$> constMap ] where- signedNumber = floatingOrInteger <$> PL.signed whiteSpace PL.number+ signedNumber = floatingOrInteger <$> PL.signed whiteSpace PL.scientific constList@@ -537,7 +541,7 @@ constList = symbolic '[' *> loop [] where loop xs = P.choice- [ symbolic ']' *> return (reverse xs)+ [ symbolic ']' $> reverse xs , (:) <$> (constantValue <* optionalSep) <*> pure xs >>= loop@@ -550,7 +554,7 @@ constMap = symbolic '{' *> loop [] where loop xs = P.choice [- symbolic '}' *> return (reverse xs)+ symbolic '}' $> reverse xs , (:) <$> (constantValuePair <* optionalSep) <*> pure xs >>= loop@@ -632,8 +636,8 @@ :: (P.Stream s, P.Token s ~ Char) => Parser s (T.Function P.SourcePos) function = withDocstring $ T.Function- <$> ((reserved "oneway" *> pure True) <|> pure False)- <*> ((reserved "void" *> pure Nothing) <|> Just <$> typeReference)+ <$> ((reserved "oneway" $> True) <|> pure False)+ <*> ((reserved "void" $> Nothing) <|> Just <$> typeReference) <*> identifier <*> parens (many field) <*> optional (reserved "throws" *> parens (many field))@@ -661,3 +665,6 @@ optionalSep :: (P.Stream s, P.Token s ~ Char) => Parser s () optionalSep = void $ optional (comma <|> semi)++string :: forall s. (P.Stream s, P.Token s ~ Char) => String -> Parser s (P.Tokens s)+string = PC.string . P.tokensToChunk (Proxy :: Proxy s)
test/Language/Thrift/ParserSpec.hs view
@@ -10,7 +10,8 @@ import Control.Monad import Data.Text (pack) import Test.Hspec-import Text.Megaparsec (SourcePos, eof, skipMany, spaceChar)+import Text.Megaparsec (SourcePos, eof, skipMany)+import Text.Megaparsec.Char (spaceChar) import TestUtils
test/TestUtils.hs view
@@ -6,6 +6,7 @@ ) where import Control.Monad (when)+import Data.Void (Void) import Test.Hspec (expectationFailure) import qualified Language.Thrift.Parser as T@@ -13,7 +14,7 @@ type Parser = T.Parser String -parse :: Parser a -> String -> Either (P.ParseError Char P.Dec) a+parse :: Parser a -> String -> Either (P.ParseErrorBundle String Void) a parse parser = P.parse (T.runParser parser) "memory" -- | @assertParses parser expected input@ will assert that running @parser@ on