1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-01 18:30:59 +01:00

Fix metadata rendering for files moves, etc.

Summary:
Some changeset metadata was not being correctly passed between the top-level
parser and the subparser, so it would be lost or incorrect when rendering
headers like "This file was moved from x to y." or rendering certain content
shields, like "the contents of this file were not modified".

Test Plan:
Created a new diff with a file move in it, rendered it, saw "This file was moved
from README to READYOU" correctly.

Reviewed By: aran
Reviewers: tuomaspelkonen, jungejason, grglr, aran
CC: aran, epriestley
Differential Revision: 321
This commit is contained in:
epriestley 2011-05-20 20:40:00 -07:00
parent d202e71ef1
commit b77e827bec

View file

@ -38,7 +38,6 @@ class DifferentialChangesetParser {
protected $whitespaceMode = null; protected $whitespaceMode = null;
protected $subparser; protected $subparser;
protected $noHighlight;
protected $renderCacheKey = null; protected $renderCacheKey = null;
@ -52,6 +51,7 @@ class DifferentialChangesetParser {
private $rightSideAttachesToNewFile; private $rightSideAttachesToNewFile;
private $renderingReference; private $renderingReference;
private $isSubparser;
const CACHE_VERSION = 4; const CACHE_VERSION = 4;
@ -355,6 +355,32 @@ class DifferentialChangesetParser {
$this->old = $old; $this->old = $old;
$this->new = $new; $this->new = $new;
$unchanged = false;
if ($this->subparser) {
$unchanged = $this->subparser->isUnchanged();
$whitelines = $this->subparser->isWhitespaceOnly();
} else if (!$changed) {
$filetype = $this->changeset->getFileType();
if ($filetype == DifferentialChangeType::FILE_TEXT ||
$filetype == DifferentialChangeType::FILE_SYMLINK) {
$unchanged = true;
}
}
$this->specialAttributes = array(
self::ATTR_UNCHANGED => $unchanged,
self::ATTR_DELETED => array_filter($this->old) &&
!array_filter($this->new),
self::ATTR_WHITELINES => $whitelines
);
if ($this->isSubparser) {
// The rest of this function deals with formatting the diff for display;
// we can exit early if we're a subparser and avoid doing extra work.
return;
}
if ($this->subparser) { if ($this->subparser) {
// Use this parser's side-by-side line information -- notably, the // Use this parser's side-by-side line information -- notably, the
@ -431,29 +457,24 @@ class DifferentialChangesetParser {
$new_corpus = ipull($this->new, 'text'); $new_corpus = ipull($this->new, 'text');
$new_corpus_block = implode("\n", $new_corpus); $new_corpus_block = implode("\n", $new_corpus);
if ($this->noHighlight) { $old_future = $this->getHighlightFuture($old_corpus_block);
$this->oldRender = explode("\n", phutil_escape_html($old_corpus_block)); $new_future = $this->getHighlightFuture($new_corpus_block);
$this->newRender = explode("\n", phutil_escape_html($new_corpus_block)); $futures = array(
} else { 'old' => $old_future,
$old_future = $this->getHighlightFuture($old_corpus_block); 'new' => $new_future,
$new_future = $this->getHighlightFuture($new_corpus_block); );
$futures = array( foreach (Futures($futures) as $key => $future) {
'old' => $old_future, switch ($key) {
'new' => $new_future, case 'old':
); $this->oldRender = $this->processHighlightedSource(
foreach (Futures($futures) as $key => $future) { $this->old,
switch ($key) { $future->resolve());
case 'old': break;
$this->oldRender = $this->processHighlightedSource( case 'new':
$this->old, $this->newRender = $this->processHighlightedSource(
$future->resolve()); $this->new,
break; $future->resolve());
case 'new': break;
$this->newRender = $this->processHighlightedSource(
$this->new,
$future->resolve());
break;
}
} }
} }
@ -469,27 +490,9 @@ class DifferentialChangesetParser {
$this->tokenHighlight($this->oldRender); $this->tokenHighlight($this->oldRender);
$this->tokenHighlight($this->newRender); $this->tokenHighlight($this->newRender);
$unchanged = false;
if ($this->subparser) {
$unchanged = $this->subparser->isUnchanged();
$whitelines = $this->subparser->isWhitespaceOnly();
} else if (!$changed) {
$filetype = $this->changeset->getFileType();
if ($filetype == DifferentialChangeType::FILE_TEXT ||
$filetype == DifferentialChangeType::FILE_SYMLINK) {
$unchanged = true;
}
}
$generated = (strpos($new_corpus_block, '@'.'generated') !== false); $generated = (strpos($new_corpus_block, '@'.'generated') !== false);
$this->specialAttributes = array( $this->specialAttributes[self::ATTR_GENERATED] = $generated;
self::ATTR_GENERATED => $generated,
self::ATTR_UNCHANGED => $unchanged,
self::ATTR_DELETED => array_filter($this->old) &&
!array_filter($this->new),
self::ATTR_WHITELINES => $whitelines
);
} }
public function loadCache() { public function loadCache() {
@ -741,18 +744,31 @@ EOSYNTHETIC;
} }
// subparser takes over the current non-whitespace-ignoring changeset // subparser takes over the current non-whitespace-ignoring changeset
$this->subparser = new DifferentialChangesetParser(); $subparser = new DifferentialChangesetParser();
$subparser->isSubparser = true;
$subparser->setChangeset($changeset);
foreach ($changeset->getHunks() as $hunk) { foreach ($changeset->getHunks() as $hunk) {
$this->subparser->parseHunk($hunk); $subparser->parseHunk($hunk);
} }
// We need to call process() so that the subparser's values for
// things like.
$subparser->process();
$this->subparser = $subparser;
// this parser takes new changeset; will use subparser's text later // this parser takes new changeset; will use subparser's text later
$changes = id(new ArcanistDiffParser())->parseDiff($diff); $changes = id(new ArcanistDiffParser())->parseDiff($diff);
$diff = DifferentialDiff::newFromRawChanges($changes); $diff = DifferentialDiff::newFromRawChanges($changes);
$changesets = $diff->getChangesets();
$changeset = reset($changesets); // While we aren't updating $this->changeset (since it has a bunch
$this->setChangeset($changeset); // of metadata we need to preserve, so that headers like "this file
// was moved" render correctly), we're overwriting the local
// $changeset so that the block below will choose the synthetic
// hunks we've built instead of the original hunks.
$changeset = head($diff->getChangesets());
} }
// This either uses the real hunks, or synthetic hunks we built above.
foreach ($changeset->getHunks() as $hunk) { foreach ($changeset->getHunks() as $hunk) {
$this->parseHunk($hunk); $this->parseHunk($hunk);
} }