Skip to content

Commit

Permalink
Ignore Nop nodes in NodeScopeResolver when creating UnreachableStatem…
Browse files Browse the repository at this point in the history
…entNode
  • Loading branch information
herndlm committed Mar 8, 2023
1 parent 04edd04 commit fa580cd
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 16 deletions.
33 changes: 23 additions & 10 deletions src/Analyser/NodeScopeResolver.php
Expand Up @@ -240,7 +240,6 @@ public function processNodes(
callable $nodeCallback,
): void
{
$nodesCount = count($nodes);
foreach ($nodes as $i => $node) {
if (!$node instanceof Node\Stmt) {
continue;
Expand All @@ -252,14 +251,12 @@ public function processNodes(
continue;
}

if ($i < $nodesCount - 1) {
$nextStmt = $nodes[$i + 1];
if (!$nextStmt instanceof Node\Stmt) {
continue;
}

$nodeCallback(new UnreachableStatementNode($nextStmt), $scope);
$nextStmt = $this->getFirstNonNopNode(array_slice($nodes, $i + 1));
if (!$nextStmt instanceof Node\Stmt) {
continue;
}

$nodeCallback(new UnreachableStatementNode($nextStmt), $scope);
break;
}
}
Expand Down Expand Up @@ -323,8 +320,8 @@ public function processStmtNodes(
}

$alreadyTerminated = true;
if ($i < $stmtCount - 1) {
$nextStmt = $stmts[$i + 1];
$nextStmt = $this->getFirstNonNopNode(array_slice($stmts, $i + 1));
if ($nextStmt !== null) {
$nodeCallback(new UnreachableStatementNode($nextStmt), $scope);
}
break;
Expand Down Expand Up @@ -4365,4 +4362,20 @@ private function getPhpDocReturnType(ResolvedPhpDocBlock $resolvedPhpDoc, Type $
return null;
}

/**
* @template T of Node
* @param array<T> $nodes
* @return T
*/
private function getFirstNonNopNode(array $nodes): ?Node
{
foreach ($nodes as $node) {
if (!$node instanceof Node\Stmt\Nop) {
return $node;
}
}

return null;
}

}
4 changes: 0 additions & 4 deletions src/Rules/DeadCode/UnreachableStatementRule.php
Expand Up @@ -21,10 +21,6 @@ public function getNodeType(): string

public function processNode(Node $node, Scope $scope): array
{
if ($node->getOriginalStatement() instanceof Node\Stmt\Nop) {
return [];
}

return [
RuleErrorBuilder::message('Unreachable statement - code above always terminates.')
->identifier('deadCode.unreachableStatement')
Expand Down
23 changes: 21 additions & 2 deletions tests/PHPStan/Rules/DeadCode/UnreachableStatementRuleTest.php
Expand Up @@ -41,11 +41,19 @@ public function testRule(): void
],
[
'Unreachable statement - code above always terminates.',
71,
44,
],
[
'Unreachable statement - code above always terminates.',
135,
58,
],
[
'Unreachable statement - code above always terminates.',
93,
],
[
'Unreachable statement - code above always terminates.',
157,
],
]);
}
Expand Down Expand Up @@ -141,4 +149,15 @@ public function testBug8620(): void
$this->analyse([__DIR__ . '/data/bug-8620.php'], []);
}

public function testBug8966(): void
{
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/bug-8966.php'], [
[
'Unreachable statement - code above always terminates.',
8,
],
]);
}

}
22 changes: 22 additions & 0 deletions tests/PHPStan/Rules/DeadCode/data/unreachable.php
Expand Up @@ -36,6 +36,28 @@ public function doLorem()
// this is why...
}

public function doLorem2(string $foo)
{
return;
// this is why...

echo $foo;
}

public function doLorem3()
{
return;
;
}

public function doLorem4(string $foo)
{
return;
;

echo $foo;
}

/**
* @param \stdClass[] $all
*/
Expand Down

0 comments on commit fa580cd

Please sign in to comment.