Test Failed
Push — master ( 1b72cc...b6de3d )
by Kirill
05:40
created

AbstractDefinition::getLine()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
191 9
                return $type;
192
193 25
            case $type instanceof TypeDefinition:
194 25
                return $type->getName();
195
        }
196
197
        throw (new ReflectionException('Unsupported argument'))
198
            ->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
199
    }
200
201
    /**
202
     * @param string|TypeDefinition|null $type
203
     * @return null|TypeDefinition
204
     * @throws ExternalFileException
205
     */
206
    protected function fetchOrNull($type): ?TypeDefinition
207
    {
208
        return $type === null ? $this->fetch($type) : null;
209
    }
210
211
    /**
212
     * @param \Throwable $error
213
     * @return ExternalFileException
214
     */
215
    protected function error(\Throwable $error): ExternalFileException
216
    {
217
        if (! $error instanceof ExternalFileException) {
218
            $error = new ReflectionException($error->getMessage(), $error->getCode(), $error);
219
        }
220
221
        return $error->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
222
    }
223
}
224