Skip to content

Commit b702b43

Browse files
committed
Extract some methods in separate classes
1 parent 2002377 commit b702b43

File tree

3 files changed

+104
-67
lines changed

3 files changed

+104
-67
lines changed

src/DirectiveProcessor.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ruudk\GraphQLCodeGenerator;
6+
7+
use GraphQL\Language\AST\DirectiveNode;
8+
use GraphQL\Language\AST\NodeList;
9+
use GraphQL\Language\AST\StringValueNode;
10+
11+
final class DirectiveProcessor
12+
{
13+
/**
14+
* Check if a field has @include or @skip directive
15+
*
16+
* @param NodeList<DirectiveNode> $directives
17+
*/
18+
public function hasIncludeOrSkipDirective(NodeList $directives) : bool
19+
{
20+
foreach ($directives as $directive) {
21+
if (in_array($directive->name->value, ['include', 'skip'], true)) {
22+
return true;
23+
}
24+
}
25+
26+
return false;
27+
}
28+
29+
/**
30+
* Extract the @indexBy directive field path
31+
*
32+
* @param NodeList<DirectiveNode> $directives
33+
* @return list<string>
34+
*/
35+
public function getIndexByDirective(NodeList $directives) : array
36+
{
37+
foreach ($directives as $directive) {
38+
if ($directive->name->value !== 'indexBy') {
39+
continue;
40+
}
41+
42+
if ( ! $directive->arguments[0]->value instanceof StringValueNode) {
43+
continue;
44+
}
45+
46+
return explode('.', $directive->arguments[0]->value->value);
47+
}
48+
49+
return [];
50+
}
51+
}

src/GraphQLCodeGenerator.php

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use Exception;
88
use GraphQL\Error\InvariantViolation;
9-
use GraphQL\Language\AST\DirectiveNode;
109
use GraphQL\Language\AST\DocumentNode;
1110
use GraphQL\Language\AST\FieldNode;
1211
use GraphQL\Language\AST\FragmentSpreadNode;
@@ -16,7 +15,6 @@
1615
use GraphQL\Language\AST\NodeList;
1716
use GraphQL\Language\AST\OperationDefinitionNode;
1817
use GraphQL\Language\AST\SelectionSetNode;
19-
use GraphQL\Language\AST\StringValueNode;
2018
use GraphQL\Language\Parser;
2119
use GraphQL\Language\Printer;
2220
use GraphQL\Type\Definition\EnumType;
@@ -143,6 +141,8 @@ final class GraphQLCodeGenerator
143141
private readonly DataClassGenerator $dataClassGenerator;
144142
private readonly InputTypeGenerator $inputTypeGenerator;
145143
private TypeMapper $typeMapper;
144+
private DirectiveProcessor $directiveProcessor;
145+
private VariableParser $variableParser;
146146

147147
/**
148148
* @var array<string, SymfonyType>
@@ -323,6 +323,10 @@ public function generate() : array
323323
$this->objectTypes,
324324
);
325325

326+
// Initialize helper classes
327+
$this->directiveProcessor = new DirectiveProcessor();
328+
$this->variableParser = new VariableParser($this->typeMapper);
329+
326330
foreach ($this->schema->getTypeMap() as $typeName => $type) {
327331
if (str_starts_with($typeName, '__')) {
328332
continue;
@@ -451,7 +455,7 @@ private function processOperation(DocumentNode $document, string $relativeFilePa
451455
$queryDir = $this->config->outputDir . '/' . $operationType;
452456
$operationDir = $queryDir . '/' . $operationName;
453457

454-
$variables = $this->parseVariables($operation);
458+
$variables = $this->variableParser->parseVariables($operation);
455459

456460
$relativePath = str_replace($this->config->outputDir . '/', '', $queryDir . '/' . $queryClassName . $operationType . '.php');
457461
$this->files[$relativePath] = $this->operationClassGenerator->generate(
@@ -509,33 +513,6 @@ private function processOperation(DocumentNode $document, string $relativeFilePa
509513
);
510514
}
511515

512-
/**
513-
* @return array<string, SymfonyType>
514-
*/
515-
private function parseVariables(OperationDefinitionNode $operation) : array
516-
{
517-
$required = [];
518-
$optional = [];
519-
520-
foreach ($operation->variableDefinitions as $varDef) {
521-
$name = $varDef->variable->name->value;
522-
$type = $this->typeMapper->mapGraphQLASTTypeToPHPType($varDef->type);
523-
524-
if ($type instanceof SymfonyType\NullableType) {
525-
$optional[$name] = $type;
526-
527-
continue;
528-
}
529-
530-
$required[$name] = $type;
531-
}
532-
533-
return [
534-
...$required,
535-
...$optional,
536-
];
537-
}
538-
539516
/**
540517
* @param list<string> $indexBy
541518
*
@@ -668,7 +645,7 @@ private function parseSelectionSet(
668645
$indexBy = [];
669646

670647
if ($this->config->indexByDirective) {
671-
$indexBy = $this->getIndexByDirective($selection->directives);
648+
$indexBy = $this->directiveProcessor->getIndexByDirective($selection->directives);
672649

673650
if ($indexBy !== []) {
674651
$indexByType = $this->typeMapper->mapGraphQLTypeToPHPType(RecursiveTypeFinder::find($nakedFieldType, $indexBy));
@@ -734,7 +711,7 @@ private function parseSelectionSet(
734711
$this->inlineFragmentRequiredFields,
735712
);
736713

737-
if ($this->hasIncludeOrSkipDirective($selection->directives)) {
714+
if ($this->directiveProcessor->hasIncludeOrSkipDirective($selection->directives)) {
738715
$subType = SymfonyType::nullable($subType);
739716
$subPayloadShape = SymfonyType::nullable($subPayloadShape);
740717
}
@@ -931,41 +908,6 @@ private function getPossibleTypes(Type $type) : array
931908
return [];
932909
}
933910

934-
/**
935-
* @param NodeList<DirectiveNode> $directives
936-
*/
937-
private function hasIncludeOrSkipDirective(NodeList $directives) : bool
938-
{
939-
foreach ($directives as $directive) {
940-
if (in_array($directive->name->value, ['include', 'skip'], true)) {
941-
return true;
942-
}
943-
}
944-
945-
return false;
946-
}
947-
948-
/**
949-
* @param NodeList<DirectiveNode> $directives
950-
* @return list<string>
951-
*/
952-
private function getIndexByDirective(NodeList $directives) : array
953-
{
954-
foreach ($directives as $directive) {
955-
if ($directive->name->value !== 'indexBy') {
956-
continue;
957-
}
958-
959-
if ( ! $directive->arguments[0]->value instanceof StringValueNode) {
960-
continue;
961-
}
962-
963-
return explode('.', $directive->arguments[0]->value->value);
964-
}
965-
966-
return [];
967-
}
968-
969911
private function singularize(string $fieldName) : string
970912
{
971913
$options = $this->inflector->singularize($fieldName);

src/VariableParser.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Ruudk\GraphQLCodeGenerator;
6+
7+
use GraphQL\Language\AST\OperationDefinitionNode;
8+
use Symfony\Component\TypeInfo\Type as SymfonyType;
9+
10+
final class VariableParser
11+
{
12+
public function __construct(
13+
private readonly TypeMapper $typeMapper,
14+
) {}
15+
16+
/**
17+
* Parse GraphQL operation variables into PHP types
18+
*
19+
* @return array<string, SymfonyType>
20+
*/
21+
public function parseVariables(OperationDefinitionNode $operation) : array
22+
{
23+
$required = [];
24+
$optional = [];
25+
26+
foreach ($operation->variableDefinitions as $varDef) {
27+
$name = $varDef->variable->name->value;
28+
$type = $this->typeMapper->mapGraphQLASTTypeToPHPType($varDef->type);
29+
30+
if ($type instanceof SymfonyType\NullableType) {
31+
$optional[$name] = $type;
32+
33+
continue;
34+
}
35+
36+
$required[$name] = $type;
37+
}
38+
39+
return [
40+
...$required,
41+
...$optional,
42+
];
43+
}
44+
}

0 commit comments

Comments
 (0)