drop preg_match support from StrContains, too vague

This commit is contained in:
TomasVotruba 2020-03-27 15:20:20 +01:00
parent 2e9c303447
commit 8f1208d18b
5 changed files with 6 additions and 158 deletions

View File

@ -0,0 +1,3 @@
services:
Rector\Php80\Rector\FunctionLike\UnionTypesRector: null
Rector\Php80\Rector\NotIdentical\StrContainsRector: null

View File

@ -17,6 +17,7 @@ use Rector\Core\RectorDefinition\RectorDefinition;
/**
* @see https://3v4l.org/CubLi
* @see https://github.com/nette/utils/blob/bd961f49b211997202bda1d0fbc410905be370d4/src/Utils/Strings.php#L81
*
* @see \Rector\Nette\Tests\Rector\NotIdentical\StrposToStringsContainsRector\StrposToStringsContainsRectorTest
*/
final class StrposToStringsContainsRector extends AbstractRector

View File

@ -4,15 +4,10 @@ declare(strict_types=1);
namespace Rector\Php80\Rector\NotIdentical;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Concat;
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Name;
use PhpParser\Node\Scalar\LNumber;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
@ -30,14 +25,9 @@ final class StrContainsRector extends AbstractRector
*/
private const OLD_STR_NAMES = ['strpos', 'strstr'];
/**
* @var string
*/
private const PREG_MATCH_NAME = 'preg_match';
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Replace strpos() !== false, strstr and preg_match() with str_contains()', [
return new RectorDefinition('Replace strpos() !== false and strstr() with str_contains()', [
new CodeSample(
<<<'PHP'
class SomeClass
@ -76,108 +66,16 @@ PHP
*/
public function refactor(Node $node): ?Node
{
$funcCall = $this->matchPossibleFuncCallToFalseOrZero($node);
$funcCall = $this->matchNotIdenticalToFalse($node);
if ($funcCall === null) {
return null;
}
if ($this->isName($funcCall, self::PREG_MATCH_NAME)) {
[$funcCall->args[0], $funcCall->args[1]] = [$funcCall->args[1], $funcCall->args[0]];
$clearedDelimiter = $this->clearValueFromDelimiters($funcCall->args[1]->value);
// unable to handle
if ($clearedDelimiter === null) {
return null;
}
$funcCall->args[1]->value = $clearedDelimiter;
}
$funcCall->name = new Name('str_contains');
return $funcCall;
}
private function matchPossibleFuncCallToFalseOrZero(NotIdentical $notIdentical): ?FuncCall
{
if ($this->isNumber($notIdentical->left, 0)) {
if (! $this->isFuncCallName($notIdentical->right, self::PREG_MATCH_NAME)) {
return null;
}
return $notIdentical->right;
}
if ($this->isNumber($notIdentical->right, 0)) {
if (! $this->isFuncCallName($notIdentical->left, self::PREG_MATCH_NAME)) {
return null;
}
return $notIdentical->left;
}
return $this->matchNotIdenticalToFalse($notIdentical);
}
private function isNumber(Expr $expr, int $value): bool
{
if (! $expr instanceof LNumber) {
return false;
}
return $expr->value === $value;
}
/**
* Possibly extract to regex package or something
*/
private function clearValueFromDelimiters(Expr $expr): ?Expr
{
// clears '#'. $value . '#'
if ($expr instanceof Concat) {
if (! $expr->right instanceof String_) {
return null;
}
$rightValue = $this->getValue($expr->right);
if (! $expr->left instanceof Concat) {
return null;
}
/** @var Concat $leftConcat */
$leftConcat = $expr->left;
if (! $leftConcat->left instanceof String_) {
return null;
}
$leftValue = $this->getValue($leftConcat->left);
if ($leftValue === $rightValue) {
return $leftConcat->right;
}
return null;
}
// clears '#content#'
if ($expr instanceof String_) {
$stringValue = $expr->value;
$firstChar = $stringValue[0];
$lastChar = $stringValue[strlen($stringValue) - 1];
if ($firstChar === $lastChar) {
$expr->value = Strings::substring($stringValue, 1, -1);
return $expr;
}
return null;
}
// not supported yet
return null;
}
private function matchNotIdenticalToFalse(NotIdentical $notIdentical): ?FuncCall
{
if ($this->isFalse($notIdentical->left)) {

View File

@ -1,27 +0,0 @@
<?php
namespace Rector\Php80\Tests\Rector\NotIdentical\StrContainsRector\Fixture;
class PregMatchFunction
{
public function run($needle, $haystack)
{
return preg_match('/' . $needle . '/', $haystack) !== 0;
}
}
?>
-----
<?php
namespace Rector\Php80\Tests\Rector\NotIdentical\StrContainsRector\Fixture;
class PregMatchFunction
{
public function run($needle, $haystack)
{
return str_contains($haystack, $needle);
}
}
?>

View File

@ -1,27 +0,0 @@
<?php
namespace Rector\Php80\Tests\Rector\NotIdentical\StrContainsRector\Fixture;
class PregMatchString
{
public function run($needle, $haystack)
{
return preg_match('#string#', $haystack) !== 0;
}
}
?>
-----
<?php
namespace Rector\Php80\Tests\Rector\NotIdentical\StrContainsRector\Fixture;
class PregMatchString
{
public function run($needle, $haystack)
{
return str_contains($haystack, 'string');
}
}
?>