Skip to content

Commit

Permalink
Add Expr Throw - PHP 8 (#146)
Browse files Browse the repository at this point in the history
* Add Expr Throw - PHP 8

* check:lint only with PHP 8.0

* fix phpstan check - instanceof PHPStan\Reflection\MethodReflection
  • Loading branch information
janatjak authored May 5, 2021
1 parent 52a9223 commit 0de69d8
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ jobs:

- name: "Check lint"
run: "composer run-script check:lint"
if: ${{ matrix.php-version == '8.0' }}

- name: "Check CodeStyle"
run: "composer run-script check:cs"
Expand Down
16 changes: 15 additions & 1 deletion src/Rules/ThrowsPhpDocRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ public function processNode(Node $node, Scope $scope): array
$method = $scope->getFunction();
$isMethodWhitelisted = $method instanceof MethodReflection && $this->isWhitelistedMethod($method);
if ($node instanceof MethodReturnStatementsNode) {
if ($isMethodWhitelisted && $method instanceof MethodReflection) {
if ($isMethodWhitelisted) {
return $this->processWhitelistedMethod($method, $node->getStartLine());
}

Expand All @@ -195,6 +195,10 @@ public function processNode(Node $node, Scope $scope): array
return $this->processThrow($node, $scope);
}

if ($node instanceof Expr\Throw_) {
return $this->processExprThrow($node, $scope);
}

if ($node instanceof MethodCall) {
return $this->processMethodCall($node, $scope);
}
Expand Down Expand Up @@ -315,6 +319,16 @@ private function processThrow(Throw_ $node, Scope $scope): array
return $this->processThrowsTypes($exceptionType);
}

/**
* @return RuleError[]
*/
private function processExprThrow(Expr\Throw_ $node, Scope $scope): array
{
$exceptionType = $scope->getType($node->expr);

return $this->processThrowsTypes($exceptionType);
}

/**
* @return RuleError[]
*/
Expand Down
8 changes: 8 additions & 0 deletions tests/src/Rules/ThrowsPhpDocRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ public function testBasicThrows(): void
$this->analyseFile(__DIR__ . '/data/throws-annotations.php');
}

/**
* @requires PHP 8.0
*/
public function testExpressionThrows(): void
{
$this->analyseFile(__DIR__ . '/data/expression-throws.php');
}

public function testTryCatch(): void
{
$this->analyseFile(__DIR__ . '/data/try-catch.php');
Expand Down
79 changes: 79 additions & 0 deletions tests/src/Rules/data/expression-throws.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php declare(strict_types = 1);

namespace Pepakriz\PHPStanExceptionRules\Rules\ExpressionThrows;

use RuntimeException;

class FooException extends RuntimeException
{
public static function create(): self
{
return new self();
}
}

/**
* @throws FooException
*/
function foo1() {
$callable = fn() => throw new FooException();
}

/**
* @throws FooException
*/
function foo2() {
return match (random_bytes(1)) {
'a' => 'b',
default => throw new FooException(),
};
}

/**
* @throws FooException
*/
function foo3() {
$value = $nullableValue ?? throw new FooException();
}

/**
* @throws FooException
*/
function foo4() {
$value = $falsableValue ?: throw new FooException();
}


class FutureThrows
{
private ?string $name;

/**
* @throws FooException
*/
public function ok1(): string
{
return $this->name ?? throw new FooException();
}

/**
* @throws FooException
*/
public function ok2(): string
{
return $this->name ?? $this->ok2();
}

/**
* @throws FooException
*/
public function ok3(): string
{
return $this->name ?? throw FooException::create();
}

public function err(): string
{
return $this->name ?? throw new FooException(); // error: Missing @throws Pepakriz\PHPStanExceptionRules\Rules\ExpressionThrows\FooException annotation
}
}

0 comments on commit 0de69d8

Please sign in to comment.