Skip to content

Commit

Permalink
Open ReferenceExecutor for extending (#801)
Browse files Browse the repository at this point in the history
(cherry picked from commit c19cd7c)
  • Loading branch information
4n70w4 authored and spawnia committed Mar 29, 2021
1 parent 65428ce commit 4432579
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 47 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,9 @@

#### Unreleased

Feat:
- Open ReferenceExecutor for extending

#### 14.5.1

Fix:
Expand Down
94 changes: 47 additions & 47 deletions src/Executor/ReferenceExecutor.php
Expand Up @@ -55,18 +55,18 @@
class ReferenceExecutor implements ExecutorImplementation
{
/** @var object */
private static $UNDEFINED;
protected static $UNDEFINED;

/** @var ExecutionContext */
private $exeContext;
protected $exeContext;

/** @var SplObjectStorage */
private $subFieldCache;
protected $subFieldCache;

private function __construct(ExecutionContext $context)
protected function __construct(ExecutionContext $context)
{
if (! self::$UNDEFINED) {
self::$UNDEFINED = Utils::undefined();
if (! static::$UNDEFINED) {
static::$UNDEFINED = Utils::undefined();
}
$this->exeContext = $context;
$this->subFieldCache = new SplObjectStorage();
Expand All @@ -87,7 +87,7 @@ public static function create(
?string $operationName,
callable $fieldResolver
) : ExecutorImplementation {
$exeContext = self::buildExecutionContext(
$exeContext = static::buildExecutionContext(
$schema,
$documentNode,
$rootValue,
Expand Down Expand Up @@ -116,7 +116,7 @@ public function doExecute() : Promise
};
}

return new self($exeContext);
return new static($exeContext);
}

/**
Expand All @@ -129,7 +129,7 @@ public function doExecute() : Promise
*
* @return ExecutionContext|array<Error>
*/
private static function buildExecutionContext(
protected static function buildExecutionContext(
Schema $schema,
DocumentNode $documentNode,
$rootValue,
Expand Down Expand Up @@ -227,7 +227,7 @@ public function doExecute() : Promise
*
* @return ExecutionResult|Promise
*/
private function buildResponse($data)
protected function buildResponse($data)
{
if ($this->isPromise($data)) {
return $data->then(function ($resolved) {
Expand All @@ -248,7 +248,7 @@ private function buildResponse($data)
*
* @return array<mixed>|Promise|stdClass|null
*/
private function executeOperation(OperationDefinitionNode $operation, $rootValue)
protected function executeOperation(OperationDefinitionNode $operation, $rootValue)
{
$type = $this->getOperationRootType($this->exeContext->schema, $operation);
$fields = $this->collectFields($type, $operation->selectionSet, new ArrayObject(), new ArrayObject());
Expand Down Expand Up @@ -290,7 +290,7 @@ function ($error) : ?Promise {
*
* @throws Error
*/
private function getOperationRootType(Schema $schema, OperationDefinitionNode $operation) : ObjectType
protected function getOperationRootType(Schema $schema, OperationDefinitionNode $operation) : ObjectType
{
switch ($operation->operation) {
case 'query':
Expand Down Expand Up @@ -339,7 +339,7 @@ private function getOperationRootType(Schema $schema, OperationDefinitionNode $o
* returns an Interface or Union type, the "runtime type" will be the actual
* Object type returned by that field.
*/
private function collectFields(
protected function collectFields(
ObjectType $runtimeType,
SelectionSetNode $selectionSet,
ArrayObject $fields,
Expand All @@ -352,7 +352,7 @@ private function collectFields(
if (! $this->shouldIncludeNode($selection)) {
break;
}
$name = self::getFieldEntryKey($selection);
$name = static::getFieldEntryKey($selection);
if (! isset($fields[$name])) {
$fields[$name] = new ArrayObject();
}
Expand Down Expand Up @@ -402,7 +402,7 @@ private function collectFields(
*
* @param FragmentSpreadNode|FieldNode|InlineFragmentNode $node
*/
private function shouldIncludeNode(SelectionNode $node) : bool
protected function shouldIncludeNode(SelectionNode $node) : bool
{
$variableValues = $this->exeContext->variableValues;
$skipDirective = Directive::skipDirective();
Expand All @@ -427,7 +427,7 @@ private function shouldIncludeNode(SelectionNode $node) : bool
/**
* Implements the logic to compute the key of a given fields entry
*/
private static function getFieldEntryKey(FieldNode $node) : string
protected static function getFieldEntryKey(FieldNode $node) : string
{
return $node->alias === null ? $node->name->value : $node->alias->value;
}
Expand All @@ -437,7 +437,7 @@ private static function getFieldEntryKey(FieldNode $node) : string
*
* @param FragmentDefinitionNode|InlineFragmentNode $fragment
*/
private function doesFragmentConditionMatch(Node $fragment, ObjectType $type) : bool
protected function doesFragmentConditionMatch(Node $fragment, ObjectType $type) : bool
{
$typeConditionNode = $fragment->typeCondition;
if ($typeConditionNode === null) {
Expand All @@ -463,7 +463,7 @@ private function doesFragmentConditionMatch(Node $fragment, ObjectType $type) :
*
* @return array<mixed>|Promise|stdClass
*/
private function executeFieldsSerially(ObjectType $parentType, $rootValue, array $path, ArrayObject $fields)
protected function executeFieldsSerially(ObjectType $parentType, $rootValue, array $path, ArrayObject $fields)
{
$result = $this->promiseReduce(
array_keys($fields->getArrayCopy()),
Expand All @@ -472,7 +472,7 @@ function ($results, $responseName) use ($path, $parentType, $rootValue, $fields)
$fieldPath = $path;
$fieldPath[] = $responseName;
$result = $this->resolveField($parentType, $rootValue, $fieldNodes, $fieldPath);
if ($result === self::$UNDEFINED) {
if ($result === static::$UNDEFINED) {
return $results;
}
$promise = $this->getPromise($result);
Expand All @@ -492,11 +492,11 @@ function ($results, $responseName) use ($path, $parentType, $rootValue, $fields)

if ($this->isPromise($result)) {
return $result->then(static function ($resolvedResults) {
return self::fixResultsIfEmptyArray($resolvedResults);
return static::fixResultsIfEmptyArray($resolvedResults);
});
}

return self::fixResultsIfEmptyArray($result);
return static::fixResultsIfEmptyArray($result);
}

/**
Expand All @@ -511,14 +511,14 @@ function ($results, $responseName) use ($path, $parentType, $rootValue, $fields)
*
* @return array<mixed>|Throwable|mixed|null
*/
private function resolveField(ObjectType $parentType, $rootValue, ArrayObject $fieldNodes, array $path)
protected function resolveField(ObjectType $parentType, $rootValue, ArrayObject $fieldNodes, array $path)
{
$exeContext = $this->exeContext;
$fieldNode = $fieldNodes[0];
$fieldName = $fieldNode->name->value;
$fieldDef = $this->getFieldDef($exeContext->schema, $parentType, $fieldName);
if ($fieldDef === null) {
return self::$UNDEFINED;
return static::$UNDEFINED;
}
$returnType = $fieldDef->getType();
// The resolve function's optional 3rd argument is a context value that
Expand Down Expand Up @@ -574,7 +574,7 @@ private function resolveField(ObjectType $parentType, $rootValue, ArrayObject $f
* added to the query type, but that would require mutating type
* definitions, which would cause issues.
*/
private function getFieldDef(Schema $schema, ObjectType $parentType, string $fieldName) : ?FieldDefinition
protected function getFieldDef(Schema $schema, ObjectType $parentType, string $fieldName) : ?FieldDefinition
{
static $schemaMetaFieldDef, $typeMetaFieldDef, $typeNameMetaFieldDef;
$schemaMetaFieldDef = $schemaMetaFieldDef ?? Introspection::schemaMetaFieldDef();
Expand Down Expand Up @@ -604,7 +604,7 @@ private function getFieldDef(Schema $schema, ObjectType $parentType, string $fie
*
* @return Throwable|Promise|mixed
*/
private function resolveFieldValueOrError(
protected function resolveFieldValueOrError(
FieldDefinition $fieldDef,
FieldNode $fieldNode,
callable $resolveFn,
Expand Down Expand Up @@ -636,7 +636,7 @@ private function resolveFieldValueOrError(
*
* @return array<mixed>|Promise|stdClass|null
*/
private function completeValueCatchingError(
protected function completeValueCatchingError(
Type $returnType,
ArrayObject $fieldNodes,
ResolveInfo $info,
Expand Down Expand Up @@ -676,7 +676,7 @@ private function completeValueCatchingError(
*
* @throws Error
*/
private function handleFieldError($rawError, ArrayObject $fieldNodes, array $path, Type $returnType) : void
protected function handleFieldError($rawError, ArrayObject $fieldNodes, array $path, Type $returnType) : void
{
$error = Error::createLocatedError(
$rawError,
Expand Down Expand Up @@ -723,7 +723,7 @@ private function handleFieldError($rawError, ArrayObject $fieldNodes, array $pat
* @throws Error
* @throws Throwable
*/
private function completeValue(
protected function completeValue(
Type $returnType,
ArrayObject $fieldNodes,
ResolveInfo $info,
Expand Down Expand Up @@ -799,7 +799,7 @@ private function completeValue(
/**
* @param mixed $value
*/
private function isPromise($value) : bool
protected function isPromise($value) : bool
{
return $value instanceof Promise || $this->exeContext->promiseAdapter->isThenable($value);
}
Expand All @@ -810,7 +810,7 @@ private function isPromise($value) : bool
*
* @param mixed $value
*/
private function getPromise($value) : ?Promise
protected function getPromise($value) : ?Promise
{
if ($value === null || $value instanceof Promise) {
return $value;
Expand Down Expand Up @@ -843,7 +843,7 @@ private function getPromise($value) : ?Promise
*
* @return Promise|mixed|null
*/
private function promiseReduce(array $values, callable $callback, $initialValue)
protected function promiseReduce(array $values, callable $callback, $initialValue)
{
return array_reduce(
$values,
Expand Down Expand Up @@ -871,7 +871,7 @@ function ($previous, $value) use ($callback) {
*
* @throws Exception
*/
private function completeListValue(ListOfType $returnType, ArrayObject $fieldNodes, ResolveInfo $info, array $path, &$results)
protected function completeListValue(ListOfType $returnType, ArrayObject $fieldNodes, ResolveInfo $info, array $path, &$results)
{
$itemType = $returnType->getWrappedType();
Utils::invariant(
Expand Down Expand Up @@ -906,7 +906,7 @@ private function completeListValue(ListOfType $returnType, ArrayObject $fieldNod
*
* @throws Exception
*/
private function completeLeafValue(LeafType $returnType, &$result)
protected function completeLeafValue(LeafType $returnType, &$result)
{
try {
return $returnType->serialize($result);
Expand All @@ -930,7 +930,7 @@ private function completeLeafValue(LeafType $returnType, &$result)
*
* @throws Error
*/
private function completeAbstractValue(
protected function completeAbstractValue(
AbstractType $returnType,
ArrayObject $fieldNodes,
ResolveInfo $info,
Expand All @@ -941,7 +941,7 @@ private function completeAbstractValue(
$typeCandidate = $returnType->resolveType($result, $exeContext->contextValue, $info);

if ($typeCandidate === null) {
$runtimeType = self::defaultTypeResolver($result, $exeContext->contextValue, $info, $returnType);
$runtimeType = static::defaultTypeResolver($result, $exeContext->contextValue, $info, $returnType);
} elseif (is_callable($typeCandidate)) {
$runtimeType = Schema::resolveType($typeCandidate);
} else {
Expand Down Expand Up @@ -1001,7 +1001,7 @@ private function completeAbstractValue(
*
* @return Promise|Type|string|null
*/
private function defaultTypeResolver($value, $contextValue, ResolveInfo $info, AbstractType $abstractType)
protected function defaultTypeResolver($value, $contextValue, ResolveInfo $info, AbstractType $abstractType)
{
// First, look for `__typename`.
if ($value !== null &&
Expand Down Expand Up @@ -1066,7 +1066,7 @@ private function defaultTypeResolver($value, $contextValue, ResolveInfo $info, A
*
* @throws Error
*/
private function completeObjectValue(
protected function completeObjectValue(
ObjectType $returnType,
ArrayObject $fieldNodes,
ResolveInfo $info,
Expand Down Expand Up @@ -1116,7 +1116,7 @@ private function completeObjectValue(
*
* @return Error
*/
private function invalidReturnTypeError(
protected function invalidReturnTypeError(
ObjectType $returnType,
$result,
ArrayObject $fieldNodes
Expand All @@ -1135,7 +1135,7 @@ private function invalidReturnTypeError(
*
* @throws Error
*/
private function collectAndExecuteSubfields(
protected function collectAndExecuteSubfields(
ObjectType $returnType,
ArrayObject $fieldNodes,
array $path,
Expand All @@ -1151,7 +1151,7 @@ private function collectAndExecuteSubfields(
* type. Memoizing ensures the subfields are not repeatedly calculated, which
* saves overhead when resolving lists of values.
*/
private function collectSubFields(ObjectType $returnType, ArrayObject $fieldNodes) : ArrayObject
protected function collectSubFields(ObjectType $returnType, ArrayObject $fieldNodes) : ArrayObject
{
if (! isset($this->subFieldCache[$returnType])) {
$this->subFieldCache[$returnType] = new SplObjectStorage();
Expand Down Expand Up @@ -1186,15 +1186,15 @@ private function collectSubFields(ObjectType $returnType, ArrayObject $fieldNode
*
* @return Promise|stdClass|array<mixed>
*/
private function executeFields(ObjectType $parentType, $rootValue, array $path, ArrayObject $fields)
protected function executeFields(ObjectType $parentType, $rootValue, array $path, ArrayObject $fields)
{
$containsPromise = false;
$results = [];
foreach ($fields as $responseName => $fieldNodes) {
$fieldPath = $path;
$fieldPath[] = $responseName;
$result = $this->resolveField($parentType, $rootValue, $fieldNodes, $fieldPath);
if ($result === self::$UNDEFINED) {
if ($result === static::$UNDEFINED) {
continue;
}
if (! $containsPromise && $this->isPromise($result)) {
Expand All @@ -1204,7 +1204,7 @@ private function executeFields(ObjectType $parentType, $rootValue, array $path,
}
// If there are no promises, we can just return the object
if (! $containsPromise) {
return self::fixResultsIfEmptyArray($results);
return static::fixResultsIfEmptyArray($results);
}

// Otherwise, results is a map from field name to the result of resolving that
Expand All @@ -1222,7 +1222,7 @@ private function executeFields(ObjectType $parentType, $rootValue, array $path,
*
* @return array<mixed>|stdClass|mixed
*/
private static function fixResultsIfEmptyArray($results)
protected static function fixResultsIfEmptyArray($results)
{
if ($results === []) {
return new stdClass();
Expand All @@ -1237,7 +1237,7 @@ private static function fixResultsIfEmptyArray($results)
*
* @param array<string, Promise|mixed> $assoc
*/
private function promiseForAssocArray(array $assoc) : Promise
protected function promiseForAssocArray(array $assoc) : Promise
{
$keys = array_keys($assoc);
$valuesAndPromises = array_values($assoc);
Expand All @@ -1249,7 +1249,7 @@ private function promiseForAssocArray(array $assoc) : Promise
$resolvedResults[$keys[$i]] = $value;
}

return self::fixResultsIfEmptyArray($resolvedResults);
return static::fixResultsIfEmptyArray($resolvedResults);
});
}

Expand All @@ -1258,7 +1258,7 @@ private function promiseForAssocArray(array $assoc) : Promise
* @param InterfaceType|UnionType $returnType
* @param mixed $result
*/
private function ensureValidRuntimeType(
protected function ensureValidRuntimeType(
$runtimeTypeOrName,
AbstractType $returnType,
ResolveInfo $info,
Expand Down

0 comments on commit 4432579

Please sign in to comment.