Skip to content

Commit

Permalink
[Php80] Handle crash leaveNode() returned invalid value of type integ…
Browse files Browse the repository at this point in the history
…er on TokenGetAllToObjectRector (#3644)

Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user authored Apr 21, 2023
1 parent add5582 commit c203b60
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Rector\Tests\Php80\Rector\FuncCall\TokenGetAllToObjectRector\Fixture;

final class NotArrayFirst2
{
public function run()
{
$code = '<?php echo 1;';

$tokens = token_get_all($code);
$this->tokens = [];
foreach ($tokens as $token) {
if (!is_array($token) || ($token[0] !== T_WHITESPACE && $token[0] !== T_INLINE_HTML)) {
$this->tokens = $token;
}
}
}
}

?>
-----
<?php

namespace Rector\Tests\Php80\Rector\FuncCall\TokenGetAllToObjectRector\Fixture;

final class NotArrayFirst2
{
public function run()
{
$code = '<?php echo 1;';

$tokens = \PhpToken::tokenize($code);
$this->tokens = [];
foreach ($tokens as $token) {
if (!$token->is(T_WHITESPACE) && !$token->is(T_INLINE_HTML)) {
$this->tokens = $token->text;
}
}
}
}

?>
79 changes: 54 additions & 25 deletions rules/Php80/NodeManipulator/TokenManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\FuncCall;
Expand Down Expand Up @@ -135,11 +137,12 @@ public function refactorTokenIsKind(array $nodes, Variable $singleTokenVariable)
{
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, function (Node $node) use (
$singleTokenVariable
): ?MethodCall {
if (! $node instanceof Identical) {
): null|MethodCall|BooleanNot {
if (! $this->isIdenticalOrNotIdentical($node)) {
return null;
}

/** @var Identical|NotIdentical $node */
$arrayDimFetchAndConstFetch = $this->matchArrayDimFetchAndConstFetch($node);
if (! $arrayDimFetchAndConstFetch instanceof ArrayDimFetchAndConstFetch) {
return null;
Expand All @@ -156,19 +159,21 @@ public function refactorTokenIsKind(array $nodes, Variable $singleTokenVariable)
return null;
}

$constName = $this->nodeNameResolver->getName($constFetch);
if ($constName === null) {
return null;
}

$constName = (string) $this->nodeNameResolver->getName($constFetch);
if (! StringUtils::isMatch($constName, '#^T_#')) {
return null;
}

return $this->createIsTConstTypeMethodCall(
$isTConstTypeMethodCall = $this->createIsTConstTypeMethodCall(
$arrayDimFetch,
$arrayDimFetchAndConstFetch->getConstFetch()
);

if ($node instanceof Identical) {
return $isTConstTypeMethodCall;
}

return new BooleanNot($isTConstTypeMethodCall);
});
}

Expand Down Expand Up @@ -212,11 +217,27 @@ public function removeIsArray(array $nodes, Variable $singleTokenVariable): void
return $node;
}

if (! $parentNode instanceof BooleanNot) {
$this->nodesToRemoveCollector->addNodeToRemove($nodeToRemove);
return $node;
}

$parentOfParentNode = $parentNode->getAttribute(AttributeKey::PARENT_NODE);
if ($parentOfParentNode instanceof BinaryOp) {
$this->nodesToRemoveCollector->addNodeToRemove($parentNode);
return $node;
}

$this->nodesToRemoveCollector->addNodeToRemove($nodeToRemove);
return $node;
});
}

private function isIdenticalOrNotIdentical(Node $node): bool
{
return $node instanceof Identical || $node instanceof NotIdentical;
}

private function replaceTernary(Ternary $ternary): void
{
$currentStmt = $this->betterNodeFinder->resolveCurrentStatement($ternary);
Expand Down Expand Up @@ -298,7 +319,7 @@ private function isArrayDimFetchWithDimIntegerValue(ArrayDimFetch $arrayDimFetch
return $this->valueResolver->isValue($arrayDimFetch->dim, $value);
}

private function matchArrayDimFetchAndConstFetch(Identical $identical): ?ArrayDimFetchAndConstFetch
private function matchArrayDimFetchAndConstFetch(Identical|NotIdentical $identical): ?ArrayDimFetchAndConstFetch
{
if ($identical->left instanceof ArrayDimFetch && $identical->right instanceof ConstFetch) {
return new ArrayDimFetchAndConstFetch($identical->left, $identical->right);
Expand Down Expand Up @@ -329,12 +350,14 @@ private function shouldSkipNodeRemovalForPartOfIf(FuncCall $funcCall): bool
return true;
}

if ($parentNode instanceof BooleanNot) {
$parentParentNode = $parentNode->getAttribute(AttributeKey::PARENT_NODE);
if ($parentParentNode instanceof If_) {
$parentParentNode->cond = $parentNode;
return true;
}
if (! $parentNode instanceof BooleanNot) {
return false;
}

$parentParentNode = $parentNode->getAttribute(AttributeKey::PARENT_NODE);
if ($parentParentNode instanceof If_) {
$parentParentNode->cond = $parentNode;
return true;
}

return false;
Expand All @@ -343,18 +366,24 @@ private function shouldSkipNodeRemovalForPartOfIf(FuncCall $funcCall): bool
private function matchParentNodeInCaseOfIdenticalTrue(FuncCall $funcCall): Identical | FuncCall
{
$parentNode = $funcCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof Identical) {
$isRightValueTrue = $this->valueResolver->isValue($parentNode->right, true);
if ($parentNode->left === $funcCall && $isRightValueTrue) {
return $parentNode;
}
if (! $parentNode instanceof Identical) {
return $funcCall;
}

$isLeftValueTrue = $this->valueResolver->isValue($parentNode->left, true);
if ($parentNode->right === $funcCall && $isLeftValueTrue) {
return $parentNode;
}
$isRightValueTrue = $this->valueResolver->isValue($parentNode->right, true);
if ($parentNode->left === $funcCall && $isRightValueTrue) {
return $parentNode;
}

$isLeftValueTrue = $this->valueResolver->isValue($parentNode->left, true);
if ($parentNode->right !== $funcCall) {
return $funcCall;
}

if (! $isLeftValueTrue) {
return $funcCall;
}

return $funcCall;
return $parentNode;
}
}

0 comments on commit c203b60

Please sign in to comment.