Completed
Push — master ( 3a6c0f...94b851 )
by Kirill
03:45
created

AbstractDefinition::getColumn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2
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 65
    public function getLine(): int
113
    {
114 65
        if ($this->line === null) {
115 9
            $this->line = $this->getFile()->getPosition($this->offset)->getLine();
116
        }
117
118 65
        return $this->line;
119
    }
120
121
    /**
122
     * @return Readable
123
     */
124 65
    public function getFile(): Readable
125
    {
126 65
        return $this->document->getFile();
127
    }
128
129
    /**
130
     * @return int
131
     */
132 66
    public function getColumn(): int
133
    {
134 66
        if ($this->column === null) {
135 10
            $this->column = $this->getFile()->getPosition($this->offset)->getColumn();
136
        }
137
138 66
        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|null $type
170
     * @return null|TypeDefinition
171
     * @throws ExternalFileException
172
     */
173
    protected function fetchOrNull($type): ?TypeDefinition
174
    {
175
        return $type === null ? $this->fetch($type) : null;
176
    }
177
178
    /**
179
     * @param \Throwable $error
180
     * @return ExternalFileException
181
     */
182 64
    protected function error(\Throwable $error): ExternalFileException
183
    {
184 64
        if (! $error instanceof ExternalFileException) {
185
            $error = new ReflectionException($error->getMessage(), $error->getCode(), $error);
186
        }
187
188 64
        return $error->throwsIn($this->getFile(), $this->getLine(), $this->getColumn());
189
    }
190
}
191