Test Failed
Push — master ( ee8b01...2ca085 )
by Kirill
03:55
created

AbstractDefinition::withOffset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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 $type
62
     * @return bool
63
     */
64
    public static function typeOf(TypeInterface $type): bool
65
    {
66
        return static::getType()->instanceOf($type);
67
    }
68
69
    /**
70
     * @param int $offset
71
     * @return Definition|TypeDefinition|TypeInvocation|$this
72
     */
73 1
    public function withOffset(int $offset): Definition
74
    {
75 1
        $this->offset = $offset;
76
77 1
        return $this;
78
    }
79
80
    /**
81
     * @param int $line
82
     * @return Definition|TypeDefinition|TypeInvocation|$this
83
     */
84 9
    public function withLine(?int $line): Definition
85
    {
86 9
        $this->line = \is_int($line) ? \max(1, $line) : $line;
87
88 9
        return $this;
89
    }
90
    /**
91
     * @param int $column
92
     * @return Definition|TypeDefinition|TypeInvocation|$this
93
     */
94
    public function withColumn(?int $column): Definition
95
    {
96
        $this->column = \is_int($column) ? \max(1, $column) : $column;
97
98
        return $this;
99
    }
100
101
    /**
102
     * @return DocumentInterface
103
     */
104 17
    public function getDocument(): DocumentInterface
105
    {
106 17
        return $this->document;
107
    }
108
109
    /**
110
     * @return int
111
     */
112 1
    public function getLine(): int
113
    {
114 1
        if ($this->line === null) {
115 1
            $this->line = $this->getFile()->getPosition($this->offset)->getLine();
116
        }
117
118 1
        return $this->line;
119
    }
120
121
    /**
122
     * @return Readable
123
     */
124 1
    public function getFile(): Readable
125
    {
126 1
        return $this->document->getFile();
127
    }
128
129
    /**
130
     * @return int
131
     */
132 2
    public function getColumn(): int
133
    {
134 2
        if ($this->column === null) {
135 2
            $this->column = $this->getFile()->getPosition($this->offset)->getColumn();
136
        }
137
138 2
        return $this->column;
139
    }
140
141
    /**
142
     * @return string
143
     */
144
    public function __toString(): string
145
    {
146
        return \sprintf('?<%s>', static::getType());
147
    }
148
149
    /**
150
     * @param string|TypeDefinition $type
151
     * @return TypeDefinition
152
     * @throws ExternalFileException
153
     */
154 10
    protected function fetch($type): TypeDefinition
155
    {
156
        switch (true) {
157 10
            case \is_string($type):
158 10
                return $this->document->getDictionary()->get($type, $this);
159
160 8
            case $type instanceof TypeDefinition:
161 8
                return $type;
162
        }
163
164
        throw (new ReflectionException('Unsupported argument'))
165
            ->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
166
    }
167
168
    /**
169
     * @param string|TypeDefinition $type
170
     * @return string|null
171
     * @throws ExternalFileException
172
     */
173 89
    protected function nameOf($type): ?string
174
    {
175
        switch (true) {
176 89
            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...
177 9
                return $type;
178
179 89
            case $type instanceof TypeDefinition:
180 89
                return $type->getName();
181
        }
182
183
        throw (new ReflectionException('Unsupported argument'))
184
            ->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
185
    }
186
187
    /**
188
     * @param string|TypeDefinition|null $type
189
     * @return null|TypeDefinition
190
     * @throws ExternalFileException
191
     */
192
    protected function fetchOrNull($type): ?TypeDefinition
193
    {
194
        return $type === null ? $this->fetch($type) : null;
195
    }
196
197
    /**
198
     * @param \Throwable $error
199
     * @return ExternalFileException
200
     */
201
    protected function error(\Throwable $error): ExternalFileException
202
    {
203
        if (! $error instanceof ExternalFileException) {
204
            $error = new ReflectionException($error->getMessage(), $error->getCode(), $error);
205
        }
206
207
        return $error->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
208
    }
209
}
210