Skip to content

Commit

Permalink
skip function-like nodes when checking if a function is a generator
Browse files Browse the repository at this point in the history
  • Loading branch information
sebkehr committed Jan 25, 2025
1 parent ae3a484 commit 13d7837
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/Reflection/Php/PhpFunctionFromParserNodeReflection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PHPStan\Node\AnonymousClassNode;
use PHPStan\Reflection\Assertions;
use PHPStan\Reflection\ExtendedFunctionVariant;
use PHPStan\Reflection\ExtendedParameterReflection;
Expand Down Expand Up @@ -281,7 +282,11 @@ private function nodeIsOrContainsYield(Node $node): bool
foreach ($node->getSubNodeNames() as $nodeName) {
$nodeProperty = $node->$nodeName;

if ($nodeProperty instanceof Node && $this->nodeIsOrContainsYield($nodeProperty)) {
if ($nodeProperty instanceof Node &&
!$nodeProperty instanceof FunctionLike &&
!$nodeProperty instanceof AnonymousClassNode &&
$this->nodeIsOrContainsYield($nodeProperty)
) {
return true;
}

Expand Down
20 changes: 20 additions & 0 deletions tests/PHPStan/Rules/Functions/ReturnTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,24 @@ public function testBug11301(): void
]);
}

public function testBug12462(): void
{
$this->checkExplicitMixed = true;
$this->checkNullables = true;
$this->analyse([__DIR__ . '/data/bug-12462.php'], [
[
'Function Bug12462\functionReturningYieldingClosure() should return int but returns Closure.',
7,
],
[
'Function Bug12462\functionReturningYieldingArrowFunction() should return int but returns Closure.',
12,
],
[
'Function Bug12462\functionRetuningYieldingAnonymousClass() should return int but returns class@anonymous/tests/PHPStan/Rules/Functions/data/bug-12462.php:17.',
17,
],
]);
}

}
22 changes: 22 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-12462.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php declare(strict_types = 1);

namespace Bug12462;

function functionReturningYieldingClosure (): int
{
return function () { yield ''; };
}

function functionReturningYieldingArrowFunction (): int
{
return fn () => yield '';
}

function functionRetuningYieldingAnonymousClass (): int
{
return new class () {
public function f(): \Generator {
yield '';
}
};
}
18 changes: 18 additions & 0 deletions tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1227,4 +1227,22 @@ public function testBug1O580(): void
]);
}

public function testBug12462(): void
{
$this->analyse([__DIR__ . '/data/bug-12462.php'], [
[
'Method Bug12462\A::methodReturningYieldingClosure() should return int but returns Closure.',
8,
],
[
'Method Bug12462\A::methodReturningYieldingArrowFunction() should return int but returns Closure.',
13,
],
[
'Method Bug12462\A::methodRetuningYieldingAnonymousClass() should return int but returns class@anonymous/tests/PHPStan/Rules/Methods/data/bug-12462.php:18.',
18,
],
]);
}

}
24 changes: 24 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-12462.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php declare(strict_types = 1);

namespace Bug12462;

class A {
function methodReturningYieldingClosure (): int
{
return function () { yield ''; };
}

function methodReturningYieldingArrowFunction (): int
{
return fn () => yield '';
}

function methodRetuningYieldingAnonymousClass (): int
{
return new class () {
public function f(): \Generator {
yield '';
}
};
}
}

0 comments on commit 13d7837

Please sign in to comment.