Completed
Push — master ( 7510c8...82c7bd )
by Kirill
08:19
created

Factory   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 80%

Importance

Changes 0
Metric Value
dl 0
loc 112
ccs 20
cts 25
cp 0.8
rs 10
c 0
b 0
f 0
wmc 9
lcom 1
cbo 6

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A process() 0 20 5
A build() 0 14 2
A getTypeCoercion() 0 4 1
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\Definition\TypeDefinition;
15
use Railt\Reflection\Contracts\Invocation\DirectiveInvocation;
16
use Railt\Reflection\Document;
17
use Railt\SDL\Compiler\Builder\BuilderInterface;
18
use Railt\SDL\Compiler\Builder\Definition;
19
use Railt\SDL\Compiler\Builder\Dependent;
20
use Railt\SDL\Compiler\Builder\Invocation;
21
use Railt\SDL\Exception\CompilerException;
22
23
/**
24
 * Class Factory
25
 */
26
class Factory
27
{
28
    /**
29
     * @var BuilderInterface[]
30
     */
31
    private const NODE_MAPPINGS = [
32
        'DirectiveDefinition'  => Definition\DirectiveBuilder::class,
33
        'EnumDefinition'       => Definition\EnumBuilder::class,
34
        'InputDefinition'      => Definition\InputBuilder::class,
35
        'InputUnionDefinition' => Definition\InputUnionBuilder::class,
36
        'InterfaceDefinition'  => Definition\InterfaceBuilder::class,
37
        'ObjectDefinition'     => Definition\ObjectBuilder::class,
38
        'ScalarDefinition'     => Definition\ScalarBuilder::class,
39
        'SchemaDefinition'     => Definition\SchemaBuilder::class,
40
        'UnionDefinition'      => Definition\UnionBuilder::class,
41
42
        'FieldDefinition'      => Dependent\FieldBuilder::class,
43
        'ArgumentDefinition'   => Dependent\ArgumentBuilder::class,
44
        'EnumValue'            => Dependent\EnumValueBuilder::class,
45
        'InputFieldDefinition' => Dependent\InputFieldBuilder::class,
46
47
        'Directive'         => Invocation\DirectiveBuilder::class,
48
        'DirectiveArgument' => Invocation\DirectiveArgumentBuilder::class,
49
    ];
50
51
    /**
52
     * @var Pipeline
53
     */
54
    private $pipeline;
55
56
    /**
57
     * @var Document
58
     */
59
    private $document;
60
61
    /**
62
     * @var RuleInterface
63
     */
64
    private $ast;
65
66
    /**
67
     * @var Coercion
68
     */
69
    private $coercion;
70
71
    /**
72
     * Processor constructor.
73
     * @param Document $document
74
     * @param RuleInterface $ast
75
     */
76 1
    public function __construct(Document $document, RuleInterface $ast)
77
    {
78 1
        $this->ast = $ast;
79 1
        $this->document = $document;
80 1
        $this->pipeline = new Pipeline();
81 1
        $this->coercion = new Coercion();
82 1
    }
83
84
    /**
85
     * @return Document
86
     * @throws \Railt\Io\Exception\ExternalFileException
87
     */
88 1
    public function process(): Document
89
    {
90 1
        foreach ($this->ast as $child) {
91 1
            $definition = $this->build($child, $this->document);
92
93 1
            if ($definition instanceof TypeDefinition) {
94 1
                $this->document->withDefinition($definition);
95
            }
96
97 1
            if ($definition instanceof DirectiveInvocation) {
98 1
                $this->document->withDirective($definition);
99
            }
100
        }
101
102 1
        foreach ($this->pipeline as $next) {
103
            $next();
104
        }
105
106 1
        return $this->document;
107
    }
108
109
    /**
110
     * @param RuleInterface $rule
111
     * @param DefinitionInterface $parent
112
     * @return DefinitionInterface
113
     * @throws \Railt\Io\Exception\ExternalFileException
114
     */
115 1
    public function build(RuleInterface $rule, DefinitionInterface $parent): DefinitionInterface
116
    {
117 1
        $mapping = self::NODE_MAPPINGS[$rule->getName()] ?? null;
118
119 1
        if ($mapping === null) {
120
            throw (new CompilerException(\sprintf('No mappings found for %s AST',
121
                $rule->getName())))->throwsIn($this->document->getFile(), $rule->getOffset());
122
        }
123
124
        /** @var BuilderInterface $instance */
125 1
        $instance = new $mapping($this->pipeline, $this);
126
127 1
        return $instance->build($rule, $parent);
128
    }
129
130
    /**
131
     * @return Coercion
132
     */
133
    public function getTypeCoercion(): Coercion
134
    {
135
        return $this->coercion;
136
    }
137
}
138