Issues (3)

src/PhpMerge/internal/Hunk.php (2 issues)

Labels
Severity
1
<?php
2
/**
3
 * This file is part of the php-merge package.
4
 *
5
 * (c) Fabian Bircher <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace PhpMerge\internal;
12
13
/**
14
 * Class Hunk
15
 *
16
 * This represents a collection of changed lines.
17
 *
18
 * @package    PhpMerge
19
 * @author     Fabian Bircher <[email protected]>
20
 * @copyright  Fabian Bircher <[email protected]>
21
 * @license    https://opensource.org/licenses/MIT
22
 * @version    Release: @package_version@
23
 * @link       http://github.com/bircher/php-merge
24
 * @internal   This class is not part of the public api.
25
 */
26
final class Hunk
27
{
28
29
    const ADDED = 1;
30
    const REMOVED = 2;
31
    const REPLACED = 3;
32
33
    /**
34
     * @var int
35
     */
36
    protected $start;
37
    /**
38
     * @var int
39
     */
40
    protected $end;
41
    /**
42
     * @var Line[]
43
     */
44
    protected $lines;
45
    /**
46
     * @var int
47
     */
48
    protected $type;
49
50
    /**
51
     * The Hunk constructor.
52
     *
53
     * @param Line|Line[] $lines
54
     *   The lines belonging to the hunk.
55
     * @param int $type
56
     *   The type of the hunk: Hunk::ADDED Hunk::REMOVED Hunk::REPLACED
57
     * @param int $start
58
     *   The line index where the hunk starts.
59
     * @param int $end
60
     *   The line index where the hunk stops.
61
     */
62 13
    public function __construct($lines, $type, $start, $end = null)
63
    {
64 13
        $this->start = $start;
65 13
        if ($end === null) {
66 13
            $end = $start;
67
        }
68 13
        $this->end = $end;
69 13
        if (!is_array($lines)) {
70 13
            $lines = array($lines);
71
        }
72 13
        $this->lines = $lines;
73 13
        $this->type = $type;
74 13
    }
75
76
    /**
77
     * Add a new line to the hunk.
78
     *
79
     * @param \PhpMerge\Line $line
0 ignored issues
show
The type PhpMerge\Line was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
80
     *   The line to add.
81
     */
82 11
    public function addLine(Line $line)
83
    {
84 11
        $this->lines[] = $line;
85 11
        $this->end = $line->getIndex();
86 11
    }
87
88
    /**
89
     * Create an array of hunks out of an array of lines.
90
     *
91
     * @param Line[] $lines
92
     *   The lines of the diff.
93
     * @return Hunk[]
94
     *   The hunks in the lines.
95
     */
96 13
    public static function createArray($lines)
97
    {
98 13
        $op = Line::UNCHANGED;
99 13
        $hunks = [];
100
        /** @var Hunk $current */
101 13
        $current = null;
102 13
        foreach ($lines as $line) {
103 13
            switch ($line->getType()) {
104 13
                case Line::REMOVED:
105 13
                    if ($op != Line::REMOVED) {
106
                        // The last line was not removed so we start a new hunk.
107 13
                        $current = new Hunk($line, Hunk::REMOVED, $line->getIndex());
108
                    } else {
109
                        // continue adding the line to the hunk.
110 2
                        $current->addLine($line);
111
                    }
112 13
                    break;
113 13
                case Line::ADDED:
114
                    switch ($op) {
115 13
                        case Line::REMOVED:
116
                            // The hunk is a replacement.
117 11
                            $current->setType(Hunk::REPLACED);
118 11
                            $current->addLine($line);
119 11
                            break;
120 12
                        case Line::ADDED:
121 5
                            $current->addLine($line);
122 5
                            break;
123 12
                        case Line::UNCHANGED:
124
                            // Add a new hunk with the added type.
125 12
                            $current = new Hunk($line, Hunk::ADDED, $line->getIndex());
126 12
                            break;
127
                    }
128 13
                    break;
129 13
                case Line::UNCHANGED:
130 13
                    if ($current) {
131
                        // The hunk exists so add it to the array.
132 11
                        $hunks[] = $current;
133 11
                        $current = null;
134
                    }
135 13
                    break;
136
            }
137 13
            $op = $line->getType();
138
        }
139 13
        if ($current) {
140
            // The last line was part of a hunk, so add it.
141 9
            $hunks[] = $current;
142
        }
143
144 13
        return $hunks;
145
    }
146
147
    /**
148
     * Set the type of the hunk.
149
     *
150
     * @param int $type
151
     */
152 11
    protected function setType($type)
153
    {
154 11
        $this->type = $type;
155 11
    }
156
157
    /**
158
     * Get the line index where the hunk starts.
159
     *
160
     * @return int
161
     */
162 12
    public function getStart()
163
    {
164 12
        return $this->start;
165
    }
166
167
    /**
168
     * Get the line index where the hunk ends.
169
     *
170
     * @return int
171
     */
172 7
    public function getEnd()
173
    {
174 7
        return $this->end;
175
    }
176
177
    /**
178
     * Get the type of the hunk.
179
     *
180
     * @return int
181
     */
182 9
    public function getType()
183
    {
184 9
        return $this->type;
185
    }
186
187
    /**
188
     * Get the lines of the hunk.
189
     *
190
     * @return Line[]
191
     */
192 1
    public function getLines()
193
    {
194 1
        return $this->lines;
195
    }
196
197
    /**
198
     * Get the removed lines.
199
     *
200
     * @return Line[]
201
     */
202 2
    public function getRemovedLines()
203
    {
204 2
        return array_values(array_filter(
205 2
            $this->lines,
206
            function (Line $line) {
207 2
                return $line->getType() == Line::REMOVED;
208 2
            }
209
        ));
210
    }
211
212
    /**
213
     * Get the added lines.
214
     *
215
     * @return Line[]
216
     */
217 9
    public function getAddedLines()
218
    {
219 9
        return array_values(array_filter(
220 9
            $this->lines,
221
            function (Line $line) {
222 9
                return $line->getType() == Line::ADDED;
223 9
            }
224
        ));
225
    }
226
227
    /**
228
     * Get the lines content.
229
     *
230
     * @return string[]
231
     */
232 6
    public function getLinesContent()
233
    {
234 6
        return array_map(
235
            function (Line $line) {
236 6
                return $line->getContent();
237 6
            },
238 6
            $this->getAddedLines()
239
        );
240
    }
241
242
    /**
243
     * Test whether the hunk is to be considered for a conflict resolution.
244
     *
245
     * @param int $line
246
     *   The line number in the original text to test.
247
     *
248
     * @return bool
249
     *   Whether the line is affected by the hunk.
250
     */
251 7
    public function isLineNumberAffected($line)
252
    {
253
        // Added lines also affect the ones afterwards in conflict resolution,
254
        // because they are added in between.
255 7
        $bleed = ($this->type == self::ADDED ? 1 : 0);
256 7
        return ($line >= $this->start && $line <= $this->end + $bleed);
257
    }
258
259
    /**
260
     * @param \PhpMerge\Hunk|null $hunk
0 ignored issues
show
The type PhpMerge\Hunk was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
261
     * @return bool
262
     */
263 7
    public function hasIntersection(Hunk $hunk = null)
264
    {
265 7
        if (!$hunk) {
266 5
            return false;
267
        }
268 7
        if ($this->type == self::ADDED && $hunk->type == self::ADDED) {
269 1
            return $this->start == $hunk->start;
270
        }
271 7
        return $this->isLineNumberAffected($hunk->start) || $this->isLineNumberAffected($hunk->end)
272 7
          || $hunk->isLineNumberAffected($this->start) || $hunk->isLineNumberAffected($this->end);
273
    }
274
}
275