|
49 | 49 | SelectionSetNode, |
50 | 50 | StringValueNode, |
51 | 51 | TypeNode, |
52 | | - TypeSystemDefinitionNode, |
53 | 52 | TypeSystemExtensionNode, |
54 | 53 | UnionTypeDefinitionNode, |
55 | 54 | UnionTypeExtensionNode, |
@@ -224,46 +223,64 @@ def parse_document(self) -> DocumentNode: |
224 | 223 | loc=self.loc(start), |
225 | 224 | ) |
226 | 225 |
|
227 | | - _parse_definition_method_names: Dict[str, str] = { |
| 226 | + _parse_type_system_definition_method_names: Dict[str, str] = { |
| 227 | + "schema": "schema_definition", |
| 228 | + "scalar": "scalar_type_definition", |
| 229 | + "type": "object_type_definition", |
| 230 | + "interface": "interface_type_definition", |
| 231 | + "union": "union_type_definition", |
| 232 | + "enum": "enum_type_definition", |
| 233 | + "input": "input_object_type_definition", |
| 234 | + "directive": "directive_definition", |
| 235 | + } |
| 236 | + |
| 237 | + _parse_other_definition_method_names: Dict[str, str] = { |
228 | 238 | **dict.fromkeys(("query", "mutation", "subscription"), "operation_definition"), |
229 | 239 | "fragment": "fragment_definition", |
230 | | - **dict.fromkeys( |
231 | | - ( |
232 | | - "schema", |
233 | | - "scalar", |
234 | | - "type", |
235 | | - "interface", |
236 | | - "union", |
237 | | - "enum", |
238 | | - "input", |
239 | | - "directive", |
240 | | - ), |
241 | | - "type_system_definition", |
242 | | - ), |
243 | 240 | "extend": "type_system_extension", |
244 | 241 | } |
245 | 242 |
|
246 | 243 | def parse_definition(self) -> DefinitionNode: |
247 | 244 | """Definition: ExecutableDefinition or TypeSystemDefinition/Extension |
248 | 245 |
|
249 | 246 | ExecutableDefinition: OperationDefinition or FragmentDefinition |
| 247 | +
|
| 248 | + TypeSystemDefinition: SchemaDefinition, TypeDefinition or DirectiveDefinition |
| 249 | +
|
| 250 | + TypeDefinition: ScalarTypeDefinition, ObjectTypeDefinition, |
| 251 | + InterfaceTypeDefinition, UnionTypeDefinition, |
| 252 | + EnumTypeDefinition or InputObjectTypeDefinition |
250 | 253 | """ |
251 | | - if self.peek(TokenKind.NAME): |
252 | | - method_name = self._parse_definition_method_names.get( |
253 | | - cast(str, self._lexer.token.value) |
| 254 | + if self.peek(TokenKind.BRACE_L): |
| 255 | + return self.parse_operation_definition() |
| 256 | + |
| 257 | + # Many definitions begin with a description and require a lookahead. |
| 258 | + has_description = self.peek_description() |
| 259 | + keyword_token = ( |
| 260 | + self._lexer.lookahead() if has_description else self._lexer.token |
| 261 | + ) |
| 262 | + |
| 263 | + if keyword_token.kind is TokenKind.NAME: |
| 264 | + token_name = cast(str, keyword_token.value) |
| 265 | + method_name = self._parse_type_system_definition_method_names.get( |
| 266 | + token_name |
254 | 267 | ) |
255 | 268 | if method_name: |
256 | 269 | return getattr(self, f"parse_{method_name}")() |
257 | | - elif self.peek(TokenKind.BRACE_L): |
258 | | - return self.parse_operation_definition() |
259 | | - elif self.peek_description(): |
260 | | - return self.parse_type_system_definition() |
261 | | - raise self.unexpected() |
262 | 270 |
|
263 | | - _parse_executable_definition_method_names: Dict[str, str] = { |
264 | | - **dict.fromkeys(("query", "mutation", "subscription"), "operation_definition"), |
265 | | - **dict.fromkeys(("fragment",), "fragment_definition"), |
266 | | - } |
| 271 | + if has_description: |
| 272 | + raise GraphQLSyntaxError( |
| 273 | + self._lexer.source, |
| 274 | + self._lexer.token.start, |
| 275 | + "Unexpected description," |
| 276 | + " descriptions are supported only on type definitions.", |
| 277 | + ) |
| 278 | + |
| 279 | + method_name = self._parse_other_definition_method_names.get(token_name) |
| 280 | + if method_name: |
| 281 | + return getattr(self, f"parse_{method_name}")() |
| 282 | + |
| 283 | + raise self.unexpected(keyword_token) |
267 | 284 |
|
268 | 285 | # Implement the parsing rules in the Operations section. |
269 | 286 |
|
@@ -580,30 +597,6 @@ def parse_named_type(self) -> NamedTypeNode: |
580 | 597 |
|
581 | 598 | # Implement the parsing rules in the Type Definition section. |
582 | 599 |
|
583 | | - _parse_type_system_definition_method_names: Dict[str, str] = { |
584 | | - "schema": "schema_definition", |
585 | | - "scalar": "scalar_type_definition", |
586 | | - "type": "object_type_definition", |
587 | | - "interface": "interface_type_definition", |
588 | | - "union": "union_type_definition", |
589 | | - "enum": "enum_type_definition", |
590 | | - "input": "input_object_type_definition", |
591 | | - "directive": "directive_definition", |
592 | | - } |
593 | | - |
594 | | - def parse_type_system_definition(self) -> TypeSystemDefinitionNode: |
595 | | - """TypeSystemDefinition""" |
596 | | - # Many definitions begin with a description and require a lookahead. |
597 | | - keyword_token = ( |
598 | | - self._lexer.lookahead() if self.peek_description() else self._lexer.token |
599 | | - ) |
600 | | - method_name = self._parse_type_system_definition_method_names.get( |
601 | | - cast(str, keyword_token.value) |
602 | | - ) |
603 | | - if method_name: |
604 | | - return getattr(self, f"parse_{method_name}")() |
605 | | - raise self.unexpected(keyword_token) |
606 | | - |
607 | 600 | _parse_type_extension_method_names: Dict[str, str] = { |
608 | 601 | "schema": "schema_extension", |
609 | 602 | "scalar": "scalar_type_extension", |
|
0 commit comments