File tree 8 files changed +146
-1
lines changed
8 files changed +146
-1
lines changed Original file line number Diff line number Diff line change 26
26
- PHPStan\Rules\Classes\ExistingClassInTraitUseRule
27
27
- PHPStan\Rules\Classes\InstantiationRule
28
28
- PHPStan\Rules\Classes\NewStaticRule
29
+ - PHPStan\Rules\Exceptions\ThrowExpressionRule
29
30
- PHPStan\Rules\Functions\CallToFunctionParametersRule
30
31
- PHPStan\Rules\Functions\ExistingClassesInArrowFunctionTypehintsRule
31
32
- PHPStan\Rules\Functions\ExistingClassesInClosureTypehintsRule
Original file line number Diff line number Diff line change @@ -494,7 +494,7 @@ private function getNodeKey(Expr $node): string
494
494
495
495
private function resolveType (Expr $ node ): Type
496
496
{
497
- if ($ node instanceof Expr \Exit_) {
497
+ if ($ node instanceof Expr \Exit_ || $ node instanceof Expr \Throw_ ) {
498
498
return new NeverType ();
499
499
}
500
500
Original file line number Diff line number Diff line change @@ -61,4 +61,9 @@ public function requiresParenthesesForNestedTernaries(): bool
61
61
return $ this ->versionId >= 80000 ;
62
62
}
63
63
64
+ public function supportsThrowExpression (): bool
65
+ {
66
+ return $ this ->versionId >= 80000 ;
67
+ }
68
+
64
69
}
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ namespace PHPStan \Rules \Exceptions ;
4
+
5
+ use PhpParser \Node ;
6
+ use PHPStan \Analyser \Scope ;
7
+ use PHPStan \Php \PhpVersion ;
8
+ use PHPStan \Rules \Rule ;
9
+ use PHPStan \Rules \RuleErrorBuilder ;
10
+
11
+ /**
12
+ * @implements Rule<Node\Expr\Throw_>
13
+ */
14
+ class ThrowExpressionRule implements Rule
15
+ {
16
+
17
+ private PhpVersion $ phpVersion ;
18
+
19
+ public function __construct (PhpVersion $ phpVersion )
20
+ {
21
+ $ this ->phpVersion = $ phpVersion ;
22
+ }
23
+
24
+ public function getNodeType (): string
25
+ {
26
+ return Node \Expr \Throw_::class;
27
+ }
28
+
29
+ public function processNode (Node $ node , Scope $ scope ): array
30
+ {
31
+ if ($ this ->phpVersion ->supportsThrowExpression ()) {
32
+ return [];
33
+ }
34
+
35
+ return [
36
+ RuleErrorBuilder::message ('Throw expression is supported only on PHP 8.0 and later. ' )->nonIgnorable ()->build (),
37
+ ];
38
+ }
39
+
40
+ }
Original file line number Diff line number Diff line change @@ -10146,6 +10146,15 @@ public function dataPow(): array
10146
10146
return $ this ->gatherAssertTypes (__DIR__ . '/data/pow.php ' );
10147
10147
}
10148
10148
10149
+ public function dataThrowExpression (): array
10150
+ {
10151
+ if (PHP_VERSION_ID < 80000 && !self ::$ useStaticReflectionProvider ) {
10152
+ return [];
10153
+ }
10154
+
10155
+ return $ this ->gatherAssertTypes (__DIR__ . '/data/throw-expr.php ' );
10156
+ }
10157
+
10149
10158
/**
10150
10159
* @dataProvider dataBug2574
10151
10160
* @dataProvider dataBug2577
@@ -10223,6 +10232,7 @@ public function dataPow(): array
10223
10232
* @dataProvider dataBug1014
10224
10233
* @dataProvider dataBugFromPr339
10225
10234
* @dataProvider dataPow
10235
+ * @dataProvider dataThrowExpression
10226
10236
* @param string $assertType
10227
10237
* @param string $file
10228
10238
* @param mixed ...$args
Original file line number Diff line number Diff line change
1
+ <?php // lint >= 8.0
2
+
3
+ namespace ThrowExpr ;
4
+
5
+ use function PHPStan \Analyser \assertType ;
6
+
7
+ class Foo
8
+ {
9
+
10
+ public function doFoo (bool $ b ): void
11
+ {
12
+ $ result = $ b ? true : throw new \Exception ();
13
+ assertType ('true ' , $ result );
14
+ }
15
+
16
+ public function doBar (): void
17
+ {
18
+ assertType ('*NEVER* ' , throw new \Exception ());
19
+ }
20
+
21
+ }
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ namespace PHPStan \Rules \Exceptions ;
4
+
5
+ use PHPStan \Php \PhpVersion ;
6
+ use PHPStan \Rules \Rule ;
7
+ use PHPStan \Testing \RuleTestCase ;
8
+
9
+ /**
10
+ * @extends RuleTestCase<ThrowExpressionRule>
11
+ */
12
+ class ThrowExpressionRuleTest extends RuleTestCase
13
+ {
14
+
15
+ /** @var PhpVersion */
16
+ private $ phpVersion ;
17
+
18
+ protected function getRule (): Rule
19
+ {
20
+ return new ThrowExpressionRule ($ this ->phpVersion );
21
+ }
22
+
23
+ public function dataRule (): array
24
+ {
25
+ return [
26
+ [
27
+ 70400 ,
28
+ [
29
+ [
30
+ 'Throw expression is supported only on PHP 8.0 and later. ' ,
31
+ 10 ,
32
+ ],
33
+ ],
34
+ ],
35
+ [
36
+ 80000 ,
37
+ [],
38
+ ],
39
+ ];
40
+ }
41
+
42
+ /**
43
+ * @dataProvider dataRule
44
+ * @param int $phpVersion
45
+ * @param mixed[] $expectedErrors
46
+ */
47
+ public function testRule (int $ phpVersion , array $ expectedErrors ): void
48
+ {
49
+ $ this ->phpVersion = new PhpVersion ($ phpVersion );
50
+ $ this ->analyse ([__DIR__ . '/data/throw-expr.php ' ], $ expectedErrors );
51
+ }
52
+
53
+ }
Original file line number Diff line number Diff line change
1
+ <?php
2
+
3
+ namespace ThrowExpr ;
4
+
5
+ class Bar
6
+ {
7
+
8
+ public function doFoo (bool $ b ): void
9
+ {
10
+ $ b ? true : throw new \Exception ();
11
+
12
+ throw new \Exception ();
13
+ }
14
+
15
+ }
You can’t perform that action at this time.
0 commit comments