mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-18 22:08:00 +01:00
[PHP] Add CallUserMethodRector
This commit is contained in:
parent
f58fa272ac
commit
ecbf96a9ed
@ -9,3 +9,5 @@ services:
|
|||||||
|
|
||||||
# be careful, run this just once, since it can keep swapping order back and forth
|
# be careful, run this just once, since it can keep swapping order back and forth
|
||||||
Rector\Php\Rector\List_\ListSwapArrayOrderRector: ~
|
Rector\Php\Rector\List_\ListSwapArrayOrderRector: ~
|
||||||
|
|
||||||
|
Rector\Php\Rector\FuncCall\CallUserFuncRector: ~
|
||||||
|
86
packages/Php/src/Rector/FuncCall/CallUserMethodRector.php
Normal file
86
packages/Php/src/Rector/FuncCall/CallUserMethodRector.php
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Rector\Php\Rector\FuncCall;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\Node\Arg;
|
||||||
|
use PhpParser\Node\Expr\FuncCall;
|
||||||
|
use PhpParser\Node\Name;
|
||||||
|
use Rector\Node\NodeFactory;
|
||||||
|
use Rector\Rector\AbstractRector;
|
||||||
|
use Rector\RectorDefinition\CodeSample;
|
||||||
|
use Rector\RectorDefinition\RectorDefinition;
|
||||||
|
|
||||||
|
final class CallUserMethodRector extends AbstractRector
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var NodeFactory
|
||||||
|
*/
|
||||||
|
private $nodeFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
private $oldToNewFunctions = [
|
||||||
|
'call_user_method' => 'call_user_func',
|
||||||
|
'call_user_method_array' => 'call_user_func_array',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function __construct(NodeFactory $nodeFactory)
|
||||||
|
{
|
||||||
|
$this->nodeFactory = $nodeFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefinition(): RectorDefinition
|
||||||
|
{
|
||||||
|
return new RectorDefinition(
|
||||||
|
'Changes call_user_method()/call_user_method_array() to call_user_func()/call_user_func_array()',
|
||||||
|
[new CodeSample(
|
||||||
|
'call_user_method($method, $obj, "arg1", "arg2");',
|
||||||
|
'call_user_func(array(&$obj, "method"), "arg1", "arg2");'
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getNodeTypes(): array
|
||||||
|
{
|
||||||
|
return [FuncCall::class];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FuncCall $funcCallNode
|
||||||
|
*/
|
||||||
|
public function refactor(Node $funcCallNode): ?Node
|
||||||
|
{
|
||||||
|
$newName = $this->matchNewFunctionName($funcCallNode);
|
||||||
|
if ($newName === null) {
|
||||||
|
return $funcCallNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
$funcCallNode->name = new Name($newName);
|
||||||
|
|
||||||
|
$argNodes = $funcCallNode->args;
|
||||||
|
|
||||||
|
$funcCallNode->args[0] = new Arg($this->nodeFactory->createArray($argNodes[1]->value, $argNodes[0]->value));
|
||||||
|
unset($funcCallNode->args[1]);
|
||||||
|
|
||||||
|
// reindex from 0
|
||||||
|
$funcCallNode->args = array_values($funcCallNode->args);
|
||||||
|
|
||||||
|
return $funcCallNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function matchNewFunctionName(FuncCall $funcCallNode): ?string
|
||||||
|
{
|
||||||
|
foreach ($this->oldToNewFunctions as $oldFunction => $newFunction) {
|
||||||
|
if ((string) $funcCallNode->name === $oldFunction) {
|
||||||
|
return $newFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Rector\Php\Tests\Rector\FuncCall\CallUserMethodRector;
|
||||||
|
|
||||||
|
use Iterator;
|
||||||
|
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Rector\Php\Rector\FuncCall\CallUserMethodRector
|
||||||
|
*
|
||||||
|
* @see https://www.mail-archive.com/php-dev@lists.php.net/msg11576.html
|
||||||
|
*/
|
||||||
|
final class CallUserMethodRectorTest extends AbstractRectorTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @dataProvider provideWrongToFixedFiles()
|
||||||
|
*/
|
||||||
|
public function test(string $wrong, string $fixed): void
|
||||||
|
{
|
||||||
|
$this->doTestFileMatchesExpectedContent($wrong, $fixed);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideWrongToFixedFiles(): Iterator
|
||||||
|
{
|
||||||
|
yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc'];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function provideConfig(): string
|
||||||
|
{
|
||||||
|
return __DIR__ . '/config.yml';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$method_name = 'hi';
|
||||||
|
|
||||||
|
call_user_func_array([$obj, $method_name], $params);
|
||||||
|
|
||||||
|
call_user_func([$obj, $method_name], $params);
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$method_name = 'hi';
|
||||||
|
|
||||||
|
call_user_method_array($method_name, $obj, $params);
|
||||||
|
|
||||||
|
call_user_method($method_name, $obj, $params);
|
@ -0,0 +1,2 @@
|
|||||||
|
services:
|
||||||
|
Rector\Php\Rector\FuncCall\CallUserMethodRector: ~
|
@ -191,9 +191,7 @@ CODE_SAMPLE
|
|||||||
}
|
}
|
||||||
|
|
||||||
$node->value->args[0] = new Arg(new String_($filterName));
|
$node->value->args[0] = new Arg(new String_($filterName));
|
||||||
$node->value->args[1] = new Arg(new Array_($arrayItems, [
|
$node->value->args[1] = new Arg(new Array_($arrayItems));
|
||||||
'kind' => Array_::KIND_SHORT,
|
|
||||||
]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $node;
|
return $node;
|
||||||
|
@ -120,9 +120,7 @@ final class NodeFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Array_($arrayItems, [
|
return new Array_($arrayItems);
|
||||||
'kind' => Array_::KIND_SHORT,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace Rector\Printer;
|
namespace Rector\Printer;
|
||||||
|
|
||||||
|
use PhpParser\Node\Expr\Array_;
|
||||||
use PhpParser\Node\Expr\Yield_;
|
use PhpParser\Node\Expr\Yield_;
|
||||||
use PhpParser\Node\Stmt\Expression;
|
use PhpParser\Node\Stmt\Expression;
|
||||||
use PhpParser\Node\Stmt\Property;
|
use PhpParser\Node\Stmt\Property;
|
||||||
@ -60,4 +61,17 @@ final class BetterStandardPrinter extends Standard
|
|||||||
$this->pCommaSeparated($node->props) .
|
$this->pCommaSeparated($node->props) .
|
||||||
';';
|
';';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print arrays in short [] by default,
|
||||||
|
* to prevent manual explicit array shortening.
|
||||||
|
*/
|
||||||
|
protected function pExpr_Array(Array_ $node): string
|
||||||
|
{
|
||||||
|
if (! $node->hasAttribute('kind')) {
|
||||||
|
$node->setAttribute('kind', Array_::KIND_SHORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::pExpr_Array($node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user