/**
* @param Node $node
*/
function enter(Node $node)
{
$schema = $this->schema;
switch ($node->kind) {
case Node::SELECTION_SET:
$namedType = Type::getNamedType($this->getType());
$compositeType = null;
if (Type::isCompositeType($namedType)) {
// isCompositeType is a type refining predicate, so this is safe.
$compositeType = $namedType;
}
$this->parentTypeStack[] = $compositeType;
// push
break;
case Node::FIELD:
$parentType = $this->getParentType();
$fieldDef = null;
if ($parentType) {
$fieldDef = self::getFieldDefinition($schema, $parentType, $node);
}
$this->fieldDefStack[] = $fieldDef;
// push
$this->typeStack[] = $fieldDef ? $fieldDef->getType() : null;
// push
break;
case Node::DIRECTIVE:
$this->directive = $schema->getDirective($node->name->value);
break;
case Node::OPERATION_DEFINITION:
$type = null;
if ($node->operation === 'query') {
$type = $schema->getQueryType();
} else {
if ($node->operation === 'mutation') {
$type = $schema->getMutationType();
} else {
if ($node->operation === 'subscription') {
$type = $schema->getSubscriptionType();
}
}
}
$this->typeStack[] = $type;
// push
break;
case Node::INLINE_FRAGMENT:
case Node::FRAGMENT_DEFINITION:
$typeConditionAST = $node->typeCondition;
$outputType = $typeConditionAST ? self::typeFromAST($schema, $typeConditionAST) : $this->getType();
$this->typeStack[] = $outputType;
// push
break;
case Node::VARIABLE_DEFINITION:
$inputType = self::typeFromAST($schema, $node->type);
$this->inputTypeStack[] = $inputType;
// push
break;
case Node::ARGUMENT:
$fieldOrDirective = $this->getDirective() ?: $this->getFieldDef();
$argDef = $argType = null;
if ($fieldOrDirective) {
$argDef = Utils::find($fieldOrDirective->args, function ($arg) use($node) {
return $arg->name === $node->name->value;
});
if ($argDef) {
$argType = $argDef->getType();
}
}
$this->argument = $argDef;
$this->inputTypeStack[] = $argType;
// push
break;
case Node::LST:
$listType = Type::getNullableType($this->getInputType());
$this->inputTypeStack[] = $listType instanceof ListOfType ? $listType->getWrappedType() : null;
// push
break;
case Node::OBJECT_FIELD:
$objectType = Type::getNamedType($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;
}
$this->inputTypeStack[] = $fieldType;
break;
}
}