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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ run them by default:
```yaml
# rector.yaml
imports:
- { resource: 'vendor/rector/rector/config/set/code-quality/*.yaml' }
- { resource: 'vendor/rector/rector/config/set/code-quality/code-quality.yaml' }
- { resource: 'vendor/rector/rector/config/set/php/php71.yaml' }
- { resource: 'vendor/rector/rector/config/set/php/php72.yaml' }
- { resource: 'vendor/rector/rector/config/set/php/php73.yaml' }
Expand Down
1 change: 1 addition & 0 deletions config/set/nette/nette-utils-code-quality.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ services:
file_get_contents: ['Nette\Utils\FileSystem', 'read']
unlink: ['Nette\Utils\FileSystem', 'delete']
rmdir: ['Nette\Utils\FileSystem', 'delete']
file_put_contents: ['Nette\Utils\FileSystem', 'write']

# strings
Rector\Nette\Rector\NotIdentical\StrposToStringsContainsRector: ~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Rector\CodingStyle\Rector\FuncCall;

use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\Greater;
Expand Down Expand Up @@ -131,7 +132,7 @@ private function getVersionNumberFormVersionString(Expr $expr): LNumber
throw new ShouldNotHappenException();
}

if (! preg_match('#^\d+\.\d+\.\d+$#', $expr->value)) {
if (! Strings::match($expr->value, '#^\d+\.\d+\.\d+$#')) {
throw new ShouldNotHappenException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Doctrine\Rector\MethodCall;

use Doctrine\ORM\EntityManagerInterface;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Scalar\String_;
Expand Down Expand Up @@ -103,7 +104,7 @@ private function convertAliasToFqn(string $name): string

private function isAlias(string $name): bool
{
return strpos($name, ':') !== false;
return Strings::contains($name, ':');
}

private function hasAlias(string $name): bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,22 @@

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp\Identical;
use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Return_;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;

/**
* @see https://www.tomasvotruba.cz/blog/2019/02/07/what-i-learned-by-using-thecodingmachine-safe/#is-there-a-better-way
*
* @see \Rector\Nette\Tests\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector\PregFunctionToNetteUtilsStringsRectorTest
*/
final class PregFunctionToNetteUtilsStringsRector extends AbstractRector
Expand All @@ -42,7 +47,7 @@ class SomeClass
public function run()
{
$content = 'Hi my name is Tom';
preg_match('#Hi#', $content);
preg_match('#Hi#', $content, $matches);
}
}
PHP
Expand All @@ -53,7 +58,7 @@ class SomeClass
public function run()
{
$content = 'Hi my name is Tom';
\Nette\Utils\Strings::match($content, '#Hi#');
$matches = \Nette\Utils\Strings::match($content, '#Hi#');
}
}
PHP
Expand All @@ -66,31 +71,79 @@ public function run()
*/
public function getNodeTypes(): array
{
return [FuncCall::class];
return [FuncCall::class, Identical::class];
}

/**
* @param FuncCall $node
* @param FuncCall|Identical $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isNames($node, array_keys($this->functionNameToMethodName))) {
if ($node instanceof Identical) {
return $this->refactorIdentical($node);
}

return $this->refactorFuncCall($node);
}

private function createMatchStaticCall(FuncCall $funcCall, string $methodName): StaticCall
{
$args = [];

if ($methodName === 'replace') {
$args[] = $funcCall->args[2];
$args[] = $funcCall->args[0];
$args[] = $funcCall->args[1];
} else {
$args[] = $funcCall->args[1];
$args[] = $funcCall->args[0];
}

return $this->createStaticCall('Nette\Utils\Strings', $methodName, $args);
}

/**
* @return FuncCall|StaticCall
*/
private function processSplit(FuncCall $funcCall, StaticCall $matchStaticCall): Expr
{
if (isset($funcCall->args[2])) {
if ($this->isValue($funcCall->args[2]->value, -1)) {
if (isset($funcCall->args[3])) {
$matchStaticCall->args[] = $funcCall->args[3];
}

return $matchStaticCall;
}

return $funcCall;
}

return $matchStaticCall;
}

/**
* @return FuncCall|StaticCall|Assign|null
*/
private function refactorFuncCall(FuncCall $funcCall): ?Expr
{
if (! $this->isNames($funcCall, array_keys($this->functionNameToMethodName))) {
return null;
}

$methodName = $this->functionNameToMethodName[$this->getName($node)];
$matchStaticCall = $this->createMatchStaticCall($node, $methodName);
$methodName = $this->functionNameToMethodName[$this->getName($funcCall)];
$matchStaticCall = $this->createMatchStaticCall($funcCall, $methodName);

// skip assigns, might be used with different return value
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
$parentNode = $funcCall->getAttribute(AttributeKey::PARENT_NODE);
if ($parentNode instanceof Assign) {
if ($methodName === 'matchAll') {
// use count
return new FuncCall(new Name('count'), [new Arg($matchStaticCall)]);
}

if ($methodName === 'split') {
return $this->processSplit($node, $matchStaticCall);
return $this->processSplit($funcCall, $matchStaticCall);
}

if ($methodName === 'replace') {
Expand All @@ -101,43 +154,43 @@ public function refactor(Node $node): ?Node
}

// assign
if (isset($node->args[2])) {
return new Assign($node->args[2]->value, $matchStaticCall);
if (isset($funcCall->args[2])) {
return new Assign($funcCall->args[2]->value, $matchStaticCall);
}

return $matchStaticCall;
}

private function createMatchStaticCall(FuncCall $funcCall, string $methodName): StaticCall
private function refactorIdentical(Identical $identical): ?Bool_
{
$args = [];
$parentNode = $identical->getAttribute(AttributeKey::PARENT_NODE);

if ($methodName === 'replace') {
$args[] = $funcCall->args[2];
$args[] = $funcCall->args[0];
$args[] = $funcCall->args[1];
} else {
$args[] = $funcCall->args[1];
$args[] = $funcCall->args[0];
if ($identical->left instanceof FuncCall) {
$refactoredFuncCall = $this->refactorFuncCall($identical->left);
if ($refactoredFuncCall !== null && $this->isValue($identical->right, 1)) {
return $this->createBoolCast($parentNode, $refactoredFuncCall);
}
}

return $this->createStaticCall('Nette\Utils\Strings', $methodName, $args);
if ($identical->right instanceof FuncCall) {
$refactoredFuncCall = $this->refactorFuncCall($identical->right);
if ($refactoredFuncCall !== null && $this->isValue($identical->left, 1)) {
return new Bool_($refactoredFuncCall);
}
}

return null;
}

private function processSplit(FuncCall $funcCall, StaticCall $matchStaticCall): Node
/**
* @param FuncCall|StaticCall|Assign $refactoredFuncCall
*/
private function createBoolCast(?Node $parentNode, Node $refactoredFuncCall): Bool_
{
if (isset($funcCall->args[2])) {
if ($this->isValue($funcCall->args[2]->value, -1)) {
if (isset($funcCall->args[3])) {
$matchStaticCall->args[] = $funcCall->args[3];
}

return $matchStaticCall;
}

return $funcCall;
if ($parentNode instanceof Return_ && $refactoredFuncCall instanceof Assign) {
$refactoredFuncCall = $refactoredFuncCall->expr;
}

return $matchStaticCall;
return new Bool_($refactoredFuncCall);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ final class SubstrStrlenFunctionToNetteUtilsStringsRector extends AbstractRector
*/
private $functionToStaticMethod = [
'substr' => 'substring',
'strlen' => 'length',
];

public function getDefinition(): RectorDefinition
Expand Down Expand Up @@ -65,9 +64,11 @@ public function getNodeTypes(): array
public function refactor(Node $node): ?Node
{
foreach ($this->functionToStaticMethod as $function => $staticMethod) {
if ($this->isName($node, $function)) {
return $this->createStaticCall('Nette\Utils\Strings', $staticMethod, $node->args);
if (! $this->isName($node, $function)) {
continue;
}

return $this->createStaticCall('Nette\Utils\Strings', $staticMethod, $node->args);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\BooleanNot;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name\FullyQualified;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;
Expand Down Expand Up @@ -74,7 +72,7 @@ public function refactor(Node $node): ?Node
return null;
}

$containsStaticCall = new StaticCall(new FullyQualified('Nette\Utils\Strings'), 'contains');
$containsStaticCall = $this->createStaticCall('Nette\Utils\Strings', 'contains');
$containsStaticCall->args[0] = $strpos->args[0];
$containsStaticCall->args[1] = $strpos->args[1];

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

namespace Rector\Nette\Tests\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector\Fixture;

class PregMatchIdenticalOne
{
public function run($content)
{
return preg_match('#\d#', $content, $matches) === 1;
}

public function go($content)
{
return 1 === preg_match('#\d#', $content);
}
}

?>
-----
<?php

namespace Rector\Nette\Tests\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector\Fixture;

class PregMatchIdenticalOne
{
public function run($content)
{
return (bool) \Nette\Utils\Strings::match($content, '#\d#');
}

public function go($content)
{
return (bool) \Nette\Utils\Strings::match($content, '#\d#');
}
}

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

namespace Rector\Nette\Tests\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector\Fixture;

class PregMatchIdenticalOneWithMatches
{
public function run($content)
{
$haveResults = preg_match('#\d#', $content, $matches) === 1;
$this->matches = $matches;

return $haveResults;
}
}

?>
-----
<?php

namespace Rector\Nette\Tests\Rector\FuncCall\PregFunctionToNetteUtilsStringsRector\Fixture;

class PregMatchIdenticalOneWithMatches
{
public function run($content)
{
$haveResults = (bool) ($matches = \Nette\Utils\Strings::match($content, '#\d#'));
$this->matches = $matches;

return $haveResults;
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public function provideDataForTest(): Iterator
yield [__DIR__ . '/Fixture/preg_split.php.inc'];
yield [__DIR__ . '/Fixture/preg_replace.php.inc'];
yield [__DIR__ . '/Fixture/preg_replace_callback.php.inc'];
yield [__DIR__ . '/Fixture/preg_match_identical_one.php.inc'];
yield [__DIR__ . '/Fixture/preg_match_identical_one_with_matches.php.inc'];
}

protected function getRectorClass(): string
Expand Down

This file was deleted.

Loading