Completed
Push — master ( c1a156...8cadde )
by Kirill
08:14
created

Builder   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 66.67%

Importance

Changes 0
Metric Value
dl 0
loc 104
ccs 22
cts 33
cp 0.6667
rs 10
c 0
b 0
f 0
wmc 11
lcom 1
cbo 7

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A run() 0 25 5
A build() 0 4 1
A buildDefinition() 0 19 3
A setLogger() 0 7 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 Psr\Log\LoggerAwareInterface;
13
use Psr\Log\LoggerAwareTrait;
14
use Psr\Log\LoggerInterface;
15
use Railt\Io\Readable;
16
use Railt\Parser\Ast\RuleInterface;
17
use Railt\Reflection\Contracts\Definition as DefinitionInterface;
18
use Railt\Reflection\Contracts\Reflection;
19
use Railt\Reflection\Document;
20
use Railt\SDL\Ast\ProvidesDefinition;
21
use Railt\SDL\Compiler\Process\Emittable;
22
use Railt\SDL\Compiler\Process\Pipeline;
23
use Railt\SDL\Exception\CompilerException;
24
use Railt\SDL\Exception\InternalException;
25
26
/**
27
 * Class Factory
28
 */
29
class Builder implements LoggerAwareInterface
30
{
31
    use LoggerAwareTrait;
32
33
    /**
34
     * @var SystemManager
35
     */
36
    private $systems;
37
38
    /**
39
     * @var Pipeline
40
     */
41
    private $pipeline;
42
43
    /**
44
     * Process constructor.
45
     */
46 119
    public function __construct()
47
    {
48 119
        $this->pipeline = new Pipeline();
49 119
        $this->systems = new SystemManager($this, $this->pipeline);
50 119
    }
51
52
    /**
53
     * @param Reflection $root
54
     * @param Readable $file
55
     * @param RuleInterface $ast
56
     * @return Document
57
     */
58 119
    public function run(Reflection $root, Readable $file, RuleInterface $ast): Document
59
    {
60 119
        $document = new Document($root, $file);
0 ignored issues
show
Compatibility introduced by
$root of type object<Railt\Reflection\Contracts\Reflection> is not a sub-type of object<Railt\Reflection\Reflection>. It seems like you assume a concrete implementation of the interface Railt\Reflection\Contracts\Reflection to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
61
62 119
        if ($this->logger) {
63
            $this->logger->debug(\sprintf('Create document %s', $document));
64
        }
65
66 119
        $this->systems->resolve($document, $ast);
67
68
        /** @var Emittable $deferred */
69 119
        foreach ($this->pipeline as $deferred) {
70 119
            $handler = $deferred->emit();
71
72 119
            while ($handler->valid()) {
73 119
                $handler->next();
74
            }
75
        }
76
77 119
        if ($this->logger) {
78
            $this->logger->debug(\sprintf('Complete document %s', $document));
79
        }
80
81 119
        return $document;
82
    }
83
84
    /**
85
     * @param RuleInterface $rule
86
     * @param DefinitionInterface $parent
87
     * @return DefinitionInterface
88
     */
89 119
    public function build(RuleInterface $rule, DefinitionInterface $parent): DefinitionInterface
90
    {
91 119
        return $this->buildDefinition($rule, $parent);
92
    }
93
94
    /**
95
     * @param ProvidesDefinition|RuleInterface $rule
96
     * @param DefinitionInterface $parent
97
     * @return DefinitionInterface
98
     * @throws CompilerException
99
     */
100 119
    private function buildDefinition(RuleInterface $rule, DefinitionInterface $parent): DefinitionInterface
101
    {
102 119
        if (! $rule instanceof ProvidesDefinition) {
103
            $error = \vsprintf('%s AST should implement %s interface', [
104
                $rule->getName(), ProvidesDefinition::class]);
105
106
            throw new InternalException($error);
107
        }
108
109 119
        $definition = $rule->resolve($parent);
110
111 119
        if ($this->logger) {
112
            $this->logger->debug(\sprintf('Create type definition %s from %s', $definition, $parent));
113
        }
114
115 119
        $this->systems->resolve($definition, $rule);
116
117 119
        return $definition;
118
    }
119
120
    /**
121
     * Sets a logger instance on the object.
122
     * @param LoggerInterface $logger
123
     * @return void
124
     */
125
    public function setLogger(LoggerInterface $logger): void
126
    {
127
        $this->logger = $logger;
128
129
        $this->pipeline->setLogger($logger);
130
        $this->systems->setLogger($logger);
131
    }
132
}
133