Skip to content

Commit

Permalink
Merge branch '9.2'
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianbergmann committed Mar 7, 2022
2 parents 0bb71d8 + c53b9a9 commit 13290ca
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 1 deletion.
1 change: 1 addition & 0 deletions ChangeLog.md
Expand Up @@ -24,6 +24,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
### Fixed

* [#885](https://github.com/sebastianbergmann/php-code-coverage/issues/885): Files that have only `\r` (CR, 0x0d) EOL characters are not handled correctly
* [#907](https://github.com/sebastianbergmann/php-code-coverage/issues/907): Line with only `return [` is not recognized as executable

## [9.2.14] - 2022-02-28

Expand Down
51 changes: 51 additions & 0 deletions src/StaticAnalysis/ExecutableLinesFindingVisitor.php
Expand Up @@ -10,7 +10,9 @@
namespace SebastianBergmann\CodeCoverage\StaticAnalysis;

use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\CallLike;
Expand Down Expand Up @@ -64,6 +66,11 @@ final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract
*/
private array $propertyLines = [];

/**
* @psalm-var array<int, Return_>
*/
private $returns = [];

public function enterNode(Node $node): void
{
$this->savePropertyLines($node);
Expand All @@ -86,6 +93,8 @@ public function enterNode(Node $node): void
*/
public function executableLines(): array
{
$this->computeReturns();

sort($this->executableLines);

return $this->executableLines;
Expand All @@ -102,6 +111,25 @@ private function savePropertyLines(Node $node): void
}
}

private function computeReturns(): void
{
foreach ($this->returns as $return) {
foreach (range($return->getStartLine(), $return->getEndLine()) as $loc) {
if (isset($this->executableLines[$loc])) {
continue 2;
}
}

$line = $return->getEndLine();

if ($return->expr !== null) {
$line = $return->expr->getStartLine();
}

$this->executableLines[$line] = $line;
}
}

/**
* @return int[]
*/
Expand All @@ -122,6 +150,22 @@ private function getLines(Node $node): array
return [$node->dim->getStartLine()];
}

if ($node instanceof Array_) {
$startLine = $node->getStartLine();

if (isset($this->executableLines[$startLine])) {
return [];
}

if ([] === $node->items) {
return [$node->getEndLine()];
}

if ($node->items[0] instanceof ArrayItem) {
return [$node->items[0]->getStartLine()];
}
}

if ($node instanceof ClassMethod) {
if ($node->name->name !== '__construct') {
return [];
Expand Down Expand Up @@ -178,13 +222,20 @@ private function getLines(Node $node): array
return [];
}

if ($node instanceof Return_) {
$this->returns[] = $node;

return [];
}

return [$node->getStartLine()];
}

private function isExecutable(Node $node): bool
{
return $node instanceof Assign ||
$node instanceof ArrayDimFetch ||
$node instanceof Array_ ||
$node instanceof BinaryOp ||
$node instanceof Break_ ||
$node instanceof CallLike ||
Expand Down
65 changes: 65 additions & 0 deletions tests/_files/source_with_return_and_array_with_scalars.php
@@ -0,0 +1,65 @@
<?php

class Foo
{
public function one(): array
{
return [
'...',
'...',
];
}

public function two(): array
{
return ['...',
'...',
];
}

public function three(): array
{
return [

'...',
];
}

public function four(): bool
{
return in_array('...', [
'...',
'...',
], true);
}

public function fifth(): array
{
return
[
]
;
}

public function sixth(): int
{
return
1
;
}

public function seventh(): int
{
return
self
::
class
;
}

public function eigth(): void
{
return
;
}
}
24 changes: 23 additions & 1 deletion tests/tests/Data/RawCodeCoverageDataTest.php
Expand Up @@ -229,6 +229,7 @@ public function testUseStatementsAreUncovered(): void
[
12,
14,
15,
16,
18,
],
Expand Down Expand Up @@ -256,6 +257,7 @@ public function testInterfacesAreUncovered(): void
[
7,
9,
10,
11,
13,
],
Expand Down Expand Up @@ -290,14 +292,14 @@ public function testHeavyIndentationIsHandledCorrectly(): void
[
9,
12,
15,
16,
18,
19,
24,
25,
28,
31,
36,
40,
46,
48,
Expand All @@ -319,6 +321,7 @@ public function testHeavyIndentationIsHandledCorrectly(): void
117,
120,
123,
125, // This shouldn't be marked as LoC, but it's high unlikely to happen IRL to have $var = []; on multiple lines
132,
135,
139,
Expand Down Expand Up @@ -363,6 +366,25 @@ public function testEachCaseInMatchExpressionIsMarkedAsExecutable(): void
);
}

public function testReturnStatementWithOnlyAnArrayWithScalarReturnsTheFirstElementLine(): void
{
$file = TEST_FILES_PATH . 'source_with_return_and_array_with_scalars.php';

$this->assertEquals(
[
8,
15,
24,
30,
40,
47,
54,
63,
],
array_keys(RawCodeCoverageData::fromUncoveredFile($file, new ParsingFileAnalyser(true, true))->lineCoverage()[$file])
);
}

public function testCoverageForFileWithInlineAnnotations(): void
{
$filename = TEST_FILES_PATH . 'source_with_oneline_annotations.php';
Expand Down

0 comments on commit 13290ca

Please sign in to comment.