public function __invoke(ValidationContext $context) { return [Node::INLINE_FRAGMENT => function (InlineFragment $node) use($context) { $fragType = Type::getUnmodifiedType($context->getType()); $parentType = $context->getParentType(); if ($fragType && $parentType && !$this->doTypesOverlap($fragType, $parentType)) { return new Error(Messages::typeIncompatibleAnonSpreadMessage($parentType, $fragType), [$node]); } }, Node::FRAGMENT_SPREAD => function (FragmentSpread $node) use($context) { $fragName = $node->name->value; $fragType = Type::getUnmodifiedType($this->getFragmentType($context, $fragName)); $parentType = $context->getParentType(); if ($fragType && $parentType && !$this->doTypesOverlap($fragType, $parentType)) { return new Error(Messages::typeIncompatibleSpreadMessage($fragName, $parentType, $fragType), [$node]); } }]; }
function enter(Node $node) { $schema = $this->_schema; switch ($node->kind) { case Node::SELECTION_SET: // var $compositeType: ?GraphQLCompositeType; $rawType = Type::getUnmodifiedType($this->getType()); $compositeType = null; if (Type::isCompositeType($rawType)) { // isCompositeType is a type refining predicate, so this is safe. $compositeType = $rawType; } array_push($this->_parentTypeStack, $compositeType); break; case Node::FIELD: $parentType = $this->getParentType(); $fieldDef = null; if ($parentType) { $fieldDef = self::_getFieldDef($schema, $parentType, $node); } array_push($this->_fieldDefStack, $fieldDef); array_push($this->_typeStack, $fieldDef ? $fieldDef->getType() : null); break; case Node::OPERATION_DEFINITION: $type = null; if ($node->operation === 'query') { $type = $schema->getQueryType(); } else { if ($node->operation === 'mutation') { $type = $schema->getMutationType(); } } array_push($this->_typeStack, $type); break; case Node::INLINE_FRAGMENT: case Node::FRAGMENT_DEFINITION: $type = $schema->getType($node->typeCondition->value); array_push($this->_typeStack, $type); break; case Node::VARIABLE_DEFINITION: array_push($this->_inputTypeStack, self::typeFromAST($schema, $node->type)); break; case Node::ARGUMENT: $field = $this->getFieldDef(); $argType = null; if ($field) { $argDef = Utils::find($field->args, function ($arg) use($node) { return $arg->name === $node->name->value; }); if ($argDef) { $argType = $argDef->getType(); } } array_push($this->_inputTypeStack, $argType); break; case Node::DIRECTIVE: $directive = $schema->getDirective($node->name->value); array_push($this->_inputTypeStack, $directive ? $directive->type : null); break; case Node::ARR: $arrayType = Type::getNullableType($this->getInputType()); array_push($this->_inputTypeStack, $arrayType instanceof ListOfType ? $arrayType->getWrappedType() : null); break; case Node::OBJECT_FIELD: $objectType = Type::getUnmodifiedType($this->getInputType()); $fieldType = null; if ($objectType instanceof InputObjectType) { $tmp = $objectType->getFields(); $inputField = isset($tmp[$node->name->value]) ? $tmp[$node->name->value] : null; $fieldType = $inputField ? $inputField->getType() : null; } array_push($this->_inputTypeStack, $fieldType); break; } }