Skip to content

Commit e75270a

Browse files
committed
skip function-like nodes when checking if a function is a generator
1 parent ae3a484 commit e75270a

File tree

5 files changed

+90
-1
lines changed

5 files changed

+90
-1
lines changed

src/Reflection/Php/PhpFunctionFromParserNodeReflection.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PhpParser\Node\FunctionLike;
88
use PhpParser\Node\Stmt\ClassMethod;
99
use PhpParser\Node\Stmt\Function_;
10+
use PHPStan\Node\AnonymousClassNode;
1011
use PHPStan\Reflection\Assertions;
1112
use PHPStan\Reflection\ExtendedFunctionVariant;
1213
use PHPStan\Reflection\ExtendedParameterReflection;
@@ -281,7 +282,11 @@ private function nodeIsOrContainsYield(Node $node): bool
281282
foreach ($node->getSubNodeNames() as $nodeName) {
282283
$nodeProperty = $node->$nodeName;
283284

284-
if ($nodeProperty instanceof Node && $this->nodeIsOrContainsYield($nodeProperty)) {
285+
if ($nodeProperty instanceof Node &&
286+
!$nodeProperty instanceof FunctionLike &&
287+
!$nodeProperty instanceof AnonymousClassNode &&
288+
$this->nodeIsOrContainsYield($nodeProperty)
289+
) {
285290
return true;
286291
}
287292

tests/PHPStan/Rules/Functions/ReturnTypeRuleTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -341,4 +341,24 @@ public function testBug11301(): void
341341
]);
342342
}
343343

344+
public function testBug12462(): void
345+
{
346+
$this->checkExplicitMixed = true;
347+
$this->checkNullables = true;
348+
$this->analyse([__DIR__ . '/data/bug-12462.php'], [
349+
[
350+
'Function Bug12462\functionReturningYieldingClosure() should return int but returns Closure.',
351+
7,
352+
],
353+
[
354+
'Function Bug12462\functionReturningYieldingArrowFunction() should return int but returns Closure.',
355+
12,
356+
],
357+
[
358+
'Function Bug12462\functionRetuningYieldingAnonymousClass() should return int but returns class@anonymous/tests/PHPStan/Rules/Functions/data/bug-12462.php:17.',
359+
17,
360+
],
361+
]);
362+
}
363+
344364
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12462;
4+
5+
function functionReturningYieldingClosure (): int
6+
{
7+
return function () { yield ''; };
8+
}
9+
10+
function functionReturningYieldingArrowFunction (): int
11+
{
12+
return fn () => yield '';
13+
}
14+
15+
function functionRetuningYieldingAnonymousClass (): int
16+
{
17+
return new class () {
18+
public function __invoke(): \Generator {
19+
yield '';
20+
}
21+
};
22+
}

tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -1227,4 +1227,22 @@ public function testBug1O580(): void
12271227
]);
12281228
}
12291229

1230+
public function testBug12462(): void
1231+
{
1232+
$this->analyse([__DIR__ . '/data/bug-12462.php'], [
1233+
[
1234+
'Method Bug12462\A::methodReturningYieldingClosure() should return int but returns Closure.',
1235+
8,
1236+
],
1237+
[
1238+
'Method Bug12462\A::methodReturningYieldingArrowFunction() should return int but returns Closure.',
1239+
13,
1240+
],
1241+
[
1242+
'Method Bug12462\A::methodRetuningYieldingAnonymousClass() should return int but returns class@anonymous/tests/PHPStan/Rules/Methods/data/bug-12462.php:18.',
1243+
18,
1244+
],
1245+
]);
1246+
}
1247+
12301248
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12462;
4+
5+
class A {
6+
function methodReturningYieldingClosure (): int
7+
{
8+
return function () { yield ''; };
9+
}
10+
11+
function methodReturningYieldingArrowFunction (): int
12+
{
13+
return fn () => yield '';
14+
}
15+
16+
function methodRetuningYieldingAnonymousClass (): int
17+
{
18+
return new class () {
19+
public function __invoke(): \Generator {
20+
yield '';
21+
}
22+
};
23+
}
24+
}

0 commit comments

Comments
 (0)