Skip to content

Commit 39659f4

Browse files
committed
Smaller diff representation in result cache
1 parent 7b68603 commit 39659f4

File tree

5 files changed

+77
-9
lines changed

5 files changed

+77
-9
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ phpstan-result-cache:
125125
php -d memory_limit=448M bin/phpstan
126126

127127
phpstan-fix:
128-
php -d memory_limit=2G bin/phpstan --fix
128+
php -d memory_limit=448M bin/phpstan --fix
129129

130130
phpstan-generate-baseline:
131131
php -d memory_limit=448M bin/phpstan --generate-baseline

conf/services.neon

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ services:
162162

163163
-
164164
class: SebastianBergmann\Diff\Differ
165+
arguments:
166+
outputBuilder: @SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder
167+
168+
-
169+
class: SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder
170+
arguments:
171+
header: ''
172+
addLineNumbers: true
165173

166174
betterReflectionSourceLocator:
167175
class: PHPStan\BetterReflection\SourceLocator\Type\SourceLocator

src/Analyser/FixedErrorDiff.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,12 @@
22

33
namespace PHPStan\Analyser;
44

5-
use SebastianBergmann\Diff\Differ;
6-
75
final class FixedErrorDiff
86
{
97

10-
/**
11-
* @param array<array{mixed, Differ::OLD|Differ::ADDED|Differ::REMOVED}> $diff
12-
*/
138
public function __construct(
149
public readonly string $originalHash,
15-
public readonly array $diff,
10+
public readonly string $diff,
1611
)
1712
{
1813
}

src/Analyser/RuleErrorTransformer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public function transform(
130130
$printer = new PhpPrinter(['indent' => str_repeat($indentDetector->indentCharacter, $indentDetector->indentSize)]);
131131
$newCode = $printer->printFormatPreserving($newStmts, $fileNodes, $oldTokens);
132132

133-
$fixedErrorDiff = new FixedErrorDiff($hash, $this->differ->diffToArray($oldCode, $newCode));
133+
$fixedErrorDiff = new FixedErrorDiff($hash, $this->differ->diff($oldCode, $newCode));
134134
}
135135

136136
return new Error(

src/Fixable/Patcher.php

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use function count;
1717
use function implode;
1818
use function sha1;
19+
use function str_starts_with;
20+
use function substr;
1921
use const PREG_SPLIT_DELIM_CAPTURE;
2022
use const PREG_SPLIT_NO_EMPTY;
2123

@@ -42,7 +44,7 @@ public function applyDiffs(string $fileName, array $diffs): string
4244
throw new FileChangedException();
4345
}
4446

45-
$diffHunks[] = Hunk::createArray(Line::createArray($diff->diff));
47+
$diffHunks[] = Hunk::createArray(Line::createArray($this->reconstructFullDiff($fileContents, $diff->diff)));
4648
}
4749

4850
if (count($diffHunks) === 0) {
@@ -90,6 +92,69 @@ public function applyDiffs(string $fileName, array $diffs): string
9092
return implode('', array_map(static fn ($l) => $l->getContent(), $result));
9193
}
9294

95+
/**
96+
* @return array<array{mixed, Differ::OLD|Differ::ADDED|Differ::REMOVED}>
97+
*/
98+
private function reconstructFullDiff(string $originalText, string $unifiedDiff): array
99+
{
100+
$originalLines = self::splitStringByLines($originalText);
101+
$diffLines = self::splitStringByLines($unifiedDiff);
102+
$result = [];
103+
104+
$origLineNo = 0;
105+
$diffPos = 0;
106+
107+
while ($diffPos < count($diffLines)) {
108+
$line = $diffLines[$diffPos];
109+
110+
$matches = Strings::match($line, '/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/');
111+
if ($matches !== null) {
112+
// Parse hunk header
113+
$origStart = (int) $matches[1] - 1; // 0-based
114+
$diffPos++;
115+
116+
// Emit kept lines before hunk
117+
while ($origLineNo < $origStart) {
118+
$result[] = [$originalLines[$origLineNo], Differ::OLD];
119+
$origLineNo++;
120+
}
121+
122+
// Process hunk
123+
while ($diffPos < count($diffLines)) {
124+
$line = $diffLines[$diffPos];
125+
if (str_starts_with($line, '@@')) {
126+
break; // next hunk
127+
}
128+
129+
$prefix = $line[0] ?? '';
130+
$content = substr($line, 1);
131+
132+
if ($prefix === ' ') {
133+
$result[] = [$content, Differ::OLD];
134+
$origLineNo++;
135+
} elseif ($prefix === '-') {
136+
$result[] = [$content, Differ::REMOVED];
137+
$origLineNo++;
138+
} elseif ($prefix === '+') {
139+
$result[] = [$content, Differ::ADDED];
140+
}
141+
142+
$diffPos++;
143+
}
144+
} else {
145+
$diffPos++;
146+
}
147+
}
148+
149+
// Emit remaining lines as kept
150+
while ($origLineNo < count($originalLines)) {
151+
$result[] = [$originalLines[$origLineNo], Differ::OLD];
152+
$origLineNo++;
153+
}
154+
155+
return $result;
156+
}
157+
93158
/**
94159
* @return string[]
95160
*/

0 commit comments

Comments
 (0)