Test Failed
Push — master ( 16c39a...9c7d46 )
by Kirill
07:07
created

Type::jsonSerialize()   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\Frontend\Type;
11
12
/**
13
 * Class Type
14
 */
15
class Type implements TypeInterface, \JsonSerializable
16
{
17
    /**
18
     * @var TypeNameInterface
19
     */
20
    private $type;
21
22
    /**
23
     * @var array
24
     */
25
    private static $inheritance = [];
26
27
    /**
28
     * @var array|string[]
29
     */
30
    private $parent;
31
32
    /**
33
     * Type constructor.
34
     * @param TypeNameInterface $type
35
     */
36
    private function __construct(TypeNameInterface $type)
37
    {
38
        $this->type = $type;
39
        $this->parent = $this->getInheritanceSequence($type->getFullyQualifiedName());
40
    }
41
42
    /**
43
     * @param string $name
44
     * @return array
45
     */
46
    private function getInheritanceSequence(string $name): array
47
    {
48
        if (self::$inheritance === []) {
49
            $this->bootInheritance(new \SplStack(), static::INHERITANCE_TREE);
50
        }
51
52
        return self::$inheritance[$name] ?? [static::ROOT_TYPE];
53
    }
54
55
    /**
56
     * @param \SplStack $stack
57
     * @param array $children
58
     */
59
    private function bootInheritance(\SplStack $stack, array $children = []): void
60
    {
61
        $push = function (string $type) use ($stack): void {
62
            self::$inheritance[$type]   = \array_values(\iterator_to_array($stack));
63
            self::$inheritance[$type][] = static::ROOT_TYPE;
64
65
            $stack->push($type);
66
        };
67
68
        foreach ($children as $type => $child) {
69
            switch (true) {
70
                case \is_string($child):
71
                    $push($child);
72
                    break;
73
74
                case \is_array($child):
75
                    $push($type);
76
                    $this->bootInheritance($stack, $child);
77
                    break;
78
            }
79
80
            $stack->pop();
81
        }
82
    }
83
84
    /**
85
     * @param TypeNameInterface $name
86
     * @return TypeInterface
87
     */
88
    public static function of(TypeNameInterface $name): TypeInterface
89
    {
90
        return new static($name);
91
    }
92
93
    /**
94
     * @return TypeNameInterface
95
     */
96
    public function getName(): TypeNameInterface
97
    {
98
        return $this->type;
99
    }
100
101
    /**
102
     * {@inheritDoc}
103
     */
104
    public function is(TypeInterface $type): bool
105
    {
106
        return $this->getName() === $type;
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
107
    }
108
109
    /**
110
     * {@inheritDoc}
111
     */
112
    public function instanceOf(TypeInterface $type): bool
113
    {
114
        $needle = $type->getName()->getFullyQualifiedName();
115
116
        return $this->is($type) || \in_array($needle, $this->parent, true);
117
    }
118
119
    /**
120
     * @return string
121
     */
122
    public function jsonSerialize(): string
123
    {
124
        return $this->getName()->getFullyQualifiedName();
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
125
    }
126
}
127