From 37bc5004a65f15aa468d2e9c4cfd24a91181cbf7 Mon Sep 17 00:00:00 2001 From: Filippo Tessarotto Date: Fri, 21 Oct 2022 12:40:54 +0200 Subject: [PATCH] Fix: return with multiline constant expr only must contain the last line --- .../ExecutableLinesFindingVisitor.php | 11 + .../source_with_multiline_constant_return.php | 247 ++++++++++++++++++ tests/tests/Data/RawCodeCoverageDataTest.php | 39 ++- 3 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 tests/_files/source_with_multiline_constant_return.php diff --git a/src/StaticAnalysis/ExecutableLinesFindingVisitor.php b/src/StaticAnalysis/ExecutableLinesFindingVisitor.php index ae0b08ae7..f69363caf 100644 --- a/src/StaticAnalysis/ExecutableLinesFindingVisitor.php +++ b/src/StaticAnalysis/ExecutableLinesFindingVisitor.php @@ -135,6 +135,17 @@ private function computeReturns(): void */ private function getLines(Node $node): array { + if ($node instanceof BinaryOp) { + if (($node->left instanceof Node\Scalar || + $node->left instanceof Node\Expr\ConstFetch) && + ($node->right instanceof Node\Scalar || + $node->right instanceof Node\Expr\ConstFetch)) { + return [$node->right->getStartLine()]; + } + + return []; + } + if ($node instanceof Cast || $node instanceof PropertyFetch || $node instanceof NullsafePropertyFetch || diff --git a/tests/_files/source_with_multiline_constant_return.php b/tests/_files/source_with_multiline_constant_return.php new file mode 100644 index 000000000..6a8d44f59 --- /dev/null +++ b/tests/_files/source_with_multiline_constant_return.php @@ -0,0 +1,247 @@ + + 1 + ; + } + + public function GreaterOrEqual(): bool + { + return + 2 + >= + 1 + ; + } + + public function Identical(): bool + { + return + 2 + === + 1 + ; + } + + public function LogicalAnd(): bool + { + return + true + and + false + ; + } + + public function LogicalOr(): bool + { + return + true + or + false + ; + } + + public function LogicalXor(): bool + { + return + true + xor + false + ; + } + + public function Minus(): int + { + return + 2 + - + 1 + ; + } + + public function Mod(): int + { + return + 2 + % + 1 + ; + } + + public function Mul(): int + { + return + 2 + * + 1 + ; + } + + public function NotEqual(): bool + { + return + 2 + != + 1 + ; + } + + public function NotIdentical(): bool + { + return + 2 + !== + 1 + ; + } + + public function Plus(): int + { + return + 2 + + + 1 + ; + } + + public function Pow(): int + { + return + 2 + ** + 1 + ; + } + + public function ShiftLeft(): int + { + return + 2 + << + 1 + ; + } + + public function ShiftRight(): int + { + return + 2 + >> + 1 + ; + } + + public function Smaller(): bool + { + return + 2 + < + 1 + ; + } + + public function SmallerOrEqual(): bool + { + return + 2 + <= + 1 + ; + } + + public function Spaceship(): int + { + return + 2 + <=> + 1 + ; + } +} diff --git a/tests/tests/Data/RawCodeCoverageDataTest.php b/tests/tests/Data/RawCodeCoverageDataTest.php index c0aba6373..ae4e48803 100644 --- a/tests/tests/Data/RawCodeCoverageDataTest.php +++ b/tests/tests/Data/RawCodeCoverageDataTest.php @@ -361,7 +361,6 @@ public function testHeavyIndentationIsHandledCorrectly(): void 99, 101, 116, - 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 @@ -428,6 +427,44 @@ public function testReturnStatementWithOnlyAnArrayWithScalarReturnsTheFirstEleme ); } + public function testReturnStatementWithConstantExprOnlyReturnTheLineOfLast(): void + { + $file = TEST_FILES_PATH . 'source_with_multiline_constant_return.php'; + + $this->assertEquals( + [ + 10, + 19, + 28, + 37, + 46, + 55, + 64, + 73, + 82, + 91, + 100, + 109, + 118, + 127, + 136, + 145, + 154, + 163, + 172, + 181, + 190, + 199, + 208, + 217, + 226, + 235, + 244, + ], + array_keys(RawCodeCoverageData::fromUncoveredFile($file, new ParsingFileAnalyser(true, true))->lineCoverage()[$file]) + ); + } + public function testCoverageForFileWithInlineAnnotations(): void { $filename = TEST_FILES_PATH . 'source_with_oneline_annotations.php';