Skip to content

Commit

Permalink
[Core] Add BetterNodeFinder::hasInstancesOfInFunctionLikeScoped() to …
Browse files Browse the repository at this point in the history
…handle only true when has same parent FunctionLike (#1405)

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Dec 6, 2021
1 parent b257048 commit 9beed78
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 49 deletions.
59 changes: 10 additions & 49 deletions rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,18 +97,25 @@ public function refactor(Node $node): ?Node

private function shouldSkip(ClassMethod | Function_ $node): bool
{
if ($this->hasReturnNode($node)) {
$hasReturn = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped($node, Return_::class);
if ($hasReturn) {
return true;
}

$yieldAndConditionalNodes = array_merge([Yield_::class], ControlStructure::CONDITIONAL_NODE_SCOPE_TYPES);
$hasNotNeverNodes = $this->hasNotNeverNodes($node, $yieldAndConditionalNodes);
$hasNotNeverNodes = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped(
$node,
$yieldAndConditionalNodes
);

if ($hasNotNeverNodes) {
return true;
}

$hasNeverNodes = $this->hasNeverNodes($node);
$hasNeverNodes = $this->betterNodeFinder->hasInstancesOfInFunctionLikeScoped(
$node,
[Node\Expr\Throw_::class, Throw_::class]
);
$hasNeverFuncCall = $this->hasNeverFuncCall($node);

if (! $hasNeverNodes && ! $hasNeverFuncCall) {
Expand All @@ -128,52 +135,6 @@ private function shouldSkip(ClassMethod | Function_ $node): bool
return $this->isName($node->returnType, 'never');
}

private function hasReturnNode(ClassMethod | Function_ $functionLike): bool
{
return (bool) $this->betterNodeFinder->findFirst((array) $functionLike->stmts, function (Node $subNode) use (
$functionLike
): bool {
if (! $subNode instanceof Return_) {
return false;
}

$parentFunctionOrClassMethod = $this->betterNodeFinder->findParentByTypes($subNode, $this->getNodeTypes());
return $parentFunctionOrClassMethod === $functionLike;
});
}

/**
* @param class-string<Node>[] $yieldAndConditionalNodes
*/
private function hasNotNeverNodes(ClassMethod | Function_ $functionLike, array $yieldAndConditionalNodes): bool
{
return (bool) $this->betterNodeFinder->findFirst((array) $functionLike->stmts, function (Node $subNode) use (
$functionLike,
$yieldAndConditionalNodes
): bool {
if (! in_array($subNode::class, $yieldAndConditionalNodes, true)) {
return false;
}

$parentFunctionOrClassMethod = $this->betterNodeFinder->findParentByTypes($subNode, $this->getNodeTypes());
return $parentFunctionOrClassMethod === $functionLike;
});
}

private function hasNeverNodes(ClassMethod | Function_ $functionLike): bool
{
return (bool) $this->betterNodeFinder->findFirst((array) $functionLike->stmts, function (Node $subNode) use (
$functionLike
): bool {
if (! in_array($subNode::class, [Node\Expr\Throw_::class, Throw_::class], true)) {
return false;
}

$parentFunctionOrClassMethod = $this->betterNodeFinder->findParentByTypes($subNode, $this->getNodeTypes());
return $parentFunctionOrClassMethod === $functionLike;
});
}

private function hasNeverFuncCall(ClassMethod | Function_ $functionLike): bool
{
$hasNeverType = false;
Expand Down
25 changes: 25 additions & 0 deletions src/PhpParser/Node/BetterNodeFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,31 @@ public function findSameNamedExprs(Expr | Variable | Property | PropertyFetch |
);
}

/**
* @template T of Node
* @param array<class-string<T>>|class-string<T> $types
*/
public function hasInstancesOfInFunctionLikeScoped(ClassMethod | Function_ $functionLike, string|array $types): bool
{
if (is_string($types)) {
$types = [$types];
}

foreach ($types as $type) {
$foundNode = $this->findFirstInstanceOf((array) $functionLike->stmts, $type);
if (! $foundNode instanceof Node) {
continue;
}

$parentFunctionLike = $this->findParentType($foundNode, $functionLike::class);
if ($parentFunctionLike === $functionLike) {
return true;
}
}

return false;
}

/**
* @template T of Node
* @param Node|Node[] $nodes
Expand Down

0 comments on commit 9beed78

Please sign in to comment.