Skip to content

Commit

Permalink
refactor(graphql)!: ArgumentNode support for `AstManipulator::getNa…
Browse files Browse the repository at this point in the history
…me()`; `DirectiveNode` support for `AstManipulator::findArgument()`, `AstManipulator::getArgument()`.
  • Loading branch information
LastDragon-ru committed Sep 7, 2023
1 parent 757fd7d commit cb29569
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
39 changes: 29 additions & 10 deletions packages/graphql/src/Utils/AstManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace LastDragon_ru\LaraASP\GraphQL\Utils;

use Closure;
use GraphQL\Language\AST\ArgumentNode;
use GraphQL\Language\AST\DirectiveNode;
use GraphQL\Language\AST\EnumTypeDefinitionNode;
use GraphQL\Language\AST\FieldDefinitionNode;
Expand Down Expand Up @@ -400,14 +401,18 @@ public function getTypeName(
}

/**
* @param InputValueDefinitionNode|(TypeDefinitionNode&Node)|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|Type $node
* @param InputValueDefinitionNode|(TypeDefinitionNode&Node)|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|ArgumentNode|Type $node
*/
public function getName(
InputValueDefinitionNode|TypeDefinitionNode|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|Type $node,
InputValueDefinitionNode|TypeDefinitionNode|FieldDefinitionNode|InputObjectField|FieldDefinition|Argument|ArgumentNode|Type $node,
): string {
if ($node instanceof TypeDefinitionNode) {
$node = $node->getName();
} elseif ($node instanceof InputValueDefinitionNode || $node instanceof FieldDefinitionNode) {
} elseif (
$node instanceof InputValueDefinitionNode
|| $node instanceof FieldDefinitionNode
|| $node instanceof ArgumentNode
) {
$node = $node->name;
} else {
// empty
Expand Down Expand Up @@ -487,6 +492,9 @@ public function getInterfaces(
return $interfaces;
}

/**
* @return ($node is HasFieldsType ? FieldDefinition : FieldDefinitionNode)|null
*/
public function getField(
InterfaceTypeDefinitionNode|ObjectTypeDefinitionNode|HasFieldsType $node,
string $name,
Expand All @@ -508,14 +516,16 @@ public function getField(
}

/**
* @param callable(InputValueDefinitionNode|Argument): bool $closure
* @param callable(InputValueDefinitionNode|Argument|ArgumentNode): bool $closure
*
* @return ($node is FieldDefinitionNode ? InputValueDefinitionNode : ($node is FieldDefinition ? Argument : ArgumentNode))|null
*/
public function findArgument(
FieldDefinitionNode|FieldDefinition $node,
FieldDefinitionNode|FieldDefinition|DirectiveNode $node,
callable $closure,
): InputValueDefinitionNode|Argument|null {
): InputValueDefinitionNode|Argument|ArgumentNode|null {
$argument = null;
$args = $node instanceof FieldDefinitionNode
$args = $node instanceof FieldDefinitionNode || $node instanceof DirectiveNode
? $node->arguments
: $node->args;

Expand All @@ -529,13 +539,16 @@ public function findArgument(
return $argument;
}

/**
* @return ($node is FieldDefinitionNode ? InputValueDefinitionNode : ($node is FieldDefinition ? Argument : ArgumentNode))|null
*/
public function getArgument(
FieldDefinitionNode|FieldDefinition $node,
FieldDefinitionNode|FieldDefinition|DirectiveNode $node,
string $name,
): InputValueDefinitionNode|Argument|null {
): InputValueDefinitionNode|Argument|ArgumentNode|null {
return $this->findArgument(
$node,
function (InputValueDefinitionNode|Argument $argument) use ($name): bool {
function (mixed $argument) use ($name): bool {
return $this->getName($argument) === $name;
},
);
Expand Down Expand Up @@ -726,6 +739,12 @@ public function setArgumentType(
continue;
}

if ($interfaceArgument instanceof ArgumentNode) {
// Seems conditional return type is not correct here
// https://github.com/phpstan/phpstan/issues/9860
continue;
}

// Update
$this->setType($interfaceArgument, $type);
}
Expand Down
15 changes: 13 additions & 2 deletions packages/graphql/src/Utils/AstManipulatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Closure;
use Exception;
use GraphQL\Language\AST\ArgumentNode;
use GraphQL\Language\AST\FieldDefinitionNode;
use GraphQL\Language\AST\InputValueDefinitionNode;
use GraphQL\Language\AST\InterfaceTypeDefinitionNode;
Expand Down Expand Up @@ -367,7 +368,7 @@ public function testFindArgument(): void {
// Test
$nodeArgument = $manipulator->findArgument(
$node,
static function (InputValueDefinitionNode|Argument $argument) use ($manipulator): bool {
static function (mixed $argument) use ($manipulator): bool {
return $manipulator->getDirective($argument, AstManipulatorTest_ADirective::class) !== null;
},
);
Expand All @@ -377,13 +378,23 @@ static function (InputValueDefinitionNode|Argument $argument) use ($manipulator)

$fieldArgument = $manipulator->findArgument(
$field,
static function (InputValueDefinitionNode|Argument $argument) use ($manipulator): bool {
static function (mixed $argument) use ($manipulator): bool {
return $manipulator->getDirective($argument, AstManipulatorTest_ADirective::class) !== null;
},
);

self::assertInstanceOf(Argument::class, $fieldArgument);
self::assertEquals('b', $fieldArgument->name);

$directiveArgument = $manipulator->findArgument(
Parser::directive('@aDirective(a: "a", b: "b")'),
static function (mixed $argument) use ($manipulator): bool {
return $manipulator->getName($argument) === 'b';
},
);

self::assertInstanceOf(ArgumentNode::class, $directiveArgument);
self::assertEquals('b', $directiveArgument->name->value);
}

/**
Expand Down

0 comments on commit cb29569

Please sign in to comment.