Repository navigation
Expand file tree
/
Copy pathHunks.php
More file actions
84 lines (69 loc) · 2.13 KB
/
Copy pathHunks.php
File metadata and controls
84 lines (69 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?php
declare(strict_types=1);
namespace Pharaonic\Diff\Text;
use Pharaonic\Diff\ChangeType;
use Pharaonic\Diff\DiffLine;
use Pharaonic\Diff\Hunk;
/**
* Groups aligned lines into hunks: each change gets up to $context unchanged lines on both sides,
* and changes separated by at most twice that many unchanged lines share one hunk.
*
* @internal
*/
final class Hunks
{
/**
* @param list<DiffLine> $lines
*
* @return list<Hunk>
*/
public static function build(array $lines, int $context): array
{
$ranges = [];
foreach ($lines as $index => $line) {
if ($line->type() === ChangeType::UNCHANGED) {
continue;
}
$last = count($ranges) - 1;
if ($last >= 0 && $index - $ranges[$last][1] - 1 <= 2 * $context) {
$ranges[$last][1] = $index;
} else {
$ranges[] = [$index, $index];
}
}
$hunks = [];
$count = count($lines);
foreach ($ranges as [$first, $last]) {
$start = max(0, $first - $context);
$end = min($count - 1, $last + $context);
$hunks[] = self::hunk($lines, $start, $end);
}
return $hunks;
}
/**
* @param list<DiffLine> $lines
*/
private static function hunk(array $lines, int $start, int $end): Hunk
{
$oldBefore = 0;
$newBefore = 0;
for ($i = 0; $i < $start; $i++) {
$oldBefore += $lines[$i]->oldLineNumber() === null ? 0 : 1;
$newBefore += $lines[$i]->newLineNumber() === null ? 0 : 1;
}
$hunkLines = array_slice($lines, $start, $end - $start + 1);
$oldLength = 0;
$newLength = 0;
foreach ($hunkLines as $line) {
$oldLength += $line->oldLineNumber() === null ? 0 : 1;
$newLength += $line->newLineNumber() === null ? 0 : 1;
}
return new Hunk(
$oldLength === 0 ? $oldBefore : $oldBefore + 1,
$oldLength,
$newLength === 0 ? $newBefore : $newBefore + 1,
$newLength,
$hunkLines,
);
}
}