diff --git a/src/StaticAnalysis/ExecutableLinesFindingVisitor.php b/src/StaticAnalysis/ExecutableLinesFindingVisitor.php index 6e1464e44..87ec13f77 100644 --- a/src/StaticAnalysis/ExecutableLinesFindingVisitor.php +++ b/src/StaticAnalysis/ExecutableLinesFindingVisitor.php @@ -204,6 +204,14 @@ private function getLines(NodeAbstract $node, bool $fromReturns): array } if ($node instanceof BinaryOp) { + if ($node instanceof BinaryOp\Concat && + ( + $node->left instanceof Node\Expr\Variable || + $node->right instanceof Node\Expr\Variable + )) { + return [$this->getNodeStartLine($node->right)]; + } + return $fromReturns ? $this->getLines($node->right, $fromReturns) : []; } diff --git a/tests/_files/source_with_multiline_constant_return.php b/tests/_files/source_with_multiline_constant_return.php index a5bc8fe21..48f694ebf 100644 --- a/tests/_files/source_with_multiline_constant_return.php +++ b/tests/_files/source_with_multiline_constant_return.php @@ -565,4 +565,27 @@ public function nestedArrayWithExecutableInKey(): array ] ]; } + + public function concatWithVar(): string + { + $var1 = 'start'; + + $var1 = + <<<'EOF' +right +EOF + . + $var1 + ; + + $var1 = + $var1 + . + <<<'EOF' +left +EOF + ; + + return $var1; + } } diff --git a/tests/tests/Data/RawCodeCoverageDataTest.php b/tests/tests/Data/RawCodeCoverageDataTest.php index 559187f9a..f87966ab2 100644 --- a/tests/tests/Data/RawCodeCoverageDataTest.php +++ b/tests/tests/Data/RawCodeCoverageDataTest.php @@ -538,6 +538,12 @@ public function testReturnStatementWithConstantExprOnlyReturnTheLineOfLast(): vo 537, 549, 562, + 571, + 573, + 578, + 581, + 585, + 589, ], array_keys(RawCodeCoverageData::fromUncoveredFile($file, new ParsingFileAnalyser(true, true))->lineCoverage()[$file]) );