Completed
Push — master ( 332a4c...198c54 )
by Kirill
02:13
created

Factory::build()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 0
dl 0
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of Railt package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
declare(strict_types=1);
9
10
namespace Railt\SDL\Compiler;
11
12
use Railt\Parser\Ast\RuleInterface;
13
use Railt\Reflection\Contracts\Dictionary;
14
use Railt\Reflection\Document;
15
use Railt\SDL\Compiler\Processor\Definition;
16
use Railt\SDL\Compiler\Processor\Extension;
17
use Railt\SDL\Compiler\Processor\Invocation;
18
use Railt\SDL\Compiler\Processor\Processable;
19
use Railt\SDL\Exception\CompilerException;
20
21
/**
22
 * Class Factory
23
 */
24
class Factory
25
{
26
    /**
27
     * @var Processable[]
28
     */
29
    private const NODE_MAPPINGS = [
30
        'DirectiveDefinition'  => Definition\DirectiveProcessor::class,
31
        'Directive'            => Invocation\DirectiveInvocationProcessor::class,
32
        'EnumDefinition'       => Definition\EnumProcessor::class,
33
        'EnumExtension'        => Extension\EnumExtensionProcessor::class,
34
        'InputDefinition'      => Definition\InputProcessor::class,
35
        'InputExtension'       => Extension\InputExtensionProcessor::class,
36
        'InputUnionDefinition' => Definition\InputUnionProcessor::class,
37
        'InputUnionExtension'  => Extension\InputUnionExtensionProcessor::class,
38
        'InterfaceDefinition'  => Definition\InterfaceProcessor::class,
39
        'InterfaceExtension'   => Extension\InterfaceExtensionProcessor::class,
40
        'ObjectDefinition'     => Definition\ObjectProcessor::class,
41
        'ObjectExtension'      => Extension\ObjectExtensionProcessor::class,
42
        'ScalarDefinition'     => Definition\ScalarProcessor::class,
43
        'ScalarExtension'      => Extension\ScalarExtensionProcessor::class,
44
        'SchemaDefinition'     => Definition\SchemaProcessor::class,
45
        'SchemaExtension'      => Extension\SchemaExtensionProcessor::class,
46
        'UnionDefinition'      => Definition\UnionProcessor::class,
47
        'UnionExtension'       => Extension\UnionExtensionProcessor::class,
48
    ];
49
50
    /**
51
     * @var CallStack
52
     */
53
    private $stack;
54
55
    /**
56
     * @var CallStack
57
     */
58
    private $pipeline;
59
60
    /**
61
     * @var Document
62
     */
63
    private $document;
64
65
    /**
66
     * @var RuleInterface
67
     */
68
    private $ast;
69
70
    /**
71
     * @var Dictionary
72
     */
73
    private $dictionary;
74
75
    /**
76
     * Processor constructor.
77
     * @param Document $document
78
     * @param RuleInterface $ast
79
     */
80
    public function __construct(Document $document, RuleInterface $ast)
81
    {
82
        $this->ast        = $ast;
83
        $this->document   = $document;
84
        $this->stack      = new CallStack();
85
        $this->pipeline   = new Pipeline();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Railt\SDL\Compiler\Pipeline() of type object<Railt\SDL\Compiler\Pipeline> is incompatible with the declared type object<Railt\SDL\Compiler\CallStack> of property $pipeline.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
86
        $this->dictionary = $document->getDictionary();
87
    }
88
89
    /**
90
     * @return Document
91
     * @throws \Railt\Io\Exception\ExternalFileException
92
     */
93
    public function process(): Document
94
    {
95
        $this->build();
96
97
        return $this->document;
98
    }
99
100
    /**
101
     * @throws \Railt\Io\Exception\ExternalFileException
102
     */
103
    protected function build(): void
104
    {
105
        /** @var RuleInterface $child */
106
        foreach ($this->ast as $child) {
107
            $processor = $this->findProcessor($child->getName());
108
109
            if ($processor === null) {
110
                throw (new CompilerException(\sprintf('Unprocessable node %s', $child->getName())))
111
                    ->throwsIn($this->document->getFile(), $child->getOffset());
112
            }
113
114
            if ($definition = $processor->process($child)) {
115
                $this->document->withDefinition($definition);
116
            }
117
        }
118
    }
119
120
    /**
121
     * @param string $name
122
     * @return null|Processable
123
     */
124
    private function findProcessor(string $name): ?Processable
125
    {
126
        $processor = self::NODE_MAPPINGS[$name] ?? null;
127
128
        return $processor ? new $processor($this->pipeline, $this->stack, $this->dictionary) : null;
129
    }
130
}
131