Parser: allowLegacySDLEmptyFields option + minor naming tweaks

This commit is contained in:
Vladimir Razuvaev 2018-08-08 00:41:20 +07:00
parent ea13c9edbf
commit 8e02fdc537
2 changed files with 67 additions and 18 deletions

View File

@ -62,23 +62,32 @@ class Parser
* Available options: * Available options:
* *
* noLocation: boolean, * noLocation: boolean,
* (By default, the parser creates AST nodes that know the location * (By default, the parser creates AST nodes that know the location
* in the source that they correspond to. This configuration flag * in the source that they correspond to. This configuration flag
* disables that behavior for performance or testing.) * disables that behavior for performance or testing.)
*
*
* allowLegacySDLEmptyFields: boolean
* If enabled, the parser will parse empty fields sets in the Schema
* Definition Language. Otherwise, the parser will follow the current
* specification.
*
* This option is provided to ease adoption of the final SDL specification
* and will be removed in a future major release.
* *
* experimentalFragmentVariables: boolean, * experimentalFragmentVariables: boolean,
* (If enabled, the parser will understand and parse variable definitions * (If enabled, the parser will understand and parse variable definitions
* contained in a fragment definition. They'll be represented in the * contained in a fragment definition. They'll be represented in the
* `variableDefinitions` field of the FragmentDefinitionNode. * `variableDefinitions` field of the FragmentDefinitionNode.
* *
* The syntax is identical to normal, query-defined variables. For example: * The syntax is identical to normal, query-defined variables. For example:
* *
* fragment A($var: Boolean = false) on T { * fragment A($var: Boolean = false) on T {
* ... * ...
* } * }
* *
* Note: this feature is experimental and may change or be removed in the * Note: this feature is experimental and may change or be removed in the
* future.) * future.)
* *
* @api * @api
* @param Source|string $source * @param Source|string $source
@ -1083,6 +1092,16 @@ class Parser
*/ */
function parseFieldsDefinition() function parseFieldsDefinition()
{ {
// Legacy support for the SDL?
if (
!empty($this->lexer->options['allowLegacySDLEmptyFields']) &&
$this->peek(Token::BRACE_L) &&
$this->lexer->lookahead()->kind === Token::BRACE_R
) {
$this->lexer->advance();
$this->lexer->advance();
return [];
}
return $this->peek(Token::BRACE_L) return $this->peek(Token::BRACE_L)
? $this->many( ? $this->many(
Token::BRACE_L, Token::BRACE_L,
@ -1177,6 +1196,9 @@ class Parser
} }
/** /**
* UnionTypeDefinition :
* - Description? union Name Directives[Const]? UnionMemberTypes?
*
* @return UnionTypeDefinitionNode * @return UnionTypeDefinitionNode
* @throws SyntaxError * @throws SyntaxError
*/ */
@ -1187,7 +1209,7 @@ class Parser
$this->expectKeyword('union'); $this->expectKeyword('union');
$name = $this->parseName(); $name = $this->parseName();
$directives = $this->parseDirectives(true); $directives = $this->parseDirectives(true);
$types = $this->parseMemberTypesDefinition(); $types = $this->parseUnionMemberTypes();
return new UnionTypeDefinitionNode([ return new UnionTypeDefinitionNode([
'name' => $name, 'name' => $name,
@ -1199,13 +1221,13 @@ class Parser
} }
/** /**
* MemberTypes : * UnionMemberTypes :
* - `|`? NamedType * - = `|`? NamedType
* - MemberTypes | NamedType * - UnionMemberTypes | NamedType
* *
* @return NamedTypeNode[] * @return NamedTypeNode[]
*/ */
function parseMemberTypesDefinition() function parseUnionMemberTypes()
{ {
$types = []; $types = [];
if ($this->skip(Token::EQUALS)) { if ($this->skip(Token::EQUALS)) {
@ -1424,6 +1446,10 @@ class Parser
} }
/** /**
* UnionTypeExtension :
* - extend union Name Directives[Const]? UnionMemberTypes
* - extend union Name Directives[Const]
*
* @return UnionTypeExtensionNode * @return UnionTypeExtensionNode
* @throws SyntaxError * @throws SyntaxError
*/ */
@ -1433,7 +1459,7 @@ class Parser
$this->expectKeyword('union'); $this->expectKeyword('union');
$name = $this->parseName(); $name = $this->parseName();
$directives = $this->parseDirectives(true); $directives = $this->parseDirectives(true);
$types = $this->parseMemberTypesDefinition(); $types = $this->parseUnionMemberTypes();
if ( if (
count($directives) === 0 && count($directives) === 0 &&
!$types !$types

View File

@ -861,6 +861,29 @@ input Hello {
); );
} }
public function testDoesNotAllowEmptyFields()
{
$body = 'type Hello { }';
$this->expectSyntaxError($body, 'Syntax Error: Expected Name, found }', new SourceLocation(1, 14));
}
/**
* @it Option: allowLegacySDLEmptyFields supports type with empty fields
*/
public function testAllowLegacySDLEmptyFieldsOption()
{
$body = 'type Hello { }';
$doc = Parser::parse($body, ['allowLegacySDLEmptyFields' => true]);
$expected = [
'definitions' => [
[
'fields' => [],
],
],
];
$this->assertArraySubset($expected, $doc->toArray(true));
}
private function typeNode($name, $loc) private function typeNode($name, $loc)
{ {
return [ return [