Test Failed
Push — master ( 690100...f55788 )
by Kirill
09:19
created

Type::isInputable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
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\IR;
11
12
/**
13
 * @method static static|TypeInterface|Type scalar()
14
 * @method static static|TypeInterface|Type object()
15
 * @method static static|TypeInterface|Type directive()
16
 * @method static static|TypeInterface|Type directiveLocation()
17
 * @method static static|TypeInterface|Type interface()
18
 * @method static static|TypeInterface|Type union()
19
 * @method static static|TypeInterface|Type enum()
20
 * @method static static|TypeInterface|Type input()
21
 * @method static static|TypeInterface|Type inputUnion()
22
 * @method static static|TypeInterface|Type schema()
23
 * @method static static|TypeInterface|Type enumValue()
24
 * @method static static|TypeInterface|Type field()
25
 * @method static static|TypeInterface|Type argument()
26
 * @method static static|TypeInterface|Type inputField()
27
 * @method static static|TypeInterface|Type document()
28
 * @method static static|TypeInterface|Type any()
29
 */
30
class Type implements TypeInterface
31
{
32
    /**
33
     * @var Type[]
34
     */
35
    private static $instances = [];
36
37
    /**
38
     * @var array[]|string[][]
39
     */
40
    private static $inheritance = [];
41
42
    /**
43
     * @var string
44
     */
45
    protected $name;
46
47
    /**
48
     * @var array|string[]
49
     */
50
    private $parent;
51
52
    /**
53
     * BaseType constructor.
54
     * @param string $name
55
     */
56
    private function __construct(string $name)
57
    {
58
        \assert(self::isValid($name), 'Invalid type ' . $name);
59
60
        $this->name   = $name;
61
        $this->parent = $this->getInheritanceSequence($name);
62
    }
63
64
    /**
65
     * @param string $name
66
     * @return array
67
     */
68
    private function getInheritanceSequence(string $name): array
69
    {
70
        if (self::$inheritance === []) {
71
            $this->bootInheritance(new \SplStack(), static::INHERITANCE_TREE);
72
        }
73
74
        return self::$inheritance[$name] ?? [static::ROOT_TYPE];
75
    }
76
77
    /**
78
     * @param \SplStack $stack
79
     * @param array $children
80
     */
81
    private function bootInheritance(\SplStack $stack, array $children = []): void
82
    {
83
        $push = function (string $type) use ($stack): void {
84
            self::$inheritance[$type]   = \array_values(\iterator_to_array($stack));
85
            self::$inheritance[$type][] = static::ROOT_TYPE;
86
87
            $stack->push($type);
88
        };
89
90
        foreach ($children as $type => $child) {
91
            switch (true) {
92
                case \is_string($child):
93
                    $push($child);
94
                    break;
95
96
                case \is_array($child):
97
                    $push($type);
98
                    $this->bootInheritance($stack, $child);
99
                    break;
100
            }
101
102
            /** @noinspection DisconnectedForeachInstructionInspection */
103
            $stack->pop();
104
        }
105
    }
106
107
    /**
108
     * @param string|ProvidesType $type
109
     * @return TypeInterface
110
     */
111
    public static function of($type): TypeInterface
112
    {
113
        switch (true) {
114
            case \is_string($type):
115
                return self::$instances[$type] ?? (self::$instances[$type] = new static($type));
116
117
            case $type instanceof TypeInterface:
118
                return $type;
119
120
            case $type instanceof ProvidesType:
0 ignored issues
show
Bug introduced by
The class Railt\SDL\IR\ProvidesType does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
121
                return $type->getType();
122
        }
123
124
        return static::of(static::ANY);
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130
    public function isInputable(): bool
131
    {
132
        return \in_array($this->name, static::ALLOWS_TO_INPUT, true);
133
    }
134
135
    /**
136
     * {@inheritDoc}
137
     */
138
    public function isReturnable(): bool
139
    {
140
        return \in_array($this->name, static::ALLOWS_TO_OUTPUT, true);
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146
    public function isDependent(): bool
147
    {
148
        return \in_array($this->name, static::DEPENDENT_TYPES, true);
149
    }
150
151
    /**
152
     * {@inheritDoc}
153
     */
154
    public function instanceOf(TypeInterface $type): bool
155
    {
156
        $needle = $type->getName();
157
158
        return $this->is($needle) || \in_array($needle, $this->parent, true);
159
    }
160
161
    /**
162
     * {@inheritDoc}
163
     */
164
    public function is(string $type): bool
165
    {
166
        return $this->getName() === $type;
167
    }
168
169
    /**
170
     * {@inheritDoc}
171
     */
172
    public function getName(): string
173
    {
174
        return $this->name;
175
    }
176
177
    /**
178
     * {@inheritDoc}
179
     */
180
    public function __toString(): string
181
    {
182
        return $this->getName();
183
    }
184
185
    /**
186
     * {@inheritDoc}
187
     */
188
    public static function isValid(string $name): bool
189
    {
190
        return \in_array($name, static::all(), true);
191
    }
192
193
    /**
194
     * @param string $name
195
     * @param array $arguments
196
     * @return TypeInterface
197
     */
198
    public static function __callStatic(string $name, array $arguments = [])
199
    {
200
        foreach (static::all() as $type) {
201
            if (\strtolower($type) === \strtolower($name)) {
202
                return static::of($type);
203
            }
204
        }
205
206
        return static::of(static::ANY);
207
    }
208
209
    /**
210
     * @return array
211
     */
212
    public static function all(): array
213
    {
214
        return \array_merge(static::DEPENDENT_TYPES, static::ROOT_TYPES);
215
    }
216
}
217