Changeset View
Changeset View
Standalone View
Standalone View
src/applications/differential/parser/DifferentialHunkParser.php
<?php | <?php | ||||
final class DifferentialHunkParser extends Phobject { | final class DifferentialHunkParser extends Phobject { | ||||
private $oldLines; | private $oldLines; | ||||
private $newLines; | private $newLines; | ||||
private $intraLineDiffs; | private $intraLineDiffs; | ||||
private $depthOnlyLines; | private $depthOnlyLines; | ||||
private $visibleLinesMask; | private $visibleLinesMask; | ||||
private $normalized; | |||||
/** | /** | ||||
* Get a map of lines on which hunks start, other than line 1. This | * Get a map of lines on which hunks start, other than line 1. This | ||||
* datastructure is used to determine when to render "Context not available." | * datastructure is used to determine when to render "Context not available." | ||||
* in diffs with multiple hunks. | * in diffs with multiple hunks. | ||||
* | * | ||||
* @return dict<int, bool> Map of lines where hunks start, other than line 1. | * @return dict<int, bool> Map of lines where hunks start, other than line 1. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | public function setDepthOnlyLines(array $map) { | ||||
$this->depthOnlyLines = $map; | $this->depthOnlyLines = $map; | ||||
return $this; | return $this; | ||||
} | } | ||||
public function getDepthOnlyLines() { | public function getDepthOnlyLines() { | ||||
return $this->depthOnlyLines; | return $this->depthOnlyLines; | ||||
} | } | ||||
public function setNormalized($normalized) { | |||||
$this->normalized = $normalized; | |||||
return $this; | |||||
} | |||||
public function getNormalized() { | |||||
return $this->normalized; | |||||
} | |||||
public function getIsDeleted() { | public function getIsDeleted() { | ||||
foreach ($this->getNewLines() as $line) { | foreach ($this->getNewLines() as $line) { | ||||
if ($line) { | if ($line) { | ||||
// At least one new line, so the entire file wasn't deleted. | // At least one new line, so the entire file wasn't deleted. | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | while (count($old_lines) || count($new_lines)) { | ||||
$rebuild_old[] = $old_line_data; | $rebuild_old[] = $old_line_data; | ||||
$rebuild_new[] = $new_line_data; | $rebuild_new[] = $new_line_data; | ||||
} | } | ||||
$this->setOldLines($rebuild_old); | $this->setOldLines($rebuild_old); | ||||
$this->setNewLines($rebuild_new); | $this->setNewLines($rebuild_new); | ||||
$this->updateChangeTypesForNormalization(); | |||||
return $this; | return $this; | ||||
} | } | ||||
public function generateIntraLineDiffs() { | public function generateIntraLineDiffs() { | ||||
$old = $this->getOldLines(); | $old = $this->getOldLines(); | ||||
$new = $this->getNewLines(); | $new = $this->getNewLines(); | ||||
$diffs = array(); | $diffs = array(); | ||||
▲ Show 20 Lines • Show All 485 Lines • ▼ Show 20 Lines | for ($ii = 0; $ii < $len; $ii++) { | ||||
} | } | ||||
break; | break; | ||||
} | } | ||||
return $character_depth; | return $character_depth; | ||||
} | } | ||||
private function updateChangeTypesForNormalization() { | |||||
if (!$this->getNormalized()) { | |||||
return; | |||||
} | |||||
// If we've parsed based on a normalized diff alignment, we may currently | |||||
// believe some lines are unchanged when they have actually changed. This | |||||
// happens when: | |||||
// | |||||
// - a line changes; | |||||
// - the change is a kind of change we normalize away when aligning the | |||||
// diff, like an indentation change; | |||||
// - we normalize the change away to align the diff; and so | |||||
// - the old and new copies of the line are now aligned in the new | |||||
// normalized diff. | |||||
// | |||||
// Then we end up with an alignment where the two lines that differ only | |||||
// in some some trivial way are aligned. This is great, and exactly what | |||||
// we're trying to accomplish by doing all this alignment stuff in the | |||||
// first place. | |||||
// | |||||
// However, in this case the correctly-aligned lines will be incorrectly | |||||
// marked as unchanged because the diff alorithm was fed normalized copies | |||||
// of the lines, and these copies truly weren't any different. | |||||
// | |||||
// When lines are aligned and marked identical, but they're not actually | |||||
// identcal, we now mark them as changed. The rest of the processing will | |||||
// figure out how to render them appropritely. | |||||
$new = $this->getNewLines(); | |||||
$old = $this->getOldLines(); | |||||
foreach ($old as $key => $o) { | |||||
$n = $new[$key]; | |||||
if (!$o || !$n) { | |||||
continue; | |||||
} | |||||
if ($o['type'] === null && $n['type'] === null) { | |||||
if ($o['text'] !== $n['text']) { | |||||
$old[$key]['type'] = '-'; | |||||
$new[$key]['type'] = '+'; | |||||
} | |||||
} | |||||
} | |||||
$this->setOldLines($old); | |||||
$this->setNewLines($new); | |||||
} | |||||
} | } |