Completed
Push — master ( 1e8320...6a42b9 )
by Kirill
03:17
created

Factory::build()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.0932

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 14
ccs 5
cts 7
cp 0.7143
crap 2.0932
rs 9.7998
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\Definition as DefinitionInterface;
14
use Railt\Reflection\Contracts\Invocation\DirectiveInvocation;
15
use Railt\Reflection\Document;
16
use Railt\SDL\Compiler\Processor\Definition;
17
use Railt\SDL\Compiler\Processor\ProcessorInterface;
18
use Railt\SDL\Exception\CompilerException;
19
20
/**
21
 * Class Factory
22
 */
23
class Factory
24
{
25
    /**
26
     * @var ProcessorInterface[]
27
     */
28
    private const NODE_MAPPINGS = [
29
        'ObjectDefinition'    => Definition\ObjectProcessor::class,
30
        'InterfaceDefinition' => Definition\InterfaceProcessor::class,
31
    ];
32
33
    /**
34
     * @var Pipeline
35
     */
36
    private $pipeline;
37
38
    /**
39
     * @var Document
40
     */
41
    private $document;
42
43
    /**
44
     * @var RuleInterface
45
     */
46
    private $ast;
47
48
    /**
49
     * Processor constructor.
50
     * @param Document $document
51
     * @param RuleInterface $ast
52
     */
53 1
    public function __construct(Document $document, RuleInterface $ast)
54
    {
55 1
        $this->ast      = $ast;
56 1
        $this->document = $document;
57 1
        $this->pipeline = new Pipeline();
58 1
    }
59
60
    /**
61
     * @return Document
62
     * @throws \Railt\Io\Exception\ExternalFileException
63
     */
64 1
    public function process(): Document
65
    {
66 1
        foreach ($this->ast as $child) {
67 1
            $definition = $this->build($child);
68
69 1
            if ($definition instanceof DefinitionInterface\TypeDefinition) {
70 1
                $this->document->withDefinition($definition);
71
            }
72
73 1
            if ($definition instanceof DirectiveInvocation) {
74 1
                $this->document->withDirective($definition);
75
            }
76
        }
77
78 1
        foreach ($this->pipeline as $next) {
79
            $next();
80
        }
81
82 1
        return $this->document;
83
    }
84
85
    /**
86
     * @param RuleInterface $rule
87
     * @return DefinitionInterface
88
     * @throws \Railt\Io\Exception\ExternalFileException
89
     */
90 1
    public function build(RuleInterface $rule): DefinitionInterface
91
    {
92 1
        $mapping = self::NODE_MAPPINGS[$rule->getName()] ?? null;
93
94 1
        if ($mapping === null) {
95
            throw (new CompilerException(\sprintf('No mappings found for %s AST', $rule->getName())))
96
                ->throwsIn($this->document->getFile(), $rule->getOffset());
97
        }
98
99
        /** @var ProcessorInterface $instance */
100 1
        $instance = new $mapping($this->document, $this->pipeline, $this);
101
102 1
        return $instance->resolve($rule);
103
    }
104
}
105