Specification::include()   A
last analyzed

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