Merge pull request #364 from simPod/instanceof

Replace node kind checks by InstanceOf checks
This commit is contained in:
Vladimir Razuvaev 2019-06-12 14:48:50 +07:00 committed by GitHub
commit 747cb49ae3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 177 additions and 157 deletions

View File

@ -138,8 +138,8 @@ class ReferenceExecutor implements ExecutorImplementation
$operation = null; $operation = null;
$hasMultipleAssumedOperations = false; $hasMultipleAssumedOperations = false;
foreach ($documentNode->definitions as $definition) { foreach ($documentNode->definitions as $definition) {
switch ($definition->kind) { switch (true) {
case NodeKind::OPERATION_DEFINITION: case $definition instanceof OperationDefinitionNode:
if (! $operationName && $operation) { if (! $operationName && $operation) {
$hasMultipleAssumedOperations = true; $hasMultipleAssumedOperations = true;
} }
@ -148,7 +148,7 @@ class ReferenceExecutor implements ExecutorImplementation
$operation = $definition; $operation = $definition;
} }
break; break;
case NodeKind::FRAGMENT_DEFINITION: case $definition instanceof FragmentDefinitionNode:
$fragments[$definition->name->value] = $definition; $fragments[$definition->name->value] = $definition;
break; break;
} }
@ -343,8 +343,8 @@ class ReferenceExecutor implements ExecutorImplementation
) { ) {
$exeContext = $this->exeContext; $exeContext = $this->exeContext;
foreach ($selectionSet->selections as $selection) { foreach ($selectionSet->selections as $selection) {
switch ($selection->kind) { switch (true) {
case NodeKind::FIELD: case $selection instanceof FieldNode:
if (! $this->shouldIncludeNode($selection)) { if (! $this->shouldIncludeNode($selection)) {
break; break;
} }
@ -354,7 +354,7 @@ class ReferenceExecutor implements ExecutorImplementation
} }
$fields[$name][] = $selection; $fields[$name][] = $selection;
break; break;
case NodeKind::INLINE_FRAGMENT: case $selection instanceof InlineFragmentNode:
if (! $this->shouldIncludeNode($selection) || if (! $this->shouldIncludeNode($selection) ||
! $this->doesFragmentConditionMatch($selection, $runtimeType) ! $this->doesFragmentConditionMatch($selection, $runtimeType)
) { ) {
@ -367,7 +367,7 @@ class ReferenceExecutor implements ExecutorImplementation
$visitedFragmentNames $visitedFragmentNames
); );
break; break;
case NodeKind::FRAGMENT_SPREAD: case $selection instanceof FragmentSpreadNode:
$fragName = $selection->name->value; $fragName = $selection->name->value;
if (! empty($visitedFragmentNames[$fragName]) || ! $this->shouldIncludeNode($selection)) { if (! empty($visitedFragmentNames[$fragName]) || ! $this->shouldIncludeNode($selection)) {
break; break;

View File

@ -64,7 +64,7 @@ class Collector
foreach ($documentNode->definitions as $definitionNode) { foreach ($documentNode->definitions as $definitionNode) {
/** @var DefinitionNode|Node $definitionNode */ /** @var DefinitionNode|Node $definitionNode */
if ($definitionNode->kind === NodeKind::OPERATION_DEFINITION) { if ($definitionNode instanceof OperationDefinitionNode) {
/** @var OperationDefinitionNode $definitionNode */ /** @var OperationDefinitionNode $definitionNode */
if ($operationName === null && $this->operation !== null) { if ($operationName === null && $this->operation !== null) {
$hasMultipleAssumedOperations = true; $hasMultipleAssumedOperations = true;
@ -74,7 +74,7 @@ class Collector
) { ) {
$this->operation = $definitionNode; $this->operation = $definitionNode;
} }
} elseif ($definitionNode->kind === NodeKind::FRAGMENT_DEFINITION) { } elseif ($definitionNode instanceof FragmentDefinitionNode) {
/** @var FragmentDefinitionNode $definitionNode */ /** @var FragmentDefinitionNode $definitionNode */
$this->fragments[$definitionNode->name->value] = $definitionNode; $this->fragments[$definitionNode->name->value] = $definitionNode;
} }
@ -196,7 +196,7 @@ class Collector
} }
} }
if ($selection->kind === NodeKind::FIELD) { if ($selection instanceof FieldNode) {
/** @var FieldNode $selection */ /** @var FieldNode $selection */
$resultName = $selection->alias ? $selection->alias->value : $selection->name->value; $resultName = $selection->alias ? $selection->alias->value : $selection->name->value;
@ -206,7 +206,7 @@ class Collector
} }
$this->fields[$resultName][] = $selection; $this->fields[$resultName][] = $selection;
} elseif ($selection->kind === NodeKind::FRAGMENT_SPREAD) { } elseif ($selection instanceof FragmentSpreadNode) {
/** @var FragmentSpreadNode $selection */ /** @var FragmentSpreadNode $selection */
$fragmentName = $selection->name->value; $fragmentName = $selection->name->value;
@ -249,7 +249,7 @@ class Collector
} }
$this->doCollectFields($runtimeType, $fragmentDefinition->selectionSet); $this->doCollectFields($runtimeType, $fragmentDefinition->selectionSet);
} elseif ($selection->kind === NodeKind::INLINE_FRAGMENT) { } elseif ($selection instanceof InlineFragmentNode) {
/** @var InlineFragmentNode $selection */ /** @var InlineFragmentNode $selection */
if ($selection->typeCondition !== null) { if ($selection->typeCondition !== null) {

View File

@ -9,6 +9,6 @@ class ListTypeNode extends Node implements TypeNode
/** @var string */ /** @var string */
public $kind = NodeKind::LIST_TYPE; public $kind = NodeKind::LIST_TYPE;
/** @var Node */ /** @var TypeNode */
public $type; public $type;
} }

View File

@ -9,6 +9,6 @@ class NonNullTypeNode extends Node implements TypeNode
/** @var string */ /** @var string */
public $kind = NodeKind::NON_NULL_TYPE; public $kind = NodeKind::NON_NULL_TYPE;
/** @var NameNode | ListTypeNode */ /** @var NamedTypeNode | ListTypeNode */
public $type; public $type;
} }

View File

@ -28,6 +28,7 @@ use GraphQL\Language\AST\IntValueNode;
use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\ListTypeNode;
use GraphQL\Language\AST\ListValueNode; use GraphQL\Language\AST\ListValueNode;
use GraphQL\Language\AST\NamedTypeNode; use GraphQL\Language\AST\NamedTypeNode;
use GraphQL\Language\AST\NameNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\NonNullTypeNode; use GraphQL\Language\AST\NonNullTypeNode;
@ -47,6 +48,7 @@ use GraphQL\Language\AST\StringValueNode;
use GraphQL\Language\AST\UnionTypeDefinitionNode; use GraphQL\Language\AST\UnionTypeDefinitionNode;
use GraphQL\Language\AST\UnionTypeExtensionNode; use GraphQL\Language\AST\UnionTypeExtensionNode;
use GraphQL\Language\AST\VariableDefinitionNode; use GraphQL\Language\AST\VariableDefinitionNode;
use GraphQL\Language\AST\VariableNode;
use GraphQL\Utils\Utils; use GraphQL\Utils\Utils;
use function count; use function count;
use function implode; use function implode;
@ -97,11 +99,11 @@ class Printer
$ast, $ast,
[ [
'leave' => [ 'leave' => [
NodeKind::NAME => static function (Node $node) { NodeKind::NAME => static function (NameNode $node) {
return '' . $node->value; return '' . $node->value;
}, },
NodeKind::VARIABLE => static function ($node) { NodeKind::VARIABLE => static function (VariableNode $node) {
return '$' . $node->name; return '$' . $node->name;
}, },

View File

@ -322,7 +322,7 @@ class AST
* *
* @api * @api
*/ */
public static function valueFromAST($valueNode, InputType $type, ?array $variables = null) public static function valueFromAST($valueNode, Type $type, ?array $variables = null)
{ {
$undefined = Utils::undefined(); $undefined = Utils::undefined();

View File

@ -17,7 +17,6 @@ use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\ListTypeNode;
use GraphQL\Language\AST\NamedTypeNode; use GraphQL\Language\AST\NamedTypeNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\NonNullTypeNode; use GraphQL\Language\AST\NonNullTypeNode;
use GraphQL\Language\AST\ObjectTypeDefinitionNode; use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeDefinitionNode; use GraphQL\Language\AST\ScalarTypeDefinitionNode;
@ -245,23 +244,20 @@ class ASTDefinitionBuilder
* *
* @throws Error * @throws Error
*/ */
private function makeSchemaDef($def) private function makeSchemaDef(Node $def)
{ {
if (! $def) { switch (true) {
throw new Error('def must be defined.'); case $def instanceof ObjectTypeDefinitionNode:
}
switch ($def->kind) {
case NodeKind::OBJECT_TYPE_DEFINITION:
return $this->makeTypeDef($def); return $this->makeTypeDef($def);
case NodeKind::INTERFACE_TYPE_DEFINITION: case $def instanceof InterfaceTypeDefinitionNode:
return $this->makeInterfaceDef($def); return $this->makeInterfaceDef($def);
case NodeKind::ENUM_TYPE_DEFINITION: case $def instanceof EnumTypeDefinitionNode:
return $this->makeEnumDef($def); return $this->makeEnumDef($def);
case NodeKind::UNION_TYPE_DEFINITION: case $def instanceof UnionTypeDefinitionNode:
return $this->makeUnionDef($def); return $this->makeUnionDef($def);
case NodeKind::SCALAR_TYPE_DEFINITION: case $def instanceof ScalarTypeDefinitionNode:
return $this->makeScalarDef($def); return $this->makeScalarDef($def);
case NodeKind::INPUT_OBJECT_TYPE_DEFINITION: case $def instanceof InputObjectTypeDefinitionNode:
return $this->makeInputObjectDef($def); return $this->makeInputObjectDef($def);
default: default:
throw new Error(sprintf('Type kind of %s not supported.', $def->kind)); throw new Error(sprintf('Type kind of %s not supported.', $def->kind));
@ -431,62 +427,48 @@ class ASTDefinitionBuilder
} }
/** /**
* @param ObjectTypeDefinitionNode|InterfaceTypeDefinitionNode|EnumTypeExtensionNode|ScalarTypeDefinitionNode|InputObjectTypeDefinitionNode $def
* @param mixed[] $config * @param mixed[] $config
* *
* @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType * @return CustomScalarType|EnumType|InputObjectType|InterfaceType|ObjectType|UnionType
* *
* @throws Error * @throws Error
*/ */
private function makeSchemaDefFromConfig($def, array $config) private function makeSchemaDefFromConfig(Node $def, array $config)
{ {
if (! $def) { switch (true) {
throw new Error('def must be defined.'); case $def instanceof ObjectTypeDefinitionNode:
}
switch ($def->kind) {
case NodeKind::OBJECT_TYPE_DEFINITION:
return new ObjectType($config); return new ObjectType($config);
case NodeKind::INTERFACE_TYPE_DEFINITION: case $def instanceof InterfaceTypeDefinitionNode:
return new InterfaceType($config); return new InterfaceType($config);
case NodeKind::ENUM_TYPE_DEFINITION: case $def instanceof EnumTypeDefinitionNode:
return new EnumType($config); return new EnumType($config);
case NodeKind::UNION_TYPE_DEFINITION: case $def instanceof UnionTypeDefinitionNode:
return new UnionType($config); return new UnionType($config);
case NodeKind::SCALAR_TYPE_DEFINITION: case $def instanceof ScalarTypeDefinitionNode:
return new CustomScalarType($config); return new CustomScalarType($config);
case NodeKind::INPUT_OBJECT_TYPE_DEFINITION: case $def instanceof InputObjectTypeDefinitionNode:
return new InputObjectType($config); return new InputObjectType($config);
default: default:
throw new Error(sprintf('Type kind of %s not supported.', $def->kind)); throw new Error(sprintf('Type kind of %s not supported.', $def->kind));
} }
} }
/** private function getNamedTypeNode(TypeNode $typeNode) : TypeNode
* @param TypeNode|ListTypeNode|NonNullTypeNode $typeNode
*
* @return TypeNode
*/
private function getNamedTypeNode(TypeNode $typeNode)
{ {
$namedType = $typeNode; $namedType = $typeNode;
while ($namedType->kind === NodeKind::LIST_TYPE || $namedType->kind === NodeKind::NON_NULL_TYPE) { while ($namedType instanceof ListTypeNode || $namedType instanceof NonNullTypeNode) {
$namedType = $namedType->type; $namedType = $namedType->type;
} }
return $namedType; return $namedType;
} }
/** private function buildWrappedType(Type $innerType, TypeNode $inputTypeNode) : Type
* @param TypeNode|ListTypeNode|NonNullTypeNode $inputTypeNode
*
* @return Type
*/
private function buildWrappedType(Type $innerType, TypeNode $inputTypeNode)
{ {
if ($inputTypeNode->kind === NodeKind::LIST_TYPE) { if ($inputTypeNode instanceof ListTypeNode) {
return Type::listOf($this->buildWrappedType($innerType, $inputTypeNode->type)); return Type::listOf($this->buildWrappedType($innerType, $inputTypeNode->type));
} }
if ($inputTypeNode->kind === NodeKind::NON_NULL_TYPE) { if ($inputTypeNode instanceof NonNullTypeNode) {
$wrappedType = $this->buildWrappedType($innerType, $inputTypeNode->type); $wrappedType = $this->buildWrappedType($innerType, $inputTypeNode->type);
return Type::nonNull(NonNull::assertNullableType($wrappedType)); return Type::nonNull(NonNull::assertNullableType($wrappedType));

View File

@ -5,10 +5,16 @@ declare(strict_types=1);
namespace GraphQL\Utils; namespace GraphQL\Utils;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Language\AST\DirectiveDefinitionNode;
use GraphQL\Language\AST\DocumentNode; use GraphQL\Language\AST\DocumentNode;
use GraphQL\Language\AST\EnumTypeDefinitionNode;
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
use GraphQL\Language\AST\SchemaDefinitionNode; use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\UnionTypeDefinitionNode;
use GraphQL\Language\Parser; use GraphQL\Language\Parser;
use GraphQL\Language\Source; use GraphQL\Language\Source;
use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\Directive;
@ -95,39 +101,38 @@ class BuildSchema
public function buildSchema() public function buildSchema()
{ {
/** @var SchemaDefinitionNode $schemaDef */
$schemaDef = null; $schemaDef = null;
$typeDefs = []; $typeDefs = [];
$this->nodeMap = []; $this->nodeMap = [];
$directiveDefs = []; $directiveDefs = [];
foreach ($this->ast->definitions as $d) { foreach ($this->ast->definitions as $definition) {
switch ($d->kind) { switch (true) {
case NodeKind::SCHEMA_DEFINITION: case $definition instanceof SchemaDefinitionNode:
if ($schemaDef) { if ($schemaDef !== null) {
throw new Error('Must provide only one schema definition.'); throw new Error('Must provide only one schema definition.');
} }
$schemaDef = $d; $schemaDef = $definition;
break; break;
case NodeKind::SCALAR_TYPE_DEFINITION: case $definition instanceof ScalarTypeDefinitionNode:
case NodeKind::OBJECT_TYPE_DEFINITION: case $definition instanceof ObjectTypeDefinitionNode:
case NodeKind::INTERFACE_TYPE_DEFINITION: case $definition instanceof InterfaceTypeDefinitionNode:
case NodeKind::ENUM_TYPE_DEFINITION: case $definition instanceof EnumTypeDefinitionNode:
case NodeKind::UNION_TYPE_DEFINITION: case $definition instanceof UnionTypeDefinitionNode:
case NodeKind::INPUT_OBJECT_TYPE_DEFINITION: case $definition instanceof InputObjectTypeDefinitionNode:
$typeName = $d->name->value; $typeName = $definition->name->value;
if (! empty($this->nodeMap[$typeName])) { if (! empty($this->nodeMap[$typeName])) {
throw new Error(sprintf('Type "%s" was defined more than once.', $typeName)); throw new Error(sprintf('Type "%s" was defined more than once.', $typeName));
} }
$typeDefs[] = $d; $typeDefs[] = $definition;
$this->nodeMap[$typeName] = $d; $this->nodeMap[$typeName] = $definition;
break; break;
case NodeKind::DIRECTIVE_DEFINITION: case $definition instanceof DirectiveDefinitionNode:
$directiveDefs[] = $d; $directiveDefs[] = $definition;
break; break;
} }
} }
$operationTypes = $schemaDef $operationTypes = $schemaDef !== null
? $this->getOperationTypes($schemaDef) ? $this->getOperationTypes($schemaDef)
: [ : [
'query' => isset($this->nodeMap['Query']) ? 'Query' : null, 'query' => isset($this->nodeMap['Query']) ? 'Query' : null,

View File

@ -7,13 +7,16 @@ namespace GraphQL\Utils;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Language\AST\DirectiveDefinitionNode; use GraphQL\Language\AST\DirectiveDefinitionNode;
use GraphQL\Language\AST\DocumentNode; use GraphQL\Language\AST\DocumentNode;
use GraphQL\Language\AST\EnumTypeExtensionNode;
use GraphQL\Language\AST\InputObjectTypeExtensionNode;
use GraphQL\Language\AST\InterfaceTypeExtensionNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\ObjectTypeExtensionNode; use GraphQL\Language\AST\ObjectTypeExtensionNode;
use GraphQL\Language\AST\SchemaDefinitionNode; use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\SchemaTypeExtensionNode; use GraphQL\Language\AST\SchemaTypeExtensionNode;
use GraphQL\Language\AST\TypeDefinitionNode; use GraphQL\Language\AST\TypeDefinitionNode;
use GraphQL\Language\AST\TypeExtensionNode; use GraphQL\Language\AST\TypeExtensionNode;
use GraphQL\Language\AST\UnionTypeExtensionNode;
use GraphQL\Type\Definition\CustomScalarType; use GraphQL\Type\Definition\CustomScalarType;
use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumType;
@ -75,8 +78,8 @@ class SchemaExtender
*/ */
protected static function checkExtensionNode(Type $type, Node $node) : void protected static function checkExtensionNode(Type $type, Node $node) : void
{ {
switch ($node->kind) { switch (true) {
case NodeKind::OBJECT_TYPE_EXTENSION: case $node instanceof ObjectTypeExtensionNode:
if (! ($type instanceof ObjectType)) { if (! ($type instanceof ObjectType)) {
throw new Error( throw new Error(
'Cannot extend non-object type "' . $type->name . '".', 'Cannot extend non-object type "' . $type->name . '".',
@ -84,7 +87,7 @@ class SchemaExtender
); );
} }
break; break;
case NodeKind::INTERFACE_TYPE_EXTENSION: case $node instanceof InterfaceTypeExtensionNode:
if (! ($type instanceof InterfaceType)) { if (! ($type instanceof InterfaceType)) {
throw new Error( throw new Error(
'Cannot extend non-interface type "' . $type->name . '".', 'Cannot extend non-interface type "' . $type->name . '".',
@ -92,7 +95,7 @@ class SchemaExtender
); );
} }
break; break;
case NodeKind::ENUM_TYPE_EXTENSION: case $node instanceof EnumTypeExtensionNode:
if (! ($type instanceof EnumType)) { if (! ($type instanceof EnumType)) {
throw new Error( throw new Error(
'Cannot extend non-enum type "' . $type->name . '".', 'Cannot extend non-enum type "' . $type->name . '".',
@ -100,7 +103,7 @@ class SchemaExtender
); );
} }
break; break;
case NodeKind::UNION_TYPE_EXTENSION: case $node instanceof UnionTypeExtensionNode:
if (! ($type instanceof UnionType)) { if (! ($type instanceof UnionType)) {
throw new Error( throw new Error(
'Cannot extend non-union type "' . $type->name . '".', 'Cannot extend non-union type "' . $type->name . '".',
@ -108,7 +111,7 @@ class SchemaExtender
); );
} }
break; break;
case NodeKind::INPUT_OBJECT_TYPE_EXTENSION: case $node instanceof InputObjectTypeExtensionNode:
if (! ($type instanceof InputObjectType)) { if (! ($type instanceof InputObjectType)) {
throw new Error( throw new Error(
'Cannot extend non-input object type "' . $type->name . '".', 'Cannot extend non-input object type "' . $type->name . '".',

View File

@ -6,12 +6,21 @@ namespace GraphQL\Utils;
use GraphQL\Error\InvariantViolation; use GraphQL\Error\InvariantViolation;
use GraphQL\Error\Warning; use GraphQL\Error\Warning;
use GraphQL\Language\AST\ArgumentNode;
use GraphQL\Language\AST\DirectiveNode;
use GraphQL\Language\AST\EnumValueNode;
use GraphQL\Language\AST\FieldNode; use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\FragmentDefinitionNode;
use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\ListTypeNode; use GraphQL\Language\AST\ListTypeNode;
use GraphQL\Language\AST\ListValueNode;
use GraphQL\Language\AST\NamedTypeNode; use GraphQL\Language\AST\NamedTypeNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\NonNullTypeNode; use GraphQL\Language\AST\NonNullTypeNode;
use GraphQL\Language\AST\ObjectFieldNode;
use GraphQL\Language\AST\OperationDefinitionNode;
use GraphQL\Language\AST\SelectionSetNode;
use GraphQL\Language\AST\VariableDefinitionNode;
use GraphQL\Type\Definition\CompositeType; use GraphQL\Type\Definition\CompositeType;
use GraphQL\Type\Definition\Directive; use GraphQL\Type\Definition\Directive;
use GraphQL\Type\Definition\EnumType; use GraphQL\Type\Definition\EnumType;
@ -254,13 +263,13 @@ class TypeInfo
// any assumptions of a valid schema to ensure runtime types are properly // any assumptions of a valid schema to ensure runtime types are properly
// checked before continuing since TypeInfo is used as part of validation // checked before continuing since TypeInfo is used as part of validation
// which occurs before guarantees of schema and document validity. // which occurs before guarantees of schema and document validity.
switch ($node->kind) { switch (true) {
case NodeKind::SELECTION_SET: case $node instanceof SelectionSetNode:
$namedType = Type::getNamedType($this->getType()); $namedType = Type::getNamedType($this->getType());
$this->parentTypeStack[] = Type::isCompositeType($namedType) ? $namedType : null; $this->parentTypeStack[] = Type::isCompositeType($namedType) ? $namedType : null;
break; break;
case NodeKind::FIELD: case $node instanceof FieldNode:
$parentType = $this->getParentType(); $parentType = $this->getParentType();
$fieldDef = null; $fieldDef = null;
if ($parentType) { if ($parentType) {
@ -274,11 +283,11 @@ class TypeInfo
$this->typeStack[] = Type::isOutputType($fieldType) ? $fieldType : null; $this->typeStack[] = Type::isOutputType($fieldType) ? $fieldType : null;
break; break;
case NodeKind::DIRECTIVE: case $node instanceof DirectiveNode:
$this->directive = $schema->getDirective($node->name->value); $this->directive = $schema->getDirective($node->name->value);
break; break;
case NodeKind::OPERATION_DEFINITION: case $node instanceof OperationDefinitionNode:
$type = null; $type = null;
if ($node->operation === 'query') { if ($node->operation === 'query') {
$type = $schema->getQueryType(); $type = $schema->getQueryType();
@ -290,8 +299,8 @@ class TypeInfo
$this->typeStack[] = Type::isOutputType($type) ? $type : null; $this->typeStack[] = Type::isOutputType($type) ? $type : null;
break; break;
case NodeKind::INLINE_FRAGMENT: case $node instanceof InlineFragmentNode:
case NodeKind::FRAGMENT_DEFINITION: case $node instanceof FragmentDefinitionNode:
$typeConditionNode = $node->typeCondition; $typeConditionNode = $node->typeCondition;
$outputType = $typeConditionNode ? self::typeFromAST( $outputType = $typeConditionNode ? self::typeFromAST(
$schema, $schema,
@ -300,12 +309,12 @@ class TypeInfo
$this->typeStack[] = Type::isOutputType($outputType) ? $outputType : null; $this->typeStack[] = Type::isOutputType($outputType) ? $outputType : null;
break; break;
case NodeKind::VARIABLE_DEFINITION: case $node instanceof VariableDefinitionNode:
$inputType = self::typeFromAST($schema, $node->type); $inputType = self::typeFromAST($schema, $node->type);
$this->inputTypeStack[] = Type::isInputType($inputType) ? $inputType : null; // push $this->inputTypeStack[] = Type::isInputType($inputType) ? $inputType : null; // push
break; break;
case NodeKind::ARGUMENT: case $node instanceof ArgumentNode:
$fieldOrDirective = $this->getDirective() ?: $this->getFieldDef(); $fieldOrDirective = $this->getDirective() ?: $this->getFieldDef();
$argDef = $argType = null; $argDef = $argType = null;
if ($fieldOrDirective) { if ($fieldOrDirective) {
@ -323,7 +332,7 @@ class TypeInfo
$this->inputTypeStack[] = Type::isInputType($argType) ? $argType : null; $this->inputTypeStack[] = Type::isInputType($argType) ? $argType : null;
break; break;
case NodeKind::LST: case $node instanceof ListValueNode:
$listType = Type::getNullableType($this->getInputType()); $listType = Type::getNullableType($this->getInputType());
$itemType = $listType instanceof ListOfType $itemType = $listType instanceof ListOfType
? $listType->getWrappedType() ? $listType->getWrappedType()
@ -331,7 +340,7 @@ class TypeInfo
$this->inputTypeStack[] = Type::isInputType($itemType) ? $itemType : null; $this->inputTypeStack[] = Type::isInputType($itemType) ? $itemType : null;
break; break;
case NodeKind::OBJECT_FIELD: case $node instanceof ObjectFieldNode:
$objectType = Type::getNamedType($this->getInputType()); $objectType = Type::getNamedType($this->getInputType());
$fieldType = null; $fieldType = null;
$inputFieldType = null; $inputFieldType = null;
@ -343,7 +352,7 @@ class TypeInfo
$this->inputTypeStack[] = Type::isInputType($inputFieldType) ? $inputFieldType : null; $this->inputTypeStack[] = Type::isInputType($inputFieldType) ? $inputFieldType : null;
break; break;
case NodeKind::ENUM: case $node instanceof EnumValueNode:
$enumType = Type::getNamedType($this->getInputType()); $enumType = Type::getNamedType($this->getInputType());
$enumValue = null; $enumValue = null;
if ($enumType instanceof EnumType) { if ($enumType instanceof EnumType) {
@ -457,37 +466,37 @@ class TypeInfo
public function leave(Node $node) public function leave(Node $node)
{ {
switch ($node->kind) { switch (true) {
case NodeKind::SELECTION_SET: case $node instanceof SelectionSetNode:
array_pop($this->parentTypeStack); array_pop($this->parentTypeStack);
break; break;
case NodeKind::FIELD: case $node instanceof FieldNode:
array_pop($this->fieldDefStack); array_pop($this->fieldDefStack);
array_pop($this->typeStack); array_pop($this->typeStack);
break; break;
case NodeKind::DIRECTIVE: case $node instanceof DirectiveNode:
$this->directive = null; $this->directive = null;
break; break;
case NodeKind::OPERATION_DEFINITION: case $node instanceof OperationDefinitionNode:
case NodeKind::INLINE_FRAGMENT: case $node instanceof InlineFragmentNode:
case NodeKind::FRAGMENT_DEFINITION: case $node instanceof FragmentDefinitionNode:
array_pop($this->typeStack); array_pop($this->typeStack);
break; break;
case NodeKind::VARIABLE_DEFINITION: case $node instanceof VariableDefinitionNode:
array_pop($this->inputTypeStack); array_pop($this->inputTypeStack);
break; break;
case NodeKind::ARGUMENT: case $node instanceof ArgumentNode:
$this->argument = null; $this->argument = null;
array_pop($this->inputTypeStack); array_pop($this->inputTypeStack);
break; break;
case NodeKind::LST: case $node instanceof ListValueNode:
case NodeKind::OBJECT_FIELD: case $node instanceof ObjectFieldNode:
array_pop($this->inputTypeStack); array_pop($this->inputTypeStack);
break; break;
case NodeKind::ENUM: case $node instanceof EnumValueNode:
$this->enumValue = null; $this->enumValue = null;
break; break;
} }

View File

@ -6,6 +6,8 @@ namespace GraphQL\Validator\Rules;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Language\AST\ArgumentNode; use GraphQL\Language\AST\ArgumentNode;
use GraphQL\Language\AST\DirectiveNode;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\NodeList; use GraphQL\Language\AST\NodeList;
@ -34,7 +36,7 @@ class KnownArgumentNames extends ValidationRule
} }
$argumentOf = $ancestors[count($ancestors) - 1]; $argumentOf = $ancestors[count($ancestors) - 1];
if ($argumentOf->kind === NodeKind::FIELD) { if ($argumentOf instanceof FieldNode) {
$fieldDef = $context->getFieldDef(); $fieldDef = $context->getFieldDef();
$parentType = $context->getParentType(); $parentType = $context->getParentType();
if ($fieldDef && $parentType) { if ($fieldDef && $parentType) {
@ -56,7 +58,7 @@ class KnownArgumentNames extends ValidationRule
[$node] [$node]
)); ));
} }
} elseif ($argumentOf->kind === NodeKind::DIRECTIVE) { } elseif ($argumentOf instanceof DirectiveNode) {
$directive = $context->getDirective(); $directive = $context->getDirective();
if ($directive) { if ($directive) {
$context->reportError(new Error( $context->reportError(new Error(

View File

@ -7,10 +7,31 @@ namespace GraphQL\Validator\Rules;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Language\AST\DirectiveDefinitionNode; use GraphQL\Language\AST\DirectiveDefinitionNode;
use GraphQL\Language\AST\DirectiveNode; use GraphQL\Language\AST\DirectiveNode;
use GraphQL\Language\AST\EnumTypeDefinitionNode;
use GraphQL\Language\AST\EnumTypeExtensionNode;
use GraphQL\Language\AST\EnumValueDefinitionNode;
use GraphQL\Language\AST\FieldDefinitionNode;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\FragmentDefinitionNode;
use GraphQL\Language\AST\FragmentSpreadNode;
use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\InputObjectTypeDefinitionNode; use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
use GraphQL\Language\AST\InputObjectTypeExtensionNode;
use GraphQL\Language\AST\InputValueDefinitionNode;
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
use GraphQL\Language\AST\InterfaceTypeExtensionNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\NodeList; use GraphQL\Language\AST\NodeList;
use GraphQL\Language\AST\ObjectTypeDefinitionNode;
use GraphQL\Language\AST\ObjectTypeExtensionNode;
use GraphQL\Language\AST\OperationDefinitionNode;
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
use GraphQL\Language\AST\ScalarTypeExtensionNode;
use GraphQL\Language\AST\SchemaDefinitionNode;
use GraphQL\Language\AST\SchemaTypeExtensionNode;
use GraphQL\Language\AST\UnionTypeDefinitionNode;
use GraphQL\Language\AST\UnionTypeExtensionNode;
use GraphQL\Language\DirectiveLocation; use GraphQL\Language\DirectiveLocation;
use GraphQL\Validator\ValidationContext; use GraphQL\Validator\ValidationContext;
use function array_map; use function array_map;
@ -96,8 +117,8 @@ class KnownDirectives extends ValidationRule
private function getDirectiveLocationForASTPath(array $ancestors) private function getDirectiveLocationForASTPath(array $ancestors)
{ {
$appliedTo = $ancestors[count($ancestors) - 1]; $appliedTo = $ancestors[count($ancestors) - 1];
switch ($appliedTo->kind) { switch (true) {
case NodeKind::OPERATION_DEFINITION: case $appliedTo instanceof OperationDefinitionNode:
switch ($appliedTo->operation) { switch ($appliedTo->operation) {
case 'query': case 'query':
return DirectiveLocation::QUERY; return DirectiveLocation::QUERY;
@ -107,40 +128,40 @@ class KnownDirectives extends ValidationRule
return DirectiveLocation::SUBSCRIPTION; return DirectiveLocation::SUBSCRIPTION;
} }
break; break;
case NodeKind::FIELD: case $appliedTo instanceof FieldNode:
return DirectiveLocation::FIELD; return DirectiveLocation::FIELD;
case NodeKind::FRAGMENT_SPREAD: case $appliedTo instanceof FragmentSpreadNode:
return DirectiveLocation::FRAGMENT_SPREAD; return DirectiveLocation::FRAGMENT_SPREAD;
case NodeKind::INLINE_FRAGMENT: case $appliedTo instanceof InlineFragmentNode:
return DirectiveLocation::INLINE_FRAGMENT; return DirectiveLocation::INLINE_FRAGMENT;
case NodeKind::FRAGMENT_DEFINITION: case $appliedTo instanceof FragmentDefinitionNode:
return DirectiveLocation::FRAGMENT_DEFINITION; return DirectiveLocation::FRAGMENT_DEFINITION;
case NodeKind::SCHEMA_DEFINITION: case $appliedTo instanceof SchemaDefinitionNode:
case NodeKind::SCHEMA_EXTENSION: case $appliedTo instanceof SchemaTypeExtensionNode:
return DirectiveLocation::SCHEMA; return DirectiveLocation::SCHEMA;
case NodeKind::SCALAR_TYPE_DEFINITION: case $appliedTo instanceof ScalarTypeDefinitionNode:
case NodeKind::SCALAR_TYPE_EXTENSION: case $appliedTo instanceof ScalarTypeExtensionNode:
return DirectiveLocation::SCALAR; return DirectiveLocation::SCALAR;
case NodeKind::OBJECT_TYPE_DEFINITION: case $appliedTo instanceof ObjectTypeDefinitionNode:
case NodeKind::OBJECT_TYPE_EXTENSION: case $appliedTo instanceof ObjectTypeExtensionNode:
return DirectiveLocation::OBJECT; return DirectiveLocation::OBJECT;
case NodeKind::FIELD_DEFINITION: case $appliedTo instanceof FieldDefinitionNode:
return DirectiveLocation::FIELD_DEFINITION; return DirectiveLocation::FIELD_DEFINITION;
case NodeKind::INTERFACE_TYPE_DEFINITION: case $appliedTo instanceof InterfaceTypeDefinitionNode:
case NodeKind::INTERFACE_TYPE_EXTENSION: case $appliedTo instanceof InterfaceTypeExtensionNode:
return DirectiveLocation::IFACE; return DirectiveLocation::IFACE;
case NodeKind::UNION_TYPE_DEFINITION: case $appliedTo instanceof UnionTypeDefinitionNode:
case NodeKind::UNION_TYPE_EXTENSION: case $appliedTo instanceof UnionTypeExtensionNode:
return DirectiveLocation::UNION; return DirectiveLocation::UNION;
case NodeKind::ENUM_TYPE_DEFINITION: case $appliedTo instanceof EnumTypeDefinitionNode:
case NodeKind::ENUM_TYPE_EXTENSION: case $appliedTo instanceof EnumTypeExtensionNode:
return DirectiveLocation::ENUM; return DirectiveLocation::ENUM;
case NodeKind::ENUM_VALUE_DEFINITION: case $appliedTo instanceof EnumValueDefinitionNode:
return DirectiveLocation::ENUM_VALUE; return DirectiveLocation::ENUM_VALUE;
case NodeKind::INPUT_OBJECT_TYPE_DEFINITION: case $appliedTo instanceof InputObjectTypeDefinitionNode:
case NodeKind::INPUT_OBJECT_TYPE_EXTENSION: case $appliedTo instanceof InputObjectTypeExtensionNode:
return DirectiveLocation::INPUT_OBJECT; return DirectiveLocation::INPUT_OBJECT;
case NodeKind::INPUT_VALUE_DEFINITION: case $appliedTo instanceof InputValueDefinitionNode:
$parentNode = $ancestors[count($ancestors) - 3]; $parentNode = $ancestors[count($ancestors) - 3];
return $parentNode instanceof InputObjectTypeDefinitionNode return $parentNode instanceof InputObjectTypeDefinitionNode

View File

@ -30,7 +30,7 @@ class LoneAnonymousOperation extends ValidationRule
$tmp = Utils::filter( $tmp = Utils::filter(
$node->definitions, $node->definitions,
static function (Node $definition) { static function (Node $definition) {
return $definition->kind === NodeKind::OPERATION_DEFINITION; return $definition instanceof OperationDefinitionNode;
} }
); );

View File

@ -110,9 +110,8 @@ class QueryComplexity extends QuerySecurityRule
private function nodeComplexity(Node $node, $complexity = 0) private function nodeComplexity(Node $node, $complexity = 0)
{ {
switch ($node->kind) { switch (true) {
case NodeKind::FIELD: case $node instanceof FieldNode:
/** @var FieldNode $node */
// default values // default values
$args = []; $args = [];
$complexityFn = FieldDefinition::DEFAULT_COMPLEXITY_FN; $complexityFn = FieldDefinition::DEFAULT_COMPLEXITY_FN;
@ -143,16 +142,14 @@ class QueryComplexity extends QuerySecurityRule
$complexity += call_user_func_array($complexityFn, [$childrenComplexity, $args]); $complexity += call_user_func_array($complexityFn, [$childrenComplexity, $args]);
break; break;
case NodeKind::INLINE_FRAGMENT: case $node instanceof InlineFragmentNode:
/** @var InlineFragmentNode $node */
// node has children? // node has children?
if (isset($node->selectionSet)) { if (isset($node->selectionSet)) {
$complexity = $this->fieldComplexity($node, $complexity); $complexity = $this->fieldComplexity($node, $complexity);
} }
break; break;
case NodeKind::FRAGMENT_SPREAD: case $node instanceof FragmentSpreadNode:
/** @var FragmentSpreadNode $node */
$fragment = $this->getFragment($node); $fragment = $this->getFragment($node);
if ($fragment !== null) { if ($fragment !== null) {

View File

@ -5,6 +5,9 @@ declare(strict_types=1);
namespace GraphQL\Validator\Rules; namespace GraphQL\Validator\Rules;
use GraphQL\Error\Error; use GraphQL\Error\Error;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\FragmentSpreadNode;
use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\Node; use GraphQL\Language\AST\Node;
use GraphQL\Language\AST\NodeKind; use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\OperationDefinitionNode; use GraphQL\Language\AST\OperationDefinitionNode;
@ -57,9 +60,8 @@ class QueryDepth extends QuerySecurityRule
private function nodeDepth(Node $node, $depth = 0, $maxDepth = 0) private function nodeDepth(Node $node, $depth = 0, $maxDepth = 0)
{ {
switch ($node->kind) { switch (true) {
case NodeKind::FIELD: case $node instanceof FieldNode:
/** @var FieldNode $node */
// node has children? // node has children?
if ($node->selectionSet !== null) { if ($node->selectionSet !== null) {
// update maxDepth if needed // update maxDepth if needed
@ -70,16 +72,14 @@ class QueryDepth extends QuerySecurityRule
} }
break; break;
case NodeKind::INLINE_FRAGMENT: case $node instanceof InlineFragmentNode:
/** @var InlineFragmentNode $node */
// node has children? // node has children?
if ($node->selectionSet !== null) { if ($node->selectionSet !== null) {
$maxDepth = $this->fieldDepth($node, $depth, $maxDepth); $maxDepth = $this->fieldDepth($node, $depth, $maxDepth);
} }
break; break;
case NodeKind::FRAGMENT_SPREAD: case $node instanceof FragmentSpreadNode:
/** @var FragmentSpreadNode $node */
$fragment = $this->getFragment($node); $fragment = $this->getFragment($node);
if ($fragment !== null) { if ($fragment !== null) {

View File

@ -9,7 +9,6 @@ use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\FragmentDefinitionNode; use GraphQL\Language\AST\FragmentDefinitionNode;
use GraphQL\Language\AST\FragmentSpreadNode; use GraphQL\Language\AST\FragmentSpreadNode;
use GraphQL\Language\AST\InlineFragmentNode; use GraphQL\Language\AST\InlineFragmentNode;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Language\AST\SelectionSetNode; use GraphQL\Language\AST\SelectionSetNode;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
use GraphQL\Type\Introspection; use GraphQL\Type\Introspection;
@ -114,8 +113,8 @@ abstract class QuerySecurityRule extends ValidationRule
$_astAndDefs = $astAndDefs ?: new ArrayObject(); $_astAndDefs = $astAndDefs ?: new ArrayObject();
foreach ($selectionSet->selections as $selection) { foreach ($selectionSet->selections as $selection) {
switch ($selection->kind) { switch (true) {
case NodeKind::FIELD: case $selection instanceof FieldNode:
/** @var FieldNode $selection */ /** @var FieldNode $selection */
$fieldName = $selection->name->value; $fieldName = $selection->name->value;
$fieldDef = null; $fieldDef = null;
@ -142,7 +141,7 @@ abstract class QuerySecurityRule extends ValidationRule
// create field context // create field context
$_astAndDefs[$responseName][] = [$selection, $fieldDef]; $_astAndDefs[$responseName][] = [$selection, $fieldDef];
break; break;
case NodeKind::INLINE_FRAGMENT: case $selection instanceof InlineFragmentNode:
/** @var InlineFragmentNode $selection */ /** @var InlineFragmentNode $selection */
$_astAndDefs = $this->collectFieldASTsAndDefs( $_astAndDefs = $this->collectFieldASTsAndDefs(
$context, $context,
@ -152,7 +151,7 @@ abstract class QuerySecurityRule extends ValidationRule
$_astAndDefs $_astAndDefs
); );
break; break;
case NodeKind::FRAGMENT_SPREAD: case $selection instanceof FragmentSpreadNode:
/** @var FragmentSpreadNode $selection */ /** @var FragmentSpreadNode $selection */
$fragName = $selection->name->value; $fragName = $selection->name->value;

View File

@ -199,7 +199,7 @@ class ValidationContext
for ($i = 0, $selectionCount = count($set->selections); $i < $selectionCount; $i++) { for ($i = 0, $selectionCount = count($set->selections); $i < $selectionCount; $i++) {
$selection = $set->selections[$i]; $selection = $set->selections[$i];
if ($selection->kind === NodeKind::FRAGMENT_SPREAD) { if ($selection instanceof FragmentSpreadNode) {
$spreads[] = $selection; $spreads[] = $selection;
} elseif ($selection->selectionSet) { } elseif ($selection->selectionSet) {
$setsToVisit[] = $selection->selectionSet; $setsToVisit[] = $selection->selectionSet;
@ -223,7 +223,7 @@ class ValidationContext
if (! $fragments) { if (! $fragments) {
$fragments = []; $fragments = [];
foreach ($this->getDocument()->definitions as $statement) { foreach ($this->getDocument()->definitions as $statement) {
if ($statement->kind !== NodeKind::FRAGMENT_DEFINITION) { if (! ($statement instanceof FragmentDefinitionNode)) {
continue; continue;
} }

View File

@ -362,7 +362,7 @@ class CollectorTest extends TestCase
$operationName = null; $operationName = null;
foreach ($documentNode->definitions as $definitionNode) { foreach ($documentNode->definitions as $definitionNode) {
/** @var Node $definitionNode */ /** @var Node $definitionNode */
if ($definitionNode->kind === NodeKind::OPERATION_DEFINITION) { if ($definitionNode instanceof OperationDefinitionNode) {
/** @var OperationDefinitionNode $definitionNode */ /** @var OperationDefinitionNode $definitionNode */
self::assertNotNull($definitionNode->name); self::assertNotNull($definitionNode->name);
$operationName = $definitionNode->name->value; $operationName = $definitionNode->name->value;

View File

@ -384,7 +384,7 @@ class VisitorTest extends ValidatorTestCase
$this->checkVisitorFnArgs($ast, func_get_args()); $this->checkVisitorFnArgs($ast, func_get_args());
$visited[] = ['leave', $node->kind, $node->value ?? null]; $visited[] = ['leave', $node->kind, $node->value ?? null];
if ($node->kind === NodeKind::NAME && $node->value === 'x') { if ($node instanceof NameNode && $node->value === 'x') {
return Visitor::stop(); return Visitor::stop();
} }
}, },