Issues (158)

src/Parser.php (1 issue)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jerowork\GraphqlAttributeSchema;
6
7
use Generator;
8
use Jerowork\GraphqlAttributeSchema\Attribute\Enum;
9
use Jerowork\GraphqlAttributeSchema\Attribute\InputType;
10
use Jerowork\GraphqlAttributeSchema\Attribute\InterfaceType;
11
use Jerowork\GraphqlAttributeSchema\Attribute\Mutation;
12
use Jerowork\GraphqlAttributeSchema\Attribute\Query;
13
use Jerowork\GraphqlAttributeSchema\Attribute\Scalar;
14
use Jerowork\GraphqlAttributeSchema\Attribute\Type;
15
use Jerowork\GraphqlAttributeSchema\Node\Node;
16
use Jerowork\GraphqlAttributeSchema\NodeParser\NodeParser;
17
use Jerowork\GraphqlAttributeSchema\NodeParser\ParseException;
18
use Jerowork\GraphqlAttributeSchema\Util\Finder\Finder;
19
use Jerowork\GraphqlAttributeSchema\Util\Reflector\Reflector;
20
use ReflectionClass;
21
use ReflectionMethod;
22
23
final readonly class Parser
0 ignored issues
show
A parse error occurred: Syntax error, unexpected T_READONLY, expecting T_CLASS on line 23 at column 6
Loading history...
24
{
25
    private const array SUPPORTED_CLASS_ATTRIBUTES = [
26
        Type::class,
27
        InterfaceType::class,
28
        InputType::class,
29
        Enum::class,
30
        Scalar::class,
31
    ];
32
33
    private const array SUPPORTED_METHOD_ATTRIBUTES = [
34
        Mutation::class,
35
        Query::class,
36
    ];
37
38
    /**
39
     * @param iterable<class-string> $customTypes
40
     */
41 4
    public function __construct(
42
        private Finder $finder,
43
        private Reflector $reflector,
44
        private NodeParser $nodeParser,
45
        private iterable $customTypes,
46 4
    ) {}
47
48
    /**
49
     * @throws ParseException
50
     */
51 2
    public function parse(string ...$dirs): Ast
52
    {
53 2
        $nodes = [];
54
55 2
        foreach ($this->getClasses(...$dirs) as $class) {
56 2
            $nodes = [...$nodes, ...$this->parseClass($class)];
57
        }
58
59 2
        foreach ($this->customTypes as $customType) {
60 2
            $nodes = [...$nodes, ...$this->parseClass(new ReflectionClass($customType))];
61
        }
62
63 2
        return new Ast(...$nodes);
64
    }
65
66
    /**
67
     * @throws ParseException
68
     *
69
     * @return Generator<Node>
70
     */
71 2
    private function parseClass(ReflectionClass $class): Generator
72
    {
73
        // Class attributes
74 2
        $attribute = $this->getSupportedAttribute($class);
75
76 2
        if ($attribute !== null) {
77 2
            yield from $this->nodeParser->parse($attribute, $class, null);
78
79 2
            return;
80
        }
81
82
        // Method attributes
83 2
        foreach ($class->getMethods() as $method) {
84 2
            $attribute = $this->getSupportedAttribute($method);
85
86 2
            if ($attribute === null) {
87
                continue;
88
            }
89
90 2
            yield from $this->nodeParser->parse($attribute, $class, $method);
91
        }
92
    }
93
94
    /**
95
     * @return Generator<ReflectionClass>
96
     */
97 2
    private function getClasses(string ...$dirs): Generator
98
    {
99 2
        foreach ($this->finder->findFiles(...$dirs) as $file) {
100 2
            yield from $this->reflector->getClasses($file);
101
        }
102
    }
103
104
    /**
105
     * @return null|class-string
106
     */
107 2
    private function getSupportedAttribute(ReflectionClass|ReflectionMethod $reflector): ?string
108
    {
109 2
        $supportedAttributes = $reflector instanceof ReflectionClass ? self::SUPPORTED_CLASS_ATTRIBUTES : self::SUPPORTED_METHOD_ATTRIBUTES;
110
111 2
        foreach ($supportedAttributes as $attribute) {
112 2
            if ($reflector->getAttributes($attribute) === []) {
113 2
                continue;
114
            }
115
116 2
            return $attribute;
117
        }
118
119 2
        return null;
120
    }
121
}
122