Skip to content

Commit 54892e1

Browse files
committed
Code fixes, optimization, cleanup, refactoring and commenting.
- Fixed cli arguments for composer defined script 'phpmd' - Added validation for SequenceMatcher::defaultOptions['context']. - Removed parameter mentioned in docBlock of SequenceMatcher::getGroupedOpCodes(). - Context.php has reduced reduced complexity.
1 parent 98d993e commit 54892e1

File tree

3 files changed

+69
-63
lines changed

3 files changed

+69
-63
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@
3636
"phpunit" : "phpunit ./tests/",
3737
"php_src" : "phpcs --standard=phpcs.xml -s -p --colors ./lib/",
3838
"php_test" : "phpcs --standard=phpcs.xml -s -p --colors ./tests/",
39-
"phpmd" : "phpmd ./ ansi cleancode, codesize, controversial, design, naming, unusedcode --exclude vendor"
39+
"phpmd" : "phpmd ./ ansi cleancode,codesize,controversial,design,naming,unusedcode --exclude vendor"
4040
}
4141
}

lib/jblond/Diff/Renderer/Text/Context.php

Lines changed: 62 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,102 +11,104 @@
1111
*
1212
* PHP version 7.2 or greater
1313
*
14-
* @package jblond\Diff\Renderer\Text
15-
* @author Chris Boulton <chris.boulton@interspire.com>
14+
* @package jblond\Diff\Renderer\Text
15+
* @author Chris Boulton <chris.boulton@interspire.com>
1616
* @copyright (c) 2009 Chris Boulton
17-
* @license New BSD License http://www.opensource.org/licenses/bsd-license.php
18-
* @version 1.15
19-
* @link https://github.com/JBlond/php-diff
17+
* @license New BSD License http://www.opensource.org/licenses/bsd-license.php
18+
* @version 1.15
19+
* @link https://github.com/JBlond/php-diff
2020
*/
2121
class Context extends RendererAbstract
2222
{
2323
/**
2424
* @var array Array of the different op-code tags and how they map to the context diff-view equivalent.
2525
*/
2626
private $tagMap = [
27-
'insert' => '+',
28-
'delete' => '-',
29-
'replace' => '!',
30-
'equal' => ' '
27+
'insert' => '+',
28+
'delete' => '-',
29+
'replace' => '!',
30+
'equal' => ' ',
3131
];
3232

3333
/**
3434
* Render and return a context formatted (old school!) diff-view.
3535
*
36+
* @link https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Context.html#Detailed-Context
37+
*
3638
* @return string The generated context diff-view.
3739
*/
3840
public function render(): string
3941
{
40-
$diff = '';
41-
$opCodes = $this->diff->getGroupedOpCodes();
42+
$diff = '';
43+
$opCodes = $this->diff->getGroupedOpCodes();
4244

4345
foreach ($opCodes as $group) {
44-
$diff .= "***************\n";
45-
$lastItem = count($group) - 1;
46-
$i1 = $group['0']['1'];
47-
$i2 = $group[$lastItem]['2'];
48-
$j1 = $group['0']['3'];
49-
$j2 = $group[$lastItem]['4'];
50-
51-
if ($i2 - $i1 >= 2) {
52-
$diff .= '*** ' . ($group['0']['1'] + 1) . ',' . $i2 . " ****\n";
53-
} else {
54-
$diff .= '*** ' . $i2 . " ****\n";
55-
}
56-
57-
if ($j2 - $j1 >= 2) {
58-
$separator = '--- ' . ($j1 + 1) . ',' . $j2 . " ----\n";
59-
} else {
60-
$separator = '--- ' . $j2 . " ----\n";
61-
}
62-
63-
$hasVisible = false;
64-
65-
foreach ($group as $code) {
66-
if ($code['0'] == 'replace' || $code['0'] == 'delete') {
67-
$hasVisible = true;
68-
break;
69-
}
70-
}
71-
72-
if ($hasVisible) {
73-
foreach ($group as [$tag, $i1, $i2, $j1, $j2]) {
74-
if ($tag == 'insert') {
75-
continue;
76-
}
46+
$diff .= "***************\n";
47+
$lastItem = count($group) - 1;
48+
$start1 = $group['0']['1'];
49+
$end1 = $group[$lastItem]['2'];
50+
$start2 = $group['0']['3'];
51+
$end2 = $group[$lastItem]['4'];
52+
53+
// Line to line header for version 1.
54+
$diffStart = $end1 - $start1 >= 2 ? $start1 + 1 . ',' : '';
55+
$diff .= '*** ' . $diffStart . $end1 . " ****\n";
56+
57+
// Line to line header for version 2.
58+
$diffStart = $end2 - $start2 >= 2 ? ($start2 + 1) . ',' : '';
59+
$separator = '--- ' . $diffStart . $end2 . " ----\n";
60+
61+
// Check for visible changes by replace or delete operations.
62+
if (!empty(array_intersect(['replace', 'delete'], array_column($group, 0)))) {
63+
// Line differences between versions or lines of version 1 are removed from version 2.
64+
// Add all operations to diff-view of version 1, except for insert.
65+
$filteredGroups = $this->filterGroups($group, 'insert');
66+
foreach ($filteredGroups as [$tag, $start1, $end1, $start2, $end2]) {
7767
$diff .= $this->tagMap[$tag] . ' ' .
7868
implode(
7969
"\n" . $this->tagMap[$tag] . ' ',
80-
$this->diff->getArrayRange($this->diff->getVersion1(), $i1, $i2)
70+
$this->diff->getArrayRange($this->diff->getVersion1(), $start1, $end1)
8171
) . "\n";
8272
}
8373
}
8474

85-
$hasVisible = false;
86-
87-
foreach ($group as $code) {
88-
if ($code['0'] == 'replace' || $code['0'] == 'insert') {
89-
$hasVisible = true;
90-
break;
91-
}
92-
}
93-
9475
$diff .= $separator;
9576

96-
if ($hasVisible) {
97-
foreach ($group as [$tag, $i1, $i2, $j1, $j2]) {
98-
if ($tag == 'delete') {
99-
continue;
100-
}
77+
// Check for visible changes by replace or insert operations.
78+
if (!empty(array_intersect(['replace', 'insert'], array_column($group, 0)))) {
79+
// Line differences between versions or lines are inserted into version 2.
80+
// Add all operations to diff-view of version 2, except for delete.
81+
$filteredGroups = $this->filterGroups($group, 'delete');
82+
foreach ($filteredGroups as [$tag, $start1, $end1, $start2, $end2]) {
10183
$diff .= $this->tagMap[$tag] . ' ' .
10284
implode(
10385
"\n" . $this->tagMap[$tag] . ' ',
104-
$this->diff->getArrayRange($this->diff->getVersion2(), $j1, $j2)
86+
$this->diff->getArrayRange($this->diff->getVersion2(), $start2, $end2)
10587
) . "\n";
10688
}
10789
}
10890
}
10991

11092
return $diff;
11193
}
94+
95+
/**
96+
* Filter out groups by tag.
97+
*
98+
* Given an array of groups, all groups which don't have the specified tag are returned.
99+
*
100+
* @param array $groups A series of opCode groups.
101+
* @param string $excludedTag Name of the opCode Tag to filter out.
102+
*
103+
* @return array Filtered opCode Groups.
104+
*/
105+
private function filterGroups(array $groups, string $excludedTag): array
106+
{
107+
return array_filter(
108+
$groups,
109+
function ($operation) use ($excludedTag) {
110+
return $operation[0] != $excludedTag;
111+
}
112+
);
113+
}
112114
}

lib/jblond/Diff/SequenceMatcher.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace jblond\Diff;
66

7+
use http\Exception\InvalidArgumentException;
8+
79
/**
810
* Sequence matcher for Diff
911
*
@@ -100,6 +102,9 @@ public function __construct($old, $new, array $options = [], $junkCallback = nul
100102
*/
101103
public function setOptions(array $options)
102104
{
105+
if (isset($options['context']) && $options['context'] < 0) {
106+
throw new InvalidArgumentException('The context option cannot be a negative value!');
107+
}
103108
$this->options = array_merge($this->defaultOptions, $options);
104109
}
105110

@@ -535,7 +540,6 @@ public function getOpCodes(): array
535540
* content of the different files but can still provide context as to where the
536541
* changes are.
537542
*
538-
* @param int $this->options['context'] The number of lines of context to provide around the groups.
539543
* @return array Nested array of all of the grouped op codes.
540544
*/
541545
public function getGroupedOpCodes(): array
@@ -583,7 +587,7 @@ public function getGroupedOpCodes(): array
583587
$groups = array();
584588
$group = array();
585589

586-
foreach ($opCodes as $key => [$tag, $i1, $i2, $j1, $j2]) {
590+
foreach ($opCodes as [$tag, $i1, $i2, $j1, $j2]) {
587591
if ($tag == 'equal' && $i2 - $i1 > $maxRange) {
588592
$group[] = array(
589593
$tag,

0 commit comments

Comments
 (0)