-
Notifications
You must be signed in to change notification settings - Fork 458
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bleeding edge - report catch with exception that is not thrown in the…
… try block
- Loading branch information
1 parent
79642dc
commit ce9299c
Showing
7 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Node; | ||
|
||
use PhpParser\Node\Stmt\Catch_; | ||
use PhpParser\NodeAbstract; | ||
use PHPStan\Type\Type; | ||
|
||
class CatchWithUnthrownExceptionNode extends NodeAbstract implements VirtualNode | ||
{ | ||
|
||
private Catch_ $originalNode; | ||
|
||
private Type $caughtType; | ||
|
||
public function __construct(Catch_ $originalNode, Type $caughtType) | ||
{ | ||
parent::__construct($originalNode->getAttributes()); | ||
$this->originalNode = $originalNode; | ||
$this->caughtType = $caughtType; | ||
} | ||
|
||
public function getOriginalNode(): Catch_ | ||
{ | ||
return $this->originalNode; | ||
} | ||
|
||
public function getCaughtType(): Type | ||
{ | ||
return $this->caughtType; | ||
} | ||
|
||
public function getType(): string | ||
{ | ||
return 'PHPStan_Node_CatchWithUnthrownExceptionNode'; | ||
} | ||
|
||
/** | ||
* @return string[] | ||
*/ | ||
public function getSubNodeNames(): array | ||
{ | ||
return []; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Exceptions; | ||
|
||
use PhpParser\Node; | ||
use PHPStan\Analyser\Scope; | ||
use PHPStan\Node\CatchWithUnthrownExceptionNode; | ||
use PHPStan\Rules\Rule; | ||
use PHPStan\Rules\RuleErrorBuilder; | ||
use PHPStan\Type\VerbosityLevel; | ||
|
||
/** | ||
* @implements Rule<CatchWithUnthrownExceptionNode> | ||
*/ | ||
class CatchWithUnthrownExceptionRule implements Rule | ||
{ | ||
|
||
public function getNodeType(): string | ||
{ | ||
return CatchWithUnthrownExceptionNode::class; | ||
} | ||
|
||
public function processNode(Node $node, Scope $scope): array | ||
{ | ||
return [ | ||
RuleErrorBuilder::message( | ||
sprintf('Dead catch - %s is never thrown in the try block.', $node->getCaughtType()->describe(VerbosityLevel::typeOnly())) | ||
)->line($node->getLine())->build(), | ||
]; | ||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
tests/PHPStan/Rules/Exceptions/CatchWithUnthrownExceptionRuleTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace PHPStan\Rules\Exceptions; | ||
|
||
use PHPStan\Rules\Rule; | ||
use PHPStan\Testing\RuleTestCase; | ||
|
||
class CatchWithUnthrownExceptionRuleTest extends RuleTestCase | ||
{ | ||
|
||
protected function getRule(): Rule | ||
{ | ||
return new CatchWithUnthrownExceptionRule(); | ||
} | ||
|
||
public function testRule(): void | ||
{ | ||
$this->analyse([__DIR__ . '/data/unthrown-exception.php'], [ | ||
[ | ||
'Dead catch - Throwable is never thrown in the try block.', | ||
12, | ||
], | ||
[ | ||
'Dead catch - Exception is never thrown in the try block.', | ||
21, | ||
], | ||
[ | ||
'Dead catch - Throwable is never thrown in the try block.', | ||
38, | ||
], | ||
[ | ||
'Dead catch - RuntimeException is never thrown in the try block.', | ||
47, | ||
], | ||
]); | ||
} | ||
|
||
} |
63 changes: 63 additions & 0 deletions
63
tests/PHPStan/Rules/Exceptions/data/unthrown-exception.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
<?php | ||
|
||
namespace UnthrownException; | ||
|
||
class Foo | ||
{ | ||
|
||
public function doFoo(): void | ||
{ | ||
try { | ||
$foo = 1; | ||
} catch (\Throwable $e) { | ||
// pass | ||
} | ||
} | ||
|
||
public function doBar(): void | ||
{ | ||
try { | ||
$foo = 1; | ||
} catch (\Exception $e) { | ||
// pass | ||
} | ||
} | ||
|
||
/** @throws \InvalidArgumentException */ | ||
public function throwIae(): void | ||
{ | ||
|
||
} | ||
|
||
public function doBaz(): void | ||
{ | ||
try { | ||
$this->throwIae(); | ||
} catch (\InvalidArgumentException $e) { | ||
|
||
} catch (\Throwable $e) { | ||
// dead | ||
} | ||
} | ||
|
||
public function doLorem(): void | ||
{ | ||
try { | ||
$this->throwIae(); | ||
} catch (\RuntimeException $e) { | ||
// dead | ||
} catch (\Throwable $e) { | ||
|
||
} | ||
} | ||
|
||
public function doIpsum(): void | ||
{ | ||
try { | ||
$this->throwIae(); | ||
} catch (\Throwable $e) { | ||
|
||
} | ||
} | ||
|
||
} |