forked from OSS/graphql
Try all extension parsers
This commit is contained in:
parent
a6bd2370b6
commit
e8b82122c6
@ -267,7 +267,7 @@ data OperationTypeDefinition
|
|||||||
|
|
||||||
data SchemaExtension
|
data SchemaExtension
|
||||||
= SchemaOperationExtension [Directive] (NonEmpty OperationTypeDefinition)
|
= SchemaOperationExtension [Directive] (NonEmpty OperationTypeDefinition)
|
||||||
| SchemaDirectiveExtension (NonEmpty Directive)
|
| SchemaDirectivesExtension (NonEmpty Directive)
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
-- ** Descriptions
|
-- ** Descriptions
|
||||||
|
@ -33,9 +33,12 @@ import Control.Applicative (Alternative(..), liftA2)
|
|||||||
import Data.Char (chr, digitToInt, isAsciiLower, isAsciiUpper, ord)
|
import Data.Char (chr, digitToInt, isAsciiLower, isAsciiUpper, ord)
|
||||||
import Data.Foldable (foldl')
|
import Data.Foldable (foldl')
|
||||||
import Data.List (dropWhileEnd)
|
import Data.List (dropWhileEnd)
|
||||||
|
import qualified Data.List.NonEmpty as NonEmpty
|
||||||
|
import Data.List.NonEmpty (NonEmpty(..))
|
||||||
import Data.Proxy (Proxy(..))
|
import Data.Proxy (Proxy(..))
|
||||||
import Data.Void (Void)
|
import Data.Void (Void)
|
||||||
import Text.Megaparsec ( Parsec
|
import Text.Megaparsec ( Parsec
|
||||||
|
, (<?>)
|
||||||
, between
|
, between
|
||||||
, chunk
|
, chunk
|
||||||
, chunkToTokens
|
, chunkToTokens
|
||||||
@ -220,5 +223,14 @@ unicodeBOM :: Parser ()
|
|||||||
unicodeBOM = optional (char '\xfeff') >> pure ()
|
unicodeBOM = optional (char '\xfeff') >> pure ()
|
||||||
|
|
||||||
-- | Parses "extend" followed by a 'symbol'. It is used by schema extensions.
|
-- | Parses "extend" followed by a 'symbol'. It is used by schema extensions.
|
||||||
extend :: Text -> Parser ()
|
extend :: forall a. Text -> String -> NonEmpty (Parser a) -> Parser a
|
||||||
extend token = symbol "extend" *> symbol token >> pure ()
|
extend token extensionLabel parsers
|
||||||
|
= foldr combine headParser (NonEmpty.tail parsers)
|
||||||
|
<?> extensionLabel
|
||||||
|
where
|
||||||
|
headParser = tryExtension $ NonEmpty.head parsers
|
||||||
|
combine current accumulated = accumulated <|> tryExtension current
|
||||||
|
tryExtension extensionParser = try
|
||||||
|
$ symbol "extend"
|
||||||
|
*> symbol token
|
||||||
|
*> extensionParser
|
@ -9,7 +9,7 @@ module Language.GraphQL.AST.Parser
|
|||||||
import Control.Applicative (Alternative(..), optional)
|
import Control.Applicative (Alternative(..), optional)
|
||||||
import Control.Applicative.Combinators (sepBy1)
|
import Control.Applicative.Combinators (sepBy1)
|
||||||
import qualified Control.Applicative.Combinators.NonEmpty as NonEmpty
|
import qualified Control.Applicative.Combinators.NonEmpty as NonEmpty
|
||||||
import Data.List.NonEmpty (NonEmpty)
|
import Data.List.NonEmpty (NonEmpty(..))
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import qualified Language.GraphQL.AST.DirectiveLocation as Directive
|
import qualified Language.GraphQL.AST.DirectiveLocation as Directive
|
||||||
import Language.GraphQL.AST.DirectiveLocation
|
import Language.GraphQL.AST.DirectiveLocation
|
||||||
@ -118,11 +118,8 @@ scalarTypeDefinition = ScalarTypeDefinition
|
|||||||
<?> "ScalarTypeDefinition"
|
<?> "ScalarTypeDefinition"
|
||||||
|
|
||||||
scalarTypeExtension :: Parser TypeExtension
|
scalarTypeExtension :: Parser TypeExtension
|
||||||
scalarTypeExtension = ScalarTypeExtension
|
scalarTypeExtension = extend "scalar" "ScalarTypeExtension"
|
||||||
<$ extend "scalar"
|
$ (ScalarTypeExtension <$> name <*> NonEmpty.some directive) :| []
|
||||||
<*> name
|
|
||||||
<*> NonEmpty.some directive
|
|
||||||
<?> "ScalarTypeExtension"
|
|
||||||
|
|
||||||
objectTypeDefinition :: Parser TypeDefinition
|
objectTypeDefinition :: Parser TypeDefinition
|
||||||
objectTypeDefinition = ObjectTypeDefinition
|
objectTypeDefinition = ObjectTypeDefinition
|
||||||
@ -135,11 +132,11 @@ objectTypeDefinition = ObjectTypeDefinition
|
|||||||
<?> "ObjectTypeDefinition"
|
<?> "ObjectTypeDefinition"
|
||||||
|
|
||||||
objectTypeExtension :: Parser TypeExtension
|
objectTypeExtension :: Parser TypeExtension
|
||||||
objectTypeExtension = extend "type"
|
objectTypeExtension = extend "type" "ObjectTypeExtension"
|
||||||
>> try fieldsDefinitionExtension
|
$ fieldsDefinitionExtension :|
|
||||||
<|> try directivesExtension
|
[ directivesExtension
|
||||||
<|> implementsInterfacesExtension
|
, implementsInterfacesExtension
|
||||||
<?> "ObjectTypeExtension"
|
]
|
||||||
where
|
where
|
||||||
fieldsDefinitionExtension = ObjectTypeFieldsDefinitionExtension
|
fieldsDefinitionExtension = ObjectTypeFieldsDefinitionExtension
|
||||||
<$> name
|
<$> name
|
||||||
@ -169,10 +166,8 @@ unionTypeDefinition = UnionTypeDefinition
|
|||||||
<?> "UnionTypeDefinition"
|
<?> "UnionTypeDefinition"
|
||||||
|
|
||||||
unionTypeExtension :: Parser TypeExtension
|
unionTypeExtension :: Parser TypeExtension
|
||||||
unionTypeExtension = extend "union"
|
unionTypeExtension = extend "union" "UnionTypeExtension"
|
||||||
>> try unionMemberTypesExtension
|
$ unionMemberTypesExtension :| [directivesExtension]
|
||||||
<|> directivesExtension
|
|
||||||
<?> "UnionTypeExtension"
|
|
||||||
where
|
where
|
||||||
unionMemberTypesExtension = UnionTypeUnionMemberTypesExtension
|
unionMemberTypesExtension = UnionTypeUnionMemberTypesExtension
|
||||||
<$> name
|
<$> name
|
||||||
@ -202,10 +197,8 @@ interfaceTypeDefinition = InterfaceTypeDefinition
|
|||||||
<?> "InterfaceTypeDefinition"
|
<?> "InterfaceTypeDefinition"
|
||||||
|
|
||||||
interfaceTypeExtension :: Parser TypeExtension
|
interfaceTypeExtension :: Parser TypeExtension
|
||||||
interfaceTypeExtension = extend "interface"
|
interfaceTypeExtension = extend "interface" "InterfaceTypeExtension"
|
||||||
>> try fieldsDefinitionExtension
|
$ fieldsDefinitionExtension :| [directivesExtension]
|
||||||
<|> directivesExtension
|
|
||||||
<?> "InterfaceTypeExtension"
|
|
||||||
where
|
where
|
||||||
fieldsDefinitionExtension = InterfaceTypeFieldsDefinitionExtension
|
fieldsDefinitionExtension = InterfaceTypeFieldsDefinitionExtension
|
||||||
<$> name
|
<$> name
|
||||||
@ -225,10 +218,8 @@ enumTypeDefinition = EnumTypeDefinition
|
|||||||
<?> "EnumTypeDefinition"
|
<?> "EnumTypeDefinition"
|
||||||
|
|
||||||
enumTypeExtension :: Parser TypeExtension
|
enumTypeExtension :: Parser TypeExtension
|
||||||
enumTypeExtension = extend "enum"
|
enumTypeExtension = extend "enum" "EnumTypeExtension"
|
||||||
>> try enumValuesDefinitionExtension
|
$ enumValuesDefinitionExtension :| [directivesExtension]
|
||||||
<|> directivesExtension
|
|
||||||
<?> "EnumTypeExtension"
|
|
||||||
where
|
where
|
||||||
enumValuesDefinitionExtension = EnumTypeEnumValuesDefinitionExtension
|
enumValuesDefinitionExtension = EnumTypeEnumValuesDefinitionExtension
|
||||||
<$> name
|
<$> name
|
||||||
@ -248,10 +239,8 @@ inputObjectTypeDefinition = InputObjectTypeDefinition
|
|||||||
<?> "InputObjectTypeDefinition"
|
<?> "InputObjectTypeDefinition"
|
||||||
|
|
||||||
inputObjectTypeExtension :: Parser TypeExtension
|
inputObjectTypeExtension :: Parser TypeExtension
|
||||||
inputObjectTypeExtension = extend "input"
|
inputObjectTypeExtension = extend "input" "InputObjectTypeExtension"
|
||||||
>> try inputFieldsDefinitionExtension
|
$ inputFieldsDefinitionExtension :| [directivesExtension]
|
||||||
<|> directivesExtension
|
|
||||||
<?> "InputObjectTypeExtension"
|
|
||||||
where
|
where
|
||||||
inputFieldsDefinitionExtension = InputObjectTypeInputFieldsDefinitionExtension
|
inputFieldsDefinitionExtension = InputObjectTypeInputFieldsDefinitionExtension
|
||||||
<$> name
|
<$> name
|
||||||
@ -314,11 +303,11 @@ operationTypeDefinitions :: Parser (NonEmpty OperationTypeDefinition)
|
|||||||
operationTypeDefinitions = braces $ NonEmpty.some operationTypeDefinition
|
operationTypeDefinitions = braces $ NonEmpty.some operationTypeDefinition
|
||||||
|
|
||||||
schemaExtension :: Parser SchemaExtension
|
schemaExtension :: Parser SchemaExtension
|
||||||
schemaExtension = extend "schema"
|
schemaExtension = extend "schema" "SchemaExtension"
|
||||||
>> try schemaOperationExtension
|
$ schemaOperationExtension :| [directivesExtension]
|
||||||
<|> SchemaDirectiveExtension <$> NonEmpty.some directive
|
|
||||||
<?> "SchemaExtension"
|
|
||||||
where
|
where
|
||||||
|
directivesExtension = SchemaDirectivesExtension
|
||||||
|
<$> NonEmpty.some directive
|
||||||
schemaOperationExtension = SchemaOperationExtension
|
schemaOperationExtension = SchemaOperationExtension
|
||||||
<$> directives
|
<$> directives
|
||||||
<*> operationTypeDefinitions
|
<*> operationTypeDefinitions
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
resolver: lts-14.21
|
resolver: lts-14.22
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
- .
|
- .
|
||||||
|
@ -88,9 +88,12 @@ spec = describe "Lexer" $ do
|
|||||||
it "lexes ampersand" $
|
it "lexes ampersand" $
|
||||||
parse amp "" "&" `shouldParse` "&"
|
parse amp "" "&" `shouldParse` "&"
|
||||||
it "lexes schema extensions" $
|
it "lexes schema extensions" $
|
||||||
parse (extend "schema") "" `shouldSucceedOn` "extend schema"
|
parseExtend "schema" `shouldSucceedOn` "extend schema"
|
||||||
it "fails if the given token doesn't match" $
|
it "fails if the given token doesn't match" $
|
||||||
parse (extend "schema") "" `shouldFailOn` "extend shema"
|
parseExtend "schema" `shouldFailOn` "extend shema"
|
||||||
|
|
||||||
|
parseExtend :: Text -> (Text -> Either (ParseErrorBundle Text Void) ())
|
||||||
|
parseExtend extension = parse (extend extension "" $ pure $ pure ()) ""
|
||||||
|
|
||||||
runBetween :: (Parser () -> Parser ()) -> Text -> Either (ParseErrorBundle Text Void) ()
|
runBetween :: (Parser () -> Parser ()) -> Text -> Either (ParseErrorBundle Text Void) ()
|
||||||
runBetween parser = parse (parser $ pure ()) ""
|
runBetween parser = parse (parser $ pure ()) ""
|
||||||
|
@ -135,3 +135,10 @@ spec = describe "Parser" $ do
|
|||||||
$ OperationTypeDefinition Query "Query" :| []
|
$ OperationTypeDefinition Query "Query" :| []
|
||||||
query = [r|extend schema @newDirective { query: Query }|]
|
query = [r|extend schema @newDirective { query: Query }|]
|
||||||
in parse document "" query `shouldParse` (testSchemaExtension :| [])
|
in parse document "" query `shouldParse` (testSchemaExtension :| [])
|
||||||
|
|
||||||
|
it "parses an object extension" $
|
||||||
|
parse document "" `shouldSucceedOn` [r|
|
||||||
|
extend type Story {
|
||||||
|
isHiddenLocally: Boolean
|
||||||
|
}
|
||||||
|
|]
|
Loading…
Reference in New Issue
Block a user