Completed
Push — master ( 96cbf3...9bcdfc )
by Steve
03:03 queued 01:23
created

RangeDifference::__toString()   B

Complexity

Conditions 9
Paths 14

Size

Total Lines 43
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

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