Passed
Push — master ( 0971b0...b7d7cf )
by Kirill
03:21
created

AbstractDefinition::fetchOrNull()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
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\Reflection;
11
12
use Railt\Io\Exception\ExternalFileException;
13
use Railt\Io\Readable;
14
use Railt\Reflection\Common\Serializable;
15
use Railt\Reflection\Contracts\Definition;
16
use Railt\Reflection\Contracts\Definition\TypeDefinition;
17
use Railt\Reflection\Contracts\Document as DocumentInterface;
18
use Railt\Reflection\Contracts\Invocation\TypeInvocation;
19
use Railt\Reflection\Contracts\Type as TypeInterface;
20
use Railt\Reflection\Exception\ReflectionException;
21
22
/**
23
 * Class AbstractDefinition
24
 */
25
abstract class AbstractDefinition implements Definition
26
{
27
    use Serializable;
28
29
    /**
30
     * @var Document
31
     */
32
    protected $document;
33
34
    /**
35
     * @var int
36
     */
37
    protected $offset = 0;
38
39
    /**
40
     * @var int|null
41
     */
42
    protected $line;
43
44
    /**
45
     * @var int|null
46
     */
47
    protected $column;
48
49
    /**
50
     * AbstractDefinition constructor.
51
     * @param Document $document
52
     */
53 9
    public function __construct(Document $document)
54
    {
55 9
        $this->document = $document;
56 9
    }
57
58
    /**
59
     * @param TypeInterface $type
60
     * @return bool
61
     */
62
    public static function typeOf(TypeInterface $type): bool
63
    {
64
        return static::getType()->instanceOf($type);
65
    }
66
67
    /**
68
     * @param int $offset
69
     * @return Definition|TypeDefinition|TypeInvocation|$this
70
     */
71 1
    public function withOffset(int $offset): Definition
72
    {
73 1
        $this->offset = $offset;
74
75 1
        return $this;
76
    }
77
78
    /**
79
     * @param int $line
80
     * @return Definition|TypeDefinition|TypeInvocation|$this
81
     */
82 9
    public function withLine(?int $line): Definition
83
    {
84 9
        $this->line = \is_int($line) ? \max(1, $line) : $line;
85
86 9
        return $this;
87
    }
88
    /**
89
     * @param int $column
90
     * @return Definition|TypeDefinition|TypeInvocation|$this
91
     */
92
    public function withColumn(?int $column): Definition
93
    {
94
        $this->column = \is_int($column) ? \max(1, $column) : $column;
95
96
        return $this;
97
    }
98
99
    /**
100
     * @return DocumentInterface
101
     */
102 17
    public function getDocument(): DocumentInterface
103
    {
104 17
        return $this->document;
105
    }
106
107
    /**
108
     * @return int
109
     */
110 65
    public function getLine(): int
111
    {
112 65
        if ($this->line === null) {
113 9
            $this->line = $this->getFile()->getPosition($this->offset)->getLine();
114
        }
115
116 65
        return $this->line;
117
    }
118
119
    /**
120
     * @return Readable
121
     */
122 65
    public function getFile(): Readable
123
    {
124 65
        return $this->document->getFile();
125
    }
126
127
    /**
128
     * @return int
129
     */
130 66
    public function getColumn(): int
131
    {
132 66
        if ($this->column === null) {
133 10
            $this->column = $this->getFile()->getPosition($this->offset)->getColumn();
134
        }
135
136 66
        return $this->column;
137
    }
138
139
    /**
140
     * @return string
141
     */
142
    public function __toString(): string
143
    {
144
        return \sprintf('?<%s>', static::getType());
145
    }
146
147
    /**
148
     * @param string|TypeDefinition $type
149
     * @return TypeDefinition
150
     * @throws ExternalFileException
151
     */
152 17
    protected function fetch($type): TypeDefinition
153
    {
154
        switch (true) {
155 17
            case \is_string($type):
156 17
                return $this->document->getDictionary()->get($type, $this);
157
158 17
            case $type instanceof TypeDefinition:
159 17
                return $type;
160
        }
161
162
        throw (new ReflectionException('Unsupported argument'))
163
            ->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
164
    }
165
166
    /**
167
     * @param string|TypeDefinition|null $type
168
     * @return null|TypeDefinition
169
     * @throws ExternalFileException
170
     */
171
    protected function fetchOrNull($type): ?TypeDefinition
172
    {
173
        return $type === null ? $this->fetch($type) : null;
174
    }
175
176
    /**
177
     * @param \Throwable $error
178
     * @return ExternalFileException
179
     */
180 64
    protected function error(\Throwable $error): ExternalFileException
181
    {
182 64
        if (! $error instanceof ExternalFileException) {
183
            $error = new ReflectionException($error->getMessage(), $error->getCode(), $error);
184
        }
185
186 64
        return $error->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
187
    }
188
}
189