Skip to content

Commit

Permalink
Merge pull request #922 from WinterSilence/patch-1
Browse files Browse the repository at this point in the history
Add `ReflectionFunctionAbstract::couldThrow()`
  • Loading branch information
Ocramius committed Dec 25, 2021
2 parents b02fa4d + fd3e956 commit 24a0301
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/Reflection/ReflectionFunctionAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
use PhpParser\Node;
use PhpParser\Node\Expr\Yield_ as YieldNode;
use PhpParser\Node\Expr\YieldFrom as YieldFromNode;
use PhpParser\Node\Stmt\Throw_ as NodeThrow;
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\FindingVisitor;
use PhpParser\PrettyPrinter\Standard as StandardPrettyPrinter;
use PhpParser\PrettyPrinterAbstract;
use Roave\BetterReflection\Reflection\Annotation\AnnotationHelper;
Expand Down Expand Up @@ -188,6 +190,17 @@ public function isVariadic(): bool
return false;
}

/** Checks if the function/method contains `throw` expressions. */
public function couldThrow(): bool
{
$visitor = new FindingVisitor(static fn (Node $node): bool => $node instanceof NodeThrow);
$traverser = new NodeTraverser();
$traverser->addVisitor($visitor);
$traverser->traverse($this->getBodyAst());

return $visitor->getFoundNodes() !== [];
}

/**
* Recursively search an array of statements (PhpParser nodes) to find if a
* yield expression exists anywhere (thus indicating this is a generator).
Expand Down
25 changes: 25 additions & 0 deletions test/unit/Reflection/ReflectionFunctionAbstractTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -700,4 +700,29 @@ public function testGetAttributesByInstance(): void

self::assertCount(2, $attributes);
}

public function testCouldThrow(): void
{
$php = <<<'PHP'
<?php
function foo($a) {
if ($a === null) {
throw new Exception('Invalid a!');
}
}
PHP;
$reflector = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
$function = $reflector->reflectFunction('foo');
self::assertTrue($function->couldThrow());

$php = <<<'PHP'
<?php
function foo(object $obj) {
echo $obj instanceof Throwable ? 'throw' : 'not throw';
}
PHP;
$reflector = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));
$function = $reflector->reflectFunction('foo');
self::assertNotTrue($function->couldThrow());
}
}

0 comments on commit 24a0301

Please sign in to comment.