Skip to content

Commit 0e8466f

Browse files
authored
Merge branch refs/heads/2.1.x into 2.2.x
2 parents e04947f + 64a7ad9 commit 0e8466f

File tree

5 files changed

+125
-1
lines changed

5 files changed

+125
-1
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@
198198
use PHPStan\Type\TypeTraverser;
199199
use PHPStan\Type\TypeUtils;
200200
use PHPStan\Type\UnionType;
201+
use ReflectionFunction;
202+
use ReflectionMethod;
201203
use ReflectionProperty;
202204
use Throwable;
203205
use Traversable;
@@ -4781,6 +4783,13 @@ private function getMethodThrowPoint(MethodReflection $methodReflection, Paramet
47814783
}
47824784
}
47834785

4786+
if (
4787+
in_array($methodReflection->getName(), ['invoke', 'invokeArgs'], true)
4788+
&& in_array($methodReflection->getDeclaringClass()->getName(), [ReflectionMethod::class, ReflectionFunction::class], true)
4789+
) {
4790+
return InternalThrowPoint::createImplicit($scope, $methodCall);
4791+
}
4792+
47844793
$throwType = $methodReflection->getThrowType();
47854794
if ($throwType === null) {
47864795
$returnType = $parametersAcceptor->getReturnType();

tests/PHPStan/Analyser/nsrt/bug-4821.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,26 @@ public function sayHello(): void
1616
return;
1717
} catch (\ReflectionException $e) {
1818
assertVariableCertainty(TrinaryLogic::createYes(), $object);
19-
assertVariableCertainty(TrinaryLogic::createMaybe(), $method);
19+
assertVariableCertainty(TrinaryLogic::createNo(), $method);
2020
}
2121
}
22+
23+
public function sayHello2(): void
24+
{
25+
$method = rand(0, 1) ? 'nonExisting' : 'sayFoo';
26+
try {
27+
$object = new HelloWorld();
28+
$method = new \ReflectionMethod($object, $method);
29+
$method->invoke($object);
30+
return;
31+
} catch (\ReflectionException $e) {
32+
assertVariableCertainty(TrinaryLogic::createYes(), $object);
33+
assertVariableCertainty(TrinaryLogic::createYes(), $method);
34+
}
35+
}
36+
37+
public function sayFoo(): void
38+
{
39+
40+
}
2241
}

tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,16 @@ public function testBug9568(): void
604604
$this->analyse([__DIR__ . '/data/bug-9568.php'], []);
605605
}
606606

607+
public function testBug7719(): void
608+
{
609+
$this->analyse([__DIR__ . '/data/bug-7719.php'], []);
610+
}
611+
612+
public function testBug9267(): void
613+
{
614+
$this->analyse([__DIR__ . '/data/bug-9267.php'], []);
615+
}
616+
607617
#[RequiresPhp('>= 8.4')]
608618
public function testPropertyHooks(): void
609619
{
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug7719;
4+
5+
class Endpoint {
6+
public function run(int $id): int {
7+
return $id;
8+
}
9+
}
10+
11+
class HelloWorld
12+
{
13+
public function sayHello(Endpoint $endpoint, string $methodName): void
14+
{
15+
try {
16+
$methodResponse = (new \ReflectionMethod($endpoint, $methodName))->invokeArgs($endpoint, ['id' => 2]);
17+
} catch (\RuntimeException $e) {
18+
echo $e->getMessage();
19+
die;
20+
}
21+
var_dump($methodResponse);
22+
}
23+
24+
public function sayHelloWithInvoke(Endpoint $endpoint, string $methodName): void
25+
{
26+
try {
27+
$methodResponse = (new \ReflectionMethod($endpoint, $methodName))->invoke($endpoint, 2);
28+
} catch (\RuntimeException $e) {
29+
echo $e->getMessage();
30+
die;
31+
}
32+
var_dump($methodResponse);
33+
}
34+
35+
public function sayHelloWithFunction(string $functionName): void
36+
{
37+
try {
38+
$result = (new \ReflectionFunction($functionName))->invokeArgs([1, 2]);
39+
} catch (\RuntimeException $e) {
40+
echo $e->getMessage();
41+
die;
42+
}
43+
var_dump($result);
44+
}
45+
46+
public function sayHelloWithFunctionInvoke(string $functionName): void
47+
{
48+
try {
49+
$result = (new \ReflectionFunction($functionName))->invoke(1, 2);
50+
} catch (\RuntimeException $e) {
51+
echo $e->getMessage();
52+
die;
53+
}
54+
var_dump($result);
55+
}
56+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug9267;
4+
5+
class FooException extends \Exception {}
6+
7+
class C {
8+
/** @return never */
9+
public function test(): never {
10+
throw new FooException("");
11+
}
12+
}
13+
14+
function bar(\ReflectionMethod $r): void {
15+
try {
16+
$r->invokeArgs(new C, array());
17+
}
18+
catch (FooException $e) {
19+
print "CAUGHT FOO!\n";
20+
}
21+
}
22+
23+
function baz(\ReflectionMethod $r): void {
24+
try {
25+
$r->invoke(new C);
26+
}
27+
catch (FooException $e) {
28+
print "CAUGHT FOO!\n";
29+
}
30+
}

0 commit comments

Comments
 (0)