Skip to content

Commit

Permalink
Too-wide return type - do not report void in PHPDoc union type
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 9, 2024
1 parent b1b7782 commit 5f0b1cc
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use PHPStan\Type\TypeUtils;
use PHPStan\Type\UnionType;
use PHPStan\Type\VerbosityLevel;
use PHPStan\Type\VoidType;
use function count;
use function sprintf;

Expand Down Expand Up @@ -48,16 +49,13 @@ public function processNode(Node $node, Scope $scope): array
foreach ($returnStatements as $returnStatement) {
$returnNode = $returnStatement->getReturnNode();
if ($returnNode->expr === null) {
$returnTypes[] = new VoidType();
continue;
}

$returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr);
}

if (count($returnTypes) === 0) {
return [];
}

$returnType = TypeCombinator::union(...$returnTypes);

$messages = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Type\TypeUtils;
use PHPStan\Type\UnionType;
use PHPStan\Type\VerbosityLevel;
use PHPStan\Type\VoidType;
use function count;
use function sprintf;

Expand Down Expand Up @@ -74,16 +75,13 @@ public function processNode(Node $node, Scope $scope): array
foreach ($returnStatements as $returnStatement) {
$returnNode = $returnStatement->getReturnNode();
if ($returnNode->expr === null) {
$returnTypes[] = new VoidType();
continue;
}

$returnTypes[] = $returnStatement->getScope()->getType($returnNode->expr);
}

if (count($returnTypes) === 0) {
return [];
}

$returnType = TypeCombinator::union(...$returnTypes);
if (
!$method->isPrivate()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,14 @@ public function testRule(): void
]);
}

public function testBug11980(): void
{
$this->analyse([__DIR__ . '/data/bug-11980-function.php'], [
[
'Function Bug11980Function\process2() never returns void so it can be removed from the return type.',
34,
],
]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -248,4 +248,16 @@ public function testAlwaysCheckFinal(bool $checkProtectedAndPublicMethods, bool
$this->analyse([__DIR__ . '/data/method-too-wide-return-always-check-final.php'], $expectedErrors);
}

public function testBug11980(): void
{
$this->checkProtectedAndPublicMethods = true;
$this->alwaysCheckFinal = true;
$this->analyse([__DIR__ . '/data/bug-11980.php'], [
[
'Method Bug11980\Demo::process2() never returns void so it can be removed from the return type.',
37,
],
]);
}

}
49 changes: 49 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-11980-function.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Bug11980Function;

/**
* @param array<int, array<string, int>> $tokens
* @param int $stackPtr
*
* @return int|void
*/
function process($tokens, $stackPtr)
{
if (empty($tokens[$stackPtr]['nested_parenthesis']) === false) {
// Not a stand-alone statement.
return;
}

$end = 10;

if ($tokens[$end]['code'] !== 10
&& $tokens[$end]['code'] !== 20
) {
// Not a stand-alone statement.
return $end;
}
}

/**
* @param array<int, array<string, int>> $tokens
* @param int $stackPtr
*
* @return int|void
*/
function process2($tokens, $stackPtr)
{
if (empty($tokens[$stackPtr]['nested_parenthesis']) === false) {
// Not a stand-alone statement.
return null;
}

$end = 10;

if ($tokens[$end]['code'] !== 10
&& $tokens[$end]['code'] !== 20
) {
// Not a stand-alone statement.
return $end;
}
}
53 changes: 53 additions & 0 deletions tests/PHPStan/Rules/TooWideTypehints/data/bug-11980.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Bug11980;

final class Demo
{

/**
* @param array<int, array<string, int>> $tokens
* @param int $stackPtr
*
* @return int|void
*/
public function process($tokens, $stackPtr)
{
if (empty($tokens[$stackPtr]['nested_parenthesis']) === false) {
// Not a stand-alone statement.
return;
}

$end = 10;

if ($tokens[$end]['code'] !== 10
&& $tokens[$end]['code'] !== 20
) {
// Not a stand-alone statement.
return $end;
}
}

/**
* @param array<int, array<string, int>> $tokens
* @param int $stackPtr
*
* @return int|void
*/
public function process2($tokens, $stackPtr)
{
if (empty($tokens[$stackPtr]['nested_parenthesis']) === false) {
// Not a stand-alone statement.
return null;
}

$end = 10;

if ($tokens[$end]['code'] !== 10
&& $tokens[$end]['code'] !== 20
) {
// Not a stand-alone statement.
return $end;
}
}
}

0 comments on commit 5f0b1cc

Please sign in to comment.