Passed
Push — master ( 81686d...1595cb )
by Kirill
04:41
created

Specification::include()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
/**
4
 * This file is part of Railt package.
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace Railt\SDL\Spec;
13
14
use Phplrt\Source\File;
15
use Phplrt\Visitor\Visitor;
16
use Railt\SDL\CompilerInterface;
17
use Phplrt\Contracts\Ast\NodeInterface;
18
use Railt\SDL\Spec\Constraint\Constraint;
19
use Phplrt\Contracts\Source\FileInterface;
20
use Phplrt\Source\Exception\NotFoundException;
21
use Phplrt\Source\Exception\NotReadableException;
22
use Railt\SDL\Spec\Constraint\RepeatableDirectives;
23
use Railt\SDL\Spec\Constraint\TypeSystemExtensions;
24
25
/**
26
 * Class Specification
27
 */
28
abstract class Specification extends Visitor implements SpecificationInterface
29
{
30
    /**
31
     * @var string
32
     */
33
    private const RESOURCES_PATHNAME = __DIR__ . '/../../resources/stdlib/%s.graphql';
34
35
    /**
36
     * @var string[]|Constraint[]
37
     */
38
    protected const STANDARD_CONSTRAINTS = [
39
        RepeatableDirectives::class,
40
        TypeSystemExtensions::class,
41
    ];
42
43
    /**
44
     * List of language version constraints.
45
     * That is, additional restrictions which should be added to
46
     * standard constraints.
47
     *
48
     * @var array|Constraint[]
49
     */
50
    protected array $constraints = [];
51
52
    /**
53
     * List of the language abilities.
54
     * That is, features that are excluded from
55
     * standard constraints.
56
     *
57
     * @var array|Constraint[]
58
     */
59
    protected array $abilities = [];
60
61
    /**
62
     * List of the language types.
63
     *
64
     * @var array|string[]
65
     */
66
    protected array $types = [];
67
68
    /**
69
     * Specification constructor.
70
     */
71
    public function __construct()
72
    {
73
        $this->bootConstraints();
74
    }
75
76
    /**
77
     * @return void
78
     */
79
    private function bootConstraints(): void
80
    {
81
        foreach (static::STANDARD_CONSTRAINTS as $constraint) {
82
            if (! \in_array($constraint, $this->abilities, true)) {
83
                $this->constraints[] = $constraint;
84
            }
85
        }
86
87
        $this->constraints = \array_unique($this->constraints);
88
    }
89
90
    /**
91
     * @param CompilerInterface $compiler
92
     * @return void
93
     * @throws NotFoundException
94
     * @throws NotReadableException
95
     */
96
    public function load(CompilerInterface $compiler): void
97
    {
98
        $this->includeMany($compiler, $this->types);
99
    }
100
101
    /**
102
     * @param CompilerInterface $compiler
103
     * @param array $names
104
     * @return void
105
     * @throws NotFoundException
106
     * @throws NotReadableException
107
     */
108
    protected function includeMany(CompilerInterface $compiler, array $names): void
109
    {
110
        foreach ($names as $name) {
111
            $this->include($compiler, $name);
112
        }
113
    }
114
115
    /**
116
     * @param CompilerInterface $compiler
117
     * @param string $name
118
     * @return void
119
     * @throws NotFoundException
120
     * @throws NotReadableException
121
     */
122
    protected function include(CompilerInterface $compiler, string $name): void
123
    {
124
        $compiler->preload($this->fromResources($name));
125
    }
126
127
    /**
128
     * @param string $name
129
     * @return FileInterface
130
     * @throws NotFoundException
131
     * @throws NotReadableException
132
     */
133
    protected function fromResources(string $name): FileInterface
134
    {
135
        return File::fromPathname(\sprintf(self::RESOURCES_PATHNAME, $name));
136
    }
137
138
    /**
139
     * @param NodeInterface $node
140
     * @return void
141
     */
142
    public function enter(NodeInterface $node): void
143
    {
144
        foreach ($this->constraints as $constraint) {
145
            $constraint::assert($node, $this);
146
        }
147
    }
148
}
149