Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ class Fixture
{
$isIt = in_array(strtolower($type), ['$this'], true);
$isIt = in_array(strtolower($type), ['$this']);

$isIt = in_array(strtolower($type), ['$this', 'two']);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this skipped part for multi data moved to specific fixture

https://github.com/rectorphp/rector-src/pull/5205/files#diff-a723d5612fbb34df879841e8ee175b22f5f9cd3d1523111e41d52ac3d74aa27f

to ease discover bug in the future.

}
}

Expand All @@ -25,8 +23,6 @@ class Fixture
{
$isIt = strtolower($type) === '$this';
$isIt = strtolower($type) == '$this';

$isIt = in_array(strtolower($type), ['$this', 'two']);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector\Fixture;

class NegatedInArray
{
public function run()
{
$isIt = ! in_array(strtolower($type), ['$this'], true);
$isIt = ! in_array(strtolower($type), ['$this']);
}
}

?>
-----
<?php

namespace Rector\Tests\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector\Fixture;

class NegatedInArray
{
public function run()
{
$isIt = strtolower($type) !== '$this';
$isIt = strtolower($type) != '$this';
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector\Fixture;

class SkipMultiData
{
public function run()
{
$isIt = in_array(strtolower($type), ['$this', 'two']);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Rector\Tests\CodeQuality\Rector\FuncCall\SingleInArrayToCompareRector\Fixture;

class SkipNegatedMultiData
{
public function run()
{
$isIt = ! in_array(strtolower($type), ['$this', 'two']);
}
}
61 changes: 48 additions & 13 deletions rules/CodeQuality/Rector/FuncCall/SingleInArrayToCompareRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\BinaryOp\Equal;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\BinaryOp\NotEqual;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\FuncCall;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
Expand Down Expand Up @@ -59,36 +62,59 @@ public function run()
*/
public function getNodeTypes(): array
{
return [FuncCall::class];
return [BooleanNot::class, FuncCall::class];
}

/**
* @param FuncCall $node
* @param BooleanNot|FuncCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isName($node, 'in_array')) {
if ($node instanceof BooleanNot) {
if (! $node->expr instanceof FuncCall) {
return null;
}

$firstArrayItem = $this->resolveArrayItem($node->expr);
if (! $firstArrayItem instanceof ArrayItem) {
return null;
}

return $this->processCompare($firstArrayItem, $node->expr, true);
}

$firstArrayItem = $this->resolveArrayItem($node);
if (! $firstArrayItem instanceof ArrayItem) {
return null;
}

return $this->processCompare($firstArrayItem, $node);
}

private function resolveArrayItem(FuncCall $funcCall): ?ArrayItem
{
if (! $this->isName($funcCall, 'in_array')) {
return null;
}

if ($node->isFirstClassCallable()) {
if ($funcCall->isFirstClassCallable()) {
return null;
}

if (! isset($node->args[1])) {
if (! isset($funcCall->args[1])) {
return null;
}

if (! $node->args[1] instanceof Arg) {
if (! $funcCall->args[1] instanceof Arg) {
return null;
}

if (! $node->args[1]->value instanceof Array_) {
if (! $funcCall->args[1]->value instanceof Array_) {
return null;
}

/** @var Array_ $arrayNode */
$arrayNode = $node->args[1]->value;
$arrayNode = $funcCall->args[1]->value;
if (count($arrayNode->items) !== 1) {
return null;
}
Expand All @@ -102,19 +128,28 @@ public function refactor(Node $node): ?Node
return null;
}

if (! isset($node->getArgs()[0])) {
if (! isset($funcCall->getArgs()[0])) {
return null;
}

return $firstArrayItem;
}

private function processCompare(ArrayItem $firstArrayItem, FuncCall $funcCall, bool $isNegated = false): Node
{
$firstArrayItemValue = $firstArrayItem->value;

$firstArg = $node->getArgs()[0];
$firstArg = $funcCall->getArgs()[0];

// strict
if (isset($node->getArgs()[2])) {
return new Identical($firstArg->value, $firstArrayItemValue);
if (isset($funcCall->getArgs()[2])) {
return $isNegated
? new NotIdentical($firstArg->value, $firstArrayItemValue)
: new Identical($firstArg->value, $firstArrayItemValue);
}

return new Equal($firstArg->value, $firstArrayItemValue);
return $isNegated
? new NotEqual($firstArg->value, $firstArrayItemValue)
: new Equal($firstArg->value, $firstArrayItemValue);
}
}