/** * @param ObjectType $object * @param InterfaceType $iface * @throws \Exception */ private function assertObjectImplementsInterface(ObjectType $object, InterfaceType $iface) { $objectFieldMap = $object->getFields(); $ifaceFieldMap = $iface->getFields(); foreach ($ifaceFieldMap as $fieldName => $ifaceField) { Utils::invariant(isset($objectFieldMap[$fieldName]), "\"{$iface}\" expects field \"{$fieldName}\" but \"{$object}\" does not provide it"); /** @var $ifaceField FieldDefinition */ /** @var $objectField FieldDefinition */ $objectField = $objectFieldMap[$fieldName]; Utils::invariant($this->isEqualType($ifaceField->getType(), $objectField->getType()), "{$iface}.{$fieldName} expects type \"{$ifaceField->getType()}\" but " . "{$object}.{$fieldName} provides type \"{$objectField->getType()}"); foreach ($ifaceField->args as $ifaceArg) { /** @var $ifaceArg FieldArgument */ /** @var $objectArg FieldArgument */ $argName = $ifaceArg->name; $objectArg = $objectField->getArg($argName); // Assert interface field arg exists on object field. Utils::invariant($objectArg, "{$iface}.{$fieldName} expects argument \"{$argName}\" but {$object}.{$fieldName} does not provide it."); // Assert interface field arg type matches object field arg type. // (invariant) Utils::invariant($this->isEqualType($ifaceArg->getType(), $objectArg->getType()), "{$iface}.{$fieldName}({$argName}:) expects type \"{$ifaceArg->getType()}\" " . "but {$object}.{$fieldName}({$argName}:) provides " . "type \"{$objectArg->getType()}\""); // Assert argument set invariance. foreach ($objectField->args as $objectArg) { $argName = $objectArg->name; $ifaceArg = $ifaceField->getArg($argName); Utils::invariant($ifaceArg, "{$iface}.{$fieldName} does not define argument \"{$argName}\" but " . "{$object}.{$fieldName} provides it."); } } } }