RangeDifference   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 75
c 1
b 0
f 0
dl 0
loc 257
ccs 73
cts 73
cp 1
rs 10
wmc 30

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getRightEnd() 0 3 1
A getLeftEnd() 0 3 1
A getMaxLength() 0 6 1
B isEqual() 0 10 7
A getAncestorEnd() 0 3 1
A getRightLength() 0 3 1
A getLeftLength() 0 3 1
A getAncestorStart() 0 3 1
A getAncestorLength() 0 3 1
A getLeftStart() 0 3 1
A getKind() 0 3 1
A __construct() 0 21 3
A getRightStart() 0 3 1
B __toString() 0 43 9
1
<?php
2
/**
3
 * (c) Steve Nebes <[email protected]>
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
declare(strict_types=1);
10
11
namespace SN\RangeDifferencer;
12
13
/**
14
 * Description of a change between two or three ranges of comparable entities.
15
 *
16
 * RangeDifference objects are the elements of a compare result returned from
17
 * the RangeDifferencer find* methods. Clients use these objects as they are
18
 * returned from the differencer. This class is not intended to be instantiated
19
 * outside of the Compare framework.
20
 *
21
 * Note: A range in the RangeDifference object is given as a start index and
22
 * length in terms of comparable entities. However, these entity indices and
23
 * counts are not necessarily character positions. For example, if an entity
24
 * represents a line in a document, the start index would be a line number and
25
 * the count would be in lines.
26
 */
27
class RangeDifference
28
{
29
    /**
30
     * @const int Two-way change constant indicating no change.
31
     */
32
    const NOCHANGE = 0;
33
34
    /**
35
     * @const int Three-way change constant indicating a change in both right
36
     *            and left.
37
     */
38
    const CONFLICT = 1;
39
40
    /**
41
     * @const int Two-way change constant indicating two-way change (same as
42
     *            RIGHT)
43
     */
44
    const CHANGE = 2;
45
46
    /**
47
     * @const int Three-way change constant indicating a change in right.
48
     */
49
    const RIGHT = 2;
50
51
    /**
52
     * @const int Three-way change constant indicating a change in left.
53
     */
54
    const LEFT = 3;
55
56
    /**
57
     * @const int Three-way change constant indicating the same change in both
58
     *            right and left, that is only the ancestor is different.
59
     */
60
    const ANCESTOR = 4;
61
62
    /**
63
     * @const int Indicates an unknown change kind.
64
     */
65
    const ERROR = 5;
66
67
    /**
68
     * @var int Kind of change.
69
     */
70
    private $kind = self::NOCHANGE;
71
72
    /** @var int */
73
    private $leftStart = 0;
74
75
    /** @var int */
76
    private $leftLength = 0;
77
78
    /** @var int */
79
    private $rightStart = 0;
80
81
    /** @var int */
82
    private $rightLength = 0;
83
84
    /** @var int */
85
    private $ancestorStart = 0;
86
87
    /** @var int */
88
    private $ancestorLength = 0;
89
90
    /**
91
     * Default values.
92
     *
93
     * @param int $kind
94
     * @param int $rightStart
95
     * @param int $rightLength
96
     * @param int $leftStart
97
     * @param int $leftLength
98
     * @param int $ancestorStart
99
     * @param int $ancestorLength
100
     *
101
     * @throws \UnexpectedValueException
102
     */
103 27
    public function __construct(
104
        int $kind,
105
        int $rightStart = 0,
106
        int $rightLength = 0,
107
        int $leftStart = 0,
108
        int $leftLength = 0,
109
        int $ancestorStart = 0,
110
        int $ancestorLength = 0
111
    )
112
    {
113 27
        if ($kind < 0 || $kind > 5) {
114 1
            throw new \UnexpectedValueException();
115
        }
116
117 26
        $this->kind = $kind;
118 26
        $this->rightStart = $rightStart;
119 26
        $this->rightLength = $rightLength;
120 26
        $this->leftStart = $leftStart;
121 26
        $this->leftLength = $leftLength;
122 26
        $this->ancestorStart = $ancestorStart;
123 26
        $this->ancestorLength = $ancestorLength;
124 26
    }
125
126
    /**
127
     * @return int
128
     */
129 2
    public function getKind(): int
130
    {
131 2
        return $this->kind;
132
    }
133
134
    /**
135
     * @return int
136
     */
137 8
    public function getLeftStart(): int
138
    {
139 8
        return $this->leftStart;
140
    }
141
142
    /**
143
     * @return int
144
     */
145 7
    public function getLeftLength(): int
146
    {
147 7
        return $this->leftLength;
148
    }
149
150
    /**
151
     * @return int
152
     */
153 3
    public function getLeftEnd(): int
154
    {
155 3
        return $this->leftStart + $this->leftLength;
156
    }
157
158
    /**
159
     * @return int
160
     */
161 8
    public function getRightStart(): int
162
    {
163 8
        return $this->rightStart;
164
    }
165
166
    /**
167
     * @return int
168
     */
169 6
    public function getRightLength(): int
170
    {
171 6
        return $this->rightLength;
172
    }
173
174
    /**
175
     * @return int
176
     */
177 3
    public function getRightEnd(): int
178
    {
179 3
        return $this->rightStart + $this->rightLength;
180
    }
181
182
    /**
183
     * @return int
184
     */
185 2
    public function getAncestorStart(): int
186
    {
187 2
        return $this->ancestorStart;
188
    }
189
190
    /**
191
     * @return int
192
     */
193 2
    public function getAncestorLength(): int
194
    {
195 2
        return $this->ancestorLength;
196
    }
197
198
    /**
199
     * @return int
200
     */
201 2
    public function getAncestorEnd(): int
202
    {
203 2
        return $this->ancestorStart + $this->ancestorLength;
204
    }
205
206
    /**
207
     * Returns the maximum number of entities in the left, right, and ancestor
208
     * sides of this range.
209
     *
210
     * @return int
211
     */
212 2
    public function getMaxLength(): int
213
    {
214 2
        return \max(
215 2
            $this->rightLength,
216 2
            $this->leftLength,
217 2
            $this->ancestorLength);
218
    }
219
220
    /**
221
     * Compare equality of RangeDifference objects.
222
     *
223
     * @param RangeDifference $other
224
     * @return bool
225
     */
226 1
    public function isEqual(RangeDifference $other): bool
227
    {
228
        return
229 1
            $this->kind === $other->getKind() &&
230 1
            $this->leftStart === $other->getLeftStart() &&
231 1
            $this->leftLength === $other->getLeftLength() &&
232 1
            $this->rightStart === $other->getRightStart() &&
233 1
            $this->rightLength === $other->getRightLength() &&
234 1
            $this->ancestorStart === $other->getAncestorStart() &&
235 1
            $this->ancestorLength === $other->getAncestorLength();
236
    }
237
238
    /**
239
     * @return string
240
     */
241 14
    public function __toString(): string
242
    {
243 14
        $buffer = 'RangeDifference {';
244
245 14
        switch ($this->kind) {
246 14
            case self::NOCHANGE:
247 2
                $buffer .= 'NOCHANGE';
248 2
                break;
249
250 14
            case self::CHANGE:
251 14
                $buffer .= 'CHANGE/RIGHT';
252 14
                break;
253
254 2
            case self::CONFLICT:
255 2
                $buffer .= 'CONFLICT';
256 2
                break;
257
258 2
            case self::LEFT:
259 2
                $buffer .= 'LEFT';
260 2
                break;
261
262 1
            case self::ANCESTOR:
263 1
                $buffer .= 'ANCESTOR';
264 1
                break;
265
266 1
            case self::ERROR:
267
            default:
268 1
                $buffer .= 'ERROR';
269 1
                break;
270
        }
271
272 14
        $buffer .= sprintf(', Left: (%d, %d) Right: (%d, %d)',
273 14
            $this->leftStart, $this->leftLength,
274 14
            $this->rightStart, $this->rightLength);
275
276 14
        if ($this->ancestorStart > 0 || $this->ancestorLength > 0) {
277 2
            $buffer .= sprintf(' Ancestor: (%d, %d)',
278 2
                $this->ancestorStart, $this->ancestorLength);
279
        }
280
281 14
        $buffer .= '}';
282
283 14
        return $buffer;
284
    }
285
}
286