[CodeQuality] Drop ArrayThisCallToThisMethodCallRector as changes behavior and better handled by FirstClassCallableRector (#2571)

This commit is contained in:
Tomas Votruba 2022-06-26 12:11:25 +02:00 committed by GitHub
parent 237f255023
commit 80715e62b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 2 additions and 405 deletions

View File

@ -1,4 +1,4 @@
# 520 Rules Overview
# 519 Rules Overview
<br>
@ -6,7 +6,7 @@
- [Arguments](#arguments) (5)
- [CodeQuality](#codequality) (73)
- [CodeQuality](#codequality) (72)
- [CodingStyle](#codingstyle) (35)
@ -390,30 +390,6 @@ Change array_merge of non arrays to array directly
<br>
### ArrayThisCallToThisMethodCallRector
Change `[$this, someMethod]` without any args to `$this->someMethod()`
- class: [`Rector\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector`](../rules/CodeQuality/Rector/Array_/ArrayThisCallToThisMethodCallRector.php)
```diff
class SomeClass
{
public function run()
{
- $values = [$this, 'giveMeMore'];
+ $values = $this->giveMeMore();
}
public function giveMeMore()
{
return 'more';
}
}
```
<br>
### BooleanNotIdenticalToNotIdenticalRector
Negated identical boolean compare to not identical compare (does not apply to non-bool values)

View File

@ -2,7 +2,6 @@
declare(strict_types=1);
use Rector\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector;
use Rector\CodeQuality\Rector\Array_\CallableThisArrayToAnonymousFunctionRector;
use Rector\CodeQuality\Rector\Assign\CombinedAssignRector;
use Rector\CodeQuality\Rector\Assign\SplitListAssignToSeparateLineRector;
@ -162,7 +161,6 @@ return static function (RectorConfig $rectorConfig): void {
ArrayKeysAndInArrayToArrayKeyExistsRector::class,
SplitListAssignToSeparateLineRector::class,
UnusedForeachValueToArrayKeysRector::class,
ArrayThisCallToThisMethodCallRector::class,
CommonNotEqualRector::class,
SetTypeToCastRector::class,
LogicalToBooleanRector::class,

View File

@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector;
use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;
final class ArrayThisCallToThisMethodCallRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(SmartFileInfo $fileInfo): void
{
$this->doTestFileInfo($fileInfo);
}
/**
* @return Iterator<SmartFileInfo>
*/
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class Fixture
{
public function run()
{
$values = $this->giveMeMore();
}
public function giveMeMore()
{
return 'more';
}
}
?>

View File

@ -1,37 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class PrivateMethod
{
public function run()
{
$values = [$this, 'giveMeMore'];
}
private function giveMeMore()
{
return 'more';
}
}
?>
-----
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class PrivateMethod
{
public function run()
{
$values = $this->giveMeMore();
}
private function giveMeMore()
{
return 'more';
}
}
?>

View File

@ -1,17 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class SkipCallWithArgs
{
public function run()
{
$values = [1, 5, 3];
usort($values, [$this, 'compareSize']);
}
private function compareSize($first, $second)
{
return $first <=> $second;
}
}

View File

@ -1,15 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class SkipFunctionArguments
{
public function run()
{
register_shutdown_function([$this, 'shutdown']);
}
private function shutdown()
{
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class SkipInProperty
{
private static $listen = [
'run' => [self::class, 'run'],
];
public function __invoke()
{
$handler = self::$listen['run'];
call_user_func($handler, 'data');
}
public function run(string $data)
{
}
}

View File

@ -1,20 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
use Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Source\SomeConstantInteger;
final class SkipNonCallable
{
public function run()
{
$this->process('tags', [
'usage' => SomeConstantInteger::VALUE,
'region' => 'tags',
]);
}
public function process()
{
}
}

View File

@ -1,12 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
class SkipNonExistingMethod
{
public function run()
{
$values = [1, 5, 3];
usort($values, [$this, 'compareSizeThat']);
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Fixture;
use Nette\Application\UI\Form;
class SkipOnNetteEvent
{
public function run()
{
$form = new Form();
$form->onSuccess[] = [$this, 'giveMeMore'];
}
public function giveMeMore()
{
return 'more';
}
}

View File

@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\Source;
final class SomeConstantInteger
{
const VALUE = 10000;
}

View File

@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
use Rector\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector;
use Rector\Config\RectorConfig;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(ArrayThisCallToThisMethodCallRector::class);
};

View File

@ -1,153 +0,0 @@
<?php
declare(strict_types=1);
namespace Rector\CodeQuality\Rector\Array_;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Property;
use PHPStan\Reflection\ReflectionProvider;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher;
use Rector\NodeCollector\ValueObject\ArrayCallable;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
/**
* @see \Rector\Tests\CodeQuality\Rector\Array_\ArrayThisCallToThisMethodCallRector\ArrayThisCallToThisMethodCallRectorTest
*/
final class ArrayThisCallToThisMethodCallRector extends AbstractRector
{
public function __construct(
private readonly ArrayCallableMethodMatcher $arrayCallableMethodMatcher,
private readonly ReflectionProvider $reflectionProvider
) {
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change `[$this, someMethod]` without any args to $this->someMethod()',
[
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$values = [$this, 'giveMeMore'];
}
public function giveMeMore()
{
return 'more';
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
{
public function run()
{
$values = $this->giveMeMore();
}
public function giveMeMore()
{
return 'more';
}
}
CODE_SAMPLE
),
]
);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Array_::class];
}
/**
* @param Array_ $node
*/
public function refactor(Node $node): ?Node
{
$arrayCallable = $this->arrayCallableMethodMatcher->match($node);
if (! $arrayCallable instanceof ArrayCallable) {
return null;
}
if ($this->isAssignedToNetteMagicOnProperty($node)) {
return null;
}
if ($this->isInsideProperty($node)) {
return null;
}
$parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
// skip if part of method
if ($parentNode instanceof Arg) {
return null;
}
if (! $this->reflectionProvider->hasClass($arrayCallable->getClass())) {
return null;
}
$classReflection = $this->reflectionProvider->getClass($arrayCallable->getClass());
if (! $classReflection->hasMethod($arrayCallable->getMethod())) {
return null;
}
$nativeReflectionClass = $classReflection->getNativeReflection();
$nativeReflectionMethod = $nativeReflectionClass->getMethod($arrayCallable->getMethod());
if ($nativeReflectionMethod->getNumberOfParameters() === 0) {
return new MethodCall(new Variable('this'), $arrayCallable->getMethod());
}
$extendedMethodReflection = $classReflection->getNativeMethod($arrayCallable->getMethod());
return $this->nodeFactory->createClosureFromMethodReflection($extendedMethodReflection);
}
private function isAssignedToNetteMagicOnProperty(Array_ $array): bool
{
$parent = $array->getAttribute(AttributeKey::PARENT_NODE);
if (! $parent instanceof Assign) {
return false;
}
if (! $parent->var instanceof ArrayDimFetch) {
return false;
}
if (! $parent->var->var instanceof PropertyFetch) {
return false;
}
/** @var PropertyFetch $propertyFetch */
$propertyFetch = $parent->var->var;
return $this->isName($propertyFetch->name, 'on*');
}
private function isInsideProperty(Array_ $array): bool
{
$parentProperty = $this->betterNodeFinder->findParentType($array, Property::class);
return $parentProperty !== null;
}
}

View File

@ -42,7 +42,6 @@ use PhpParser\Node\Stmt\Use_;
use PhpParser\Node\Stmt\UseUse;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
@ -53,7 +52,6 @@ use Rector\Core\Exception\NotImplementedYetException;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeDecorator\PropertyTypeDecorator;
use Rector\Core\Php\PhpVersionProvider;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\ValueObject\MethodName;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeNameResolver\NodeNameResolver;
@ -83,7 +81,6 @@ final class NodeFactory
private readonly NodeNameResolver $nodeNameResolver,
private readonly PhpDocTypeChanger $phpDocTypeChanger,
private readonly CurrentNodeProvider $currentNodeProvider,
private readonly AstResolver $reflectionAstResolver,
private readonly PropertyTypeDecorator $propertyTypeDecorator
) {
}
@ -459,16 +456,6 @@ final class NodeFactory
return new ConstFetch(new Name('true'));
}
public function createClosureFromMethodReflection(MethodReflection $methodReflection): Closure
{
$classMethod = $this->reflectionAstResolver->resolveClassMethodFromMethodReflection($methodReflection);
if (! $classMethod instanceof ClassMethod) {
throw new ShouldNotHappenException();
}
return $this->createClosureFromClassMethod($classMethod);
}
/**
* @param string|ObjectReference::* $constantName
*/