Skip to content
15 changes: 8 additions & 7 deletions src/Error/Error.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ class Error extends Exception implements JsonSerializable, ClientAware
const CATEGORY_GRAPHQL = 'graphql';
const CATEGORY_INTERNAL = 'internal';

/** @var SourceLocation[] */
/**
* Lazily initialized.
*
* @var SourceLocation[]
*/
private $locations;

/**
Expand Down Expand Up @@ -203,10 +207,7 @@ public function getCategory()
return $this->category;
}

/**
* @return Source|null
*/
public function getSource()
public function getSource() : ?Source
{
if ($this->source === null) {
if (isset($this->nodes[0]) && $this->nodes[0]->loc !== null) {
Expand Down Expand Up @@ -258,9 +259,9 @@ static function ($p) : bool {
*
* @api
*/
public function getLocations()
public function getLocations() : array
{
if ($this->locations === null) {
if (! isset($this->locations)) {
$positions = $this->getPositions();
$source = $this->getSource();
$nodes = $this->nodes;
Expand Down
16 changes: 11 additions & 5 deletions src/Type/Definition/EnumType.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ class EnumType extends Type implements InputType, OutputType, LeafType, Nullable
/** @var EnumTypeDefinitionNode|null */
public $astNode;

/** @var EnumValueDefinition[] */
/**
* Lazily initialized.
*
* @var EnumValueDefinition[]
*/
private $values;

/**
* Actually a MixedStore<mixed, EnumValueDefinition>, PHPStan won't let us type it that way
* Lazily initialized.
*
* Actually a MixedStore<mixed, EnumValueDefinition>, PHPStan won't let us type it that way.
*
* @var MixedStore
*/
Expand Down Expand Up @@ -88,9 +94,9 @@ private function getNameLookup() : ArrayObject
/**
* @return EnumValueDefinition[]
*/
public function getValues()
public function getValues() : array
{
if ($this->values === null) {
if (! isset($this->values)) {
$this->values = [];
$config = $this->config;

Expand Down Expand Up @@ -145,7 +151,7 @@ public function serialize($value)
*/
private function getValueLookup() : MixedStore
{
if ($this->valueLookup === null) {
if (! isset($this->valueLookup)) {
$this->valueLookup = new MixedStore();

foreach ($this->getValues() as $valueName => $value) {
Expand Down
7 changes: 6 additions & 1 deletion src/Type/Definition/FieldDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ protected function __construct(array $config)
$this->complexityFn = $config['complexity'] ?? self::DEFAULT_COMPLEXITY_FN;
}

public static function defineFieldMap(Type $type, $fields)
/**
* @param (callable():mixed[])|mixed[] $fields
*
* @return array<string, self>
*/
public static function defineFieldMap(Type $type, $fields) : array
{
if (is_callable($fields)) {
$fields = $fields();
Expand Down
65 changes: 34 additions & 31 deletions src/Type/Definition/InputObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace GraphQL\Type\Definition;

use Exception;
use GraphQL\Error\InvariantViolation;
use GraphQL\Language\AST\InputObjectTypeDefinitionNode;
use GraphQL\Language\AST\InputObjectTypeExtensionNode;
Expand All @@ -21,7 +20,11 @@ class InputObjectType extends Type implements InputType, NullableType, NamedType
/** @var InputObjectTypeDefinitionNode|null */
public $astNode;

/** @var InputObjectField[] */
/**
* Lazily initialized.
*
* @var InputObjectField[]
*/
private $fields;

/** @var InputObjectTypeExtensionNode[] */
Expand All @@ -46,16 +49,12 @@ public function __construct(array $config)
}

/**
* @param string $name
*
* @return InputObjectField
*
* @throws Exception
* @throws InvariantViolation
*/
public function getField($name)
public function getField(string $name) : InputObjectField
{
if ($this->fields === null) {
$this->getFields();
if (! isset($this->fields)) {
$this->initializeFields();
}
Utils::invariant(isset($this->fields[$name]), "Field '%s' is not defined for type '%s'", $name, $this->name);

Expand All @@ -65,32 +64,36 @@ public function getField($name)
/**
* @return InputObjectField[]
*/
public function getFields()
public function getFields() : array
{
if ($this->fields === null) {
$this->fields = [];
if (! isset($this->fields)) {
$this->initializeFields();
}

$fields = $this->config['fields'] ?? [];
if (is_callable($fields)) {
$fields = $fields();
}
return $this->fields;
}

if (! is_array($fields)) {
throw new InvariantViolation(
sprintf('%s fields must be an array or a callable which returns such an array.', $this->name)
);
}
protected function initializeFields() : void
{
$this->fields = [];
$fields = $this->config['fields'] ?? [];
if (is_callable($fields)) {
$fields = $fields();
}

foreach ($fields as $name => $field) {
if ($field instanceof Type) {
$field = ['type' => $field];
}
$field = new InputObjectField($field + ['name' => $name]);
$this->fields[$field->name] = $field;
}
if (! is_array($fields)) {
throw new InvariantViolation(
sprintf('%s fields must be an array or a callable which returns such an array.', $this->name)
);
}

return $this->fields;
foreach ($fields as $name => $field) {
if ($field instanceof Type) {
$field = ['type' => $field];
}
$field = new InputObjectField($field + ['name' => $name]);
$this->fields[$field->name] = $field;
}
}

/**
Expand All @@ -99,7 +102,7 @@ public function getFields()
*
* @throws InvariantViolation
*/
public function assertValid()
public function assertValid() : void
{
parent::assertValid();

Expand Down
53 changes: 27 additions & 26 deletions src/Type/Definition/InterfaceType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT
/** @var InterfaceTypeExtensionNode[] */
public $extensionASTNodes;

/** @var FieldDefinition[] */
/**
* Lazily initialized.
*
* @var FieldDefinition[]
*/
private $fields;

/**
Expand All @@ -44,9 +48,11 @@ public function __construct(array $config)
/**
* @param mixed $type
*
* @return self
* @return $this
*
* @throws InvariantViolation
*/
public static function assertInterfaceType($type)
public static function assertInterfaceType($type) : self
{
Utils::invariant(
$type instanceof self,
Expand All @@ -56,30 +62,20 @@ public static function assertInterfaceType($type)
return $type;
}

/**
* @param string $name
*
* @return FieldDefinition
*/
public function getField($name)
public function getField(string $name) : FieldDefinition
{
if ($this->fields === null) {
$this->getFields();
if (! isset($this->fields)) {
$this->initializeFields();
}
Utils::invariant(isset($this->fields[$name]), 'Field "%s" is not defined for type "%s"', $name, $this->name);

return $this->fields[$name];
}

/**
* @param string $name
*
* @return bool
*/
public function hasField($name)
public function hasField(string $name) : bool
{
if ($this->fields === null) {
$this->getFields();
if (! isset($this->fields)) {
$this->initializeFields();
}

return isset($this->fields[$name]);
Expand All @@ -88,21 +84,26 @@ public function hasField($name)
/**
* @return FieldDefinition[]
*/
public function getFields()
public function getFields() : array
{
if ($this->fields === null) {
$fields = $this->config['fields'] ?? [];
$this->fields = FieldDefinition::defineFieldMap($this, $fields);
if (! isset($this->fields)) {
$this->initializeFields();
}

return $this->fields;
}

protected function initializeFields() : void
{
$fields = $this->config['fields'] ?? [];
$this->fields = FieldDefinition::defineFieldMap($this, $fields);
}

/**
* Resolves concrete ObjectType for given object value
*
* @param object $objectValue
* @param mixed[] $context
* @param object $objectValue
* @param mixed $context
*
* @return Type|null
*/
Expand All @@ -120,7 +121,7 @@ public function resolveType($objectValue, $context, ResolveInfo $info)
/**
* @throws InvariantViolation
*/
public function assertValid()
public function assertValid() : void
{
parent::assertValid();

Expand Down
Loading