Skip to content

Commit fbafe21

Browse files
committed
Merge branch 2.1.x into 2.2.x
2 parents e6fb781 + f077b36 commit fbafe21

File tree

7 files changed

+239
-9
lines changed

7 files changed

+239
-9
lines changed

src/Analyser/ExprHandler/MethodCallHandler.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,6 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
110110
$methodReflection->getNamedArgumentsVariants(),
111111
);
112112

113-
$methodThrowPoint = $this->getMethodThrowPoint($methodReflection, $parametersAcceptor, $expr, $scope);
114-
if ($methodThrowPoint !== null) {
115-
$throwPoints[] = $methodThrowPoint;
116-
}
117113
}
118114
} else {
119115
$methodNameResult = $nodeScopeResolver->processExprNode($stmt, $expr->name, $scope, $storage, $nodeCallback, $context->enterDeep());
@@ -157,6 +153,13 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
157153
$scope = $argsResult->getScope();
158154

159155
if ($methodReflection !== null) {
156+
if ($parametersAcceptor !== null) {
157+
$methodThrowPoint = $this->getMethodThrowPoint($methodReflection, $parametersAcceptor, $expr, $scope);
158+
if ($methodThrowPoint !== null) {
159+
$throwPoints[] = $methodThrowPoint;
160+
}
161+
}
162+
160163
if ($methodReflection->getName() === '__construct' || $methodReflection->hasSideEffects()->yes()) {
161164
$nodeScopeResolver->callNodeCallback($nodeCallback, new InvalidateExprNode($normalizedExpr->var), $scope, $storage);
162165
$scope = $scope->invalidateExpression($normalizedExpr->var, true, $methodReflection->getDeclaringClass());

src/Analyser/ExprHandler/StaticCallHandler.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,6 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
103103
$methodReflection->getNamedArgumentsVariants(),
104104
);
105105

106-
$methodThrowPoint = $this->getStaticMethodThrowPoint($methodReflection, $parametersAcceptor, $expr, $scope);
107-
if ($methodThrowPoint !== null) {
108-
$throwPoints[] = $methodThrowPoint;
109-
}
110-
111106
$declaringClass = $methodReflection->getDeclaringClass();
112107
if (
113108
$declaringClass->getName() === 'Closure'
@@ -203,6 +198,13 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex
203198
$scope = $argsResult->getScope();
204199
$scopeFunction = $scope->getFunction();
205200

201+
if ($methodReflection !== null && $parametersAcceptor !== null) {
202+
$methodThrowPoint = $this->getStaticMethodThrowPoint($methodReflection, $parametersAcceptor, $expr, $scope);
203+
if ($methodThrowPoint !== null) {
204+
$throwPoints[] = $methodThrowPoint;
205+
}
206+
}
207+
206208
if (
207209
$methodReflection !== null
208210
&& (

tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,16 @@ public function testBug9349(): void
14221422
]);
14231423
}
14241424

1425+
public function testBug14318(): void
1426+
{
1427+
$this->cliArgumentsVariablesRegistered = true;
1428+
$this->polluteScopeWithLoopInitialAssignments = false;
1429+
$this->checkMaybeUndefinedVariables = true;
1430+
$this->polluteScopeWithAlwaysIterableForeach = true;
1431+
1432+
$this->analyse([__DIR__ . '/data/bug-14318.php'], []);
1433+
}
1434+
14251435
#[RequiresPhp('>= 8.0')]
14261436
public function testBug14274(): void
14271437
{

tests/PHPStan/Rules/Variables/EmptyRuleTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ public function testBug10367(): void
209209
$this->analyse([__DIR__ . '/data/bug-10367.php'], []);
210210
}
211211

212+
public function testBug11284(): void
213+
{
214+
$this->treatPhpDocTypesAsCertain = true;
215+
216+
$this->analyse([__DIR__ . '/data/bug-11284.php'], []);
217+
}
218+
219+
public function testBug7806(): void
220+
{
221+
$this->treatPhpDocTypesAsCertain = true;
222+
223+
$this->analyse([__DIR__ . '/data/bug-7806.php'], []);
224+
}
225+
212226
#[RequiresPhp('>= 8.0')]
213227
public function testIssetAfterRememberedConstructor(): void
214228
{
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug11284;
4+
5+
class HelloWorld
6+
{
7+
8+
/**
9+
* @param array<string> $err
10+
* @throws \RuntimeException
11+
*/
12+
public function maybeThrows(array &$err): void
13+
{
14+
$err[] = 'error';
15+
if (random_int(0, 1) === 1) {
16+
throw new \RuntimeException();
17+
}
18+
}
19+
20+
public function test(): void
21+
{
22+
$err = [];
23+
try {
24+
$this->maybeThrows($err);
25+
} catch (\RuntimeException $e) {
26+
if (!empty($err)) {
27+
echo implode(', ', $err);
28+
}
29+
}
30+
}
31+
32+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug14318;
4+
5+
class HelloWorld5
6+
{
7+
public function test5(): void
8+
{
9+
global $pdo;
10+
11+
try {
12+
$this->maybeThrows5($sql = "SELECT * FROM foo");
13+
$rs = $pdo->query($sql);
14+
if ($result = $rs->fetch(\PDO::FETCH_ASSOC)) {
15+
// do something
16+
}
17+
} catch (\PDOException $e) {
18+
var_dump($sql);
19+
}
20+
}
21+
22+
/**
23+
* @throws \RuntimeException
24+
*/
25+
public function maybeThrows5(string $s): void
26+
{
27+
if (random_int(0, 1) === 1) {
28+
throw new \RuntimeException();
29+
}
30+
}
31+
}
32+
33+
class HelloWorld6
34+
{
35+
public function test6(): void
36+
{
37+
global $pdo;
38+
39+
try {
40+
$this->maybeThrows6(strlen($sql = "SELECT * FROM foo"));
41+
$rs = $pdo->query($sql);
42+
if ($result = $rs->fetch(\PDO::FETCH_ASSOC)) {
43+
// do something
44+
}
45+
} catch (\PDOException $e) {
46+
var_dump($sql);
47+
}
48+
}
49+
50+
/**
51+
* @throws \RuntimeException
52+
*/
53+
public function maybeThrows6(int $s): void
54+
{
55+
if (random_int(0, 1) === 1) {
56+
throw new \RuntimeException();
57+
}
58+
}
59+
}
60+
61+
class HelloWorld7Static
62+
{
63+
public function test7(): void
64+
{
65+
global $pdo;
66+
67+
try {
68+
self::maybeThrows7($sql = "SELECT * FROM foo");
69+
$rs = $pdo->query($sql);
70+
if ($result = $rs->fetch(\PDO::FETCH_ASSOC)) {
71+
// do something
72+
}
73+
} catch (\PDOException $e) {
74+
var_dump($sql);
75+
}
76+
}
77+
78+
/**
79+
* @throws \RuntimeException
80+
*/
81+
public static function maybeThrows7(string $s): void
82+
{
83+
if (random_int(0, 1) === 1) {
84+
throw new \RuntimeException();
85+
}
86+
}
87+
}
88+
89+
class HelloWorld8Static
90+
{
91+
public function test8(): void
92+
{
93+
global $pdo;
94+
95+
try {
96+
self::maybeThrows8(strlen($sql = "SELECT * FROM foo"));
97+
$rs = $pdo->query($sql);
98+
if ($result = $rs->fetch(\PDO::FETCH_ASSOC)) {
99+
// do something
100+
}
101+
} catch (\PDOException $e) {
102+
var_dump($sql);
103+
}
104+
}
105+
106+
/**
107+
* @throws \RuntimeException
108+
*/
109+
public static function maybeThrows8(int $s): void
110+
{
111+
if (random_int(0, 1) === 1) {
112+
throw new \RuntimeException();
113+
}
114+
}
115+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug7806;
4+
5+
class TestMethod {
6+
/**
7+
* @param array<string>|null $reasons
8+
* @throws \Exception
9+
*/
10+
function check(array &$reasons = null): void {
11+
$fileName = time() % 2 ? "abc":null;
12+
if (!$fileName) {
13+
$reasons[] = sprintf("Dependency check fail");
14+
throw new \Exception("check failed");
15+
}
16+
}
17+
18+
function test():void {
19+
try {
20+
$this->check($reasons);
21+
printf("ok\n");
22+
} catch (\Exception $e) {
23+
if (!empty($reasons)) {
24+
$e = new \Exception("Dependency check failed: " . implode(', ', $reasons), 0, $e);
25+
}
26+
throw new \Exception("Failed", 0, $e);
27+
}
28+
}
29+
}
30+
31+
/**
32+
* @param array<string>|null $reasons
33+
* @throws \Exception
34+
*/
35+
function check1(array &$reasons = null): void {
36+
$fileName = time() % 2 ? "abc":null;
37+
if (!$fileName) {
38+
$reasons[] = sprintf("Dependency check fail");
39+
throw new \Exception("check failed");
40+
}
41+
}
42+
43+
function test1():void {
44+
try {
45+
check1($reasons);
46+
printf("ok\n");
47+
} catch (\Exception $e) {
48+
if (!empty($reasons)) {
49+
$e = new \Exception("Dependency check failed: " . implode(', ', $reasons), 0, $e);
50+
}
51+
throw new \Exception("Failed", 0, $e);
52+
}
53+
}
54+

0 commit comments

Comments
 (0)