Test Failed
Push — master ( 08713d...9fa0b4 )
by Kirill
03:13
created

Builder::shouldBeTypeOf()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 3
dl 0
loc 15
ccs 0
cts 13
cp 0
crap 12
rs 9.7666
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\Builder;
11
12
use Railt\Parser\Ast\RuleInterface;
13
use Railt\Reflection\Contracts\Definition;
14
use Railt\Reflection\Contracts\Definition\Behaviour\ProvidesTypeIndication;
15
use Railt\Reflection\Contracts\Definition\TypeDefinition;
16
use Railt\SDL\Compiler\Ast\Value\ValueInterface;
17
use Railt\SDL\Compiler\Builder\Common\ValueBuilder;
18
use Railt\SDL\Compiler\Builder\Common\ValueInvocation;
19
use Railt\SDL\Compiler\Factory;
20
use Railt\SDL\Compiler\Pipeline;
21
use Railt\SDL\Exception\TypeConflictException;
22
23
/**
24
 * Class Builder
25
 */
26
abstract class Builder implements BuilderInterface
27
{
28
    /**
29
     * @var Pipeline
30
     */
31
    protected $when;
32
33
    /**
34
     * @var Factory
35
     */
36
    private $factory;
37
38
    /**
39
     * Builder constructor.
40
     * @param Pipeline $pipeline
41
     * @param Factory $factory
42
     */
43
    public function __construct(Pipeline $pipeline, Factory $factory)
44
    {
45
        $this->when    = $pipeline;
46
        $this->factory = $factory;
47
    }
48
49
    /**
50
     * @param Definition|ProvidesTypeIndication $from
51
     * @param ValueInterface $value
52
     * @return array|mixed
53
     * @throws \Railt\Io\Exception\ExternalFileException
54
     */
55
    protected function valueOf(ProvidesTypeIndication $from, ValueInterface $value)
56
    {
57
        $result = (new ValueBuilder($from))->valueOf($value);
58
59
        $this->when->runtime(function() use ($result) {
60
            (new ValueInvocation())->invoke($result);
61
        });
62
63
        return $result;
64
    }
65
66
    /**
67
     * @param TypeDefinition $parent
68
     * @param TypeDefinition $definition
69
     * @param array $types
70
     * @throws \Railt\Io\Exception\ExternalFileException
71
     */
72
    protected function shouldBeTypeOf(TypeDefinition $parent, TypeDefinition $definition, array $types): void
73
    {
74
        foreach ($types as $allowed) {
75
            if ($definition::getType()->is($allowed)) {
76
                return;
77
            }
78
        }
79
80
        $error = \vsprintf('%s should be one of {%s}, but %s given', [
81
            $parent, \implode(', ', $types), $definition
82
        ]);
83
84
        throw (new TypeConflictException($error))
85
            ->throwsIn($parent->getFile(), $parent->getLine(), $parent->getColumn());
86
    }
87
88
    /**
89
     * @param string $type
90
     * @param TypeDefinition $from
91
     * @return TypeDefinition
92
     * @throws \Railt\Reflection\Exception\TypeNotFoundException
93
     */
94
    protected function load(string $type, TypeDefinition $from): TypeDefinition
95
    {
96
        $dict = $from->getDictionary();
97
98
        return $dict->get($type, $from);
99
    }
100
101
    /**
102
     * @param RuleInterface $ast
103
     * @param Definition $parent
104
     * @return Definition
105
     * @throws \Railt\Io\Exception\ExternalFileException
106
     */
107
    protected function dependent(RuleInterface $ast, Definition $parent): Definition
108
    {
109
        return $this->factory->build($ast, $parent);
110
    }
111
}
112