Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. StrictUnifiedDiffOutputBuilder.php

function StrictUnifiedDiffOutputBuilder::writeDiffHunks

1 call to StrictUnifiedDiffOutputBuilder::writeDiffHunks()
StrictUnifiedDiffOutputBuilder::getDiff in vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php

File

vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php, line 125

Class

StrictUnifiedDiffOutputBuilder
Strict Unified diff output builder.

Namespace

SebastianBergmann\Diff\Output

Code

private function writeDiffHunks($output, array $diff) : void {
    // detect "No newline at end of file" and insert into `$diff` if needed
    $upperLimit = count($diff);
    if (0 === $diff[$upperLimit - 1][1]) {
        $lc = substr($diff[$upperLimit - 1][0], -1);
        if ("\n" !== $lc) {
            array_splice($diff, $upperLimit, 0, [
                [
                    "\n\\ No newline at end of file\n",
                    Differ::NO_LINE_END_EOF_WARNING,
                ],
            ]);
        }
    }
    else {
        // search back for the last `+` and `-` line,
        // check if it has a trailing linebreak, else add a warning under it
        $toFind = [
            1 => true,
            2 => true,
        ];
        for ($i = $upperLimit - 1; $i >= 0; $i--) {
            if (isset($toFind[$diff[$i][1]])) {
                unset($toFind[$diff[$i][1]]);
                $lc = substr($diff[$i][0], -1);
                if ("\n" !== $lc) {
                    array_splice($diff, $i + 1, 0, [
                        [
                            "\n\\ No newline at end of file\n",
                            Differ::NO_LINE_END_EOF_WARNING,
                        ],
                    ]);
                }
                if (!count($toFind)) {
                    break;
                }
            }
        }
    }
    // write hunks to output buffer
    $cutOff = max($this->commonLineThreshold, $this->contextLines);
    $hunkCapture = false;
    $sameCount = $toRange = $fromRange = 0;
    $toStart = $fromStart = 1;
    $i = 0;
    
    /** @var int $i */
    foreach ($diff as $i => $entry) {
        if (0 === $entry[1]) {
            // same
            if (false === $hunkCapture) {
                $fromStart++;
                $toStart++;
                continue;
            }
            $sameCount++;
            $toRange++;
            $fromRange++;
            if ($sameCount === $cutOff) {
                $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
                // note: $contextEndOffset = $this->contextLines;
                //
                // because we never go beyond the end of the diff.
                // with the cutoff/contextlines here the follow is never true;
                //
                // if ($i - $cutOff + $this->contextLines + 1 > \count($diff)) {
                //    $contextEndOffset = count($diff) - 1;
                // }
                //
                // ; that would be true for a trailing incomplete hunk case which is dealt with after this loop
                $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $cutOff + $this->contextLines + 1, $fromStart - $contextStartOffset, $fromRange - $cutOff + $contextStartOffset + $this->contextLines, $toStart - $contextStartOffset, $toRange - $cutOff + $contextStartOffset + $this->contextLines, $output);
                $fromStart += $fromRange;
                $toStart += $toRange;
                $hunkCapture = false;
                $sameCount = $toRange = $fromRange = 0;
            }
            continue;
        }
        $sameCount = 0;
        if ($entry[1] === Differ::NO_LINE_END_EOF_WARNING) {
            continue;
        }
        $this->changed = true;
        if (false === $hunkCapture) {
            $hunkCapture = $i;
        }
        if (Differ::ADDED === $entry[1]) {
            // added
            $toRange++;
        }
        if (Differ::REMOVED === $entry[1]) {
            // removed
            $fromRange++;
        }
    }
    if (false === $hunkCapture) {
        return;
    }
    // we end here when cutoff (commonLineThreshold) was not reached, but we were capturing a hunk,
    // do not render hunk till end automatically because the number of context lines might be less than the commonLineThreshold
    $contextStartOffset = $hunkCapture - $this->contextLines < 0 ? $hunkCapture : $this->contextLines;
    // prevent trying to write out more common lines than there are in the diff _and_
    // do not write more than configured through the context lines
    $contextEndOffset = min($sameCount, $this->contextLines);
    $fromRange -= $sameCount;
    $toRange -= $sameCount;
    $this->writeHunk($diff, $hunkCapture - $contextStartOffset, $i - $sameCount + $contextEndOffset + 1, $fromStart - $contextStartOffset, $fromRange + $contextStartOffset + $contextEndOffset, $toStart - $contextStartOffset, $toRange + $contextStartOffset + $contextEndOffset, $output);
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal