Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CodingStyle] Add variadic method call unpack to CallUserFuncCallToVariadicRector #6316

Merged
merged 1 commit into from
May 3, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Fixture;

use Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Source\Redirector;

final class ArrayLocalMethod
{
private $redirector;

public function __construct()
{
$this->redirector = new Redirector();
}

public function run()
{
$args = \func_get_args();
call_user_func_array([$this->redirector, 'redirect'], $args);
}
}

?>
-----
<?php

namespace Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Fixture;

use Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Source\Redirector;

final class ArrayLocalMethod
{
private $redirector;

public function __construct()
{
$this->redirector = new Redirector();
}

public function run()
{
$args = \func_get_args();
$this->redirector->redirect(...$args);
}
}

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

namespace Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Fixture;

use Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Source\Redirector;

final class ArrayLocalMethodWithReference
{
private $redirector;

public function __construct()
{
$this->redirector = new Redirector();
}

public function run()
{
$args = \func_get_args();
call_user_func_array([&$this->redirector, 'redirect'], $args);
}
}

?>
-----
<?php

namespace Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Fixture;

use Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Source\Redirector;

final class ArrayLocalMethodWithReference
{
private $redirector;

public function __construct()
{
$this->redirector = new Redirector();
}

public function run()
{
$args = \func_get_args();
$this->redirector->redirect(...$args);
}
}

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

declare(strict_types=1);

namespace Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\Source;

final class Redirector
{
public function redirect($first, $second)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\DowngradePhp70\Rector\Coalesce\DowngradeStrictTypeDeclarationRector\Fixture;

class PropertyFetch
final class ComparePropertyFetch
{
private $a;
private $b;
Expand All @@ -19,7 +19,7 @@ class PropertyFetch

namespace Rector\Tests\DowngradePhp70\Rector\Coalesce\DowngradeStrictTypeDeclarationRector\Fixture;

class PropertyFetch
final class ComparePropertyFetch
{
private $a;
private $b;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture;

class MethodCall
final class DispatcherCall
{
/** @var \League\Event\EventDispatcher */
private $dispatcher;
Expand All @@ -24,7 +24,7 @@ class MethodCall

namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture;

class MethodCall
final class DispatcherCall
{
/** @var \League\Event\EventDispatcher */
private $dispatcher;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Scalar\String_;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @changelog https://www.php.net/manual/en/function.call-user-func-array.php#117655
* @changelog https://3v4l.org/CBWt9
*
* @see \Rector\Tests\CodingStyle\Rector\FuncCall\CallUserFuncCallToVariadicRector\CallUserFuncCallToVariadicRectorTest
*/
Expand Down Expand Up @@ -62,14 +69,58 @@ public function refactor(Node $node): ?Node
return null;
}

$functionName = $this->valueResolver->getValue($node->args[0]->value);
if (! is_string($functionName)) {
return null;
$firstArgValue = $node->args[0]->value;
$secondArgValue = $node->args[1]->value;

if ($firstArgValue instanceof String_) {
$functionName = $this->valueResolver->getValue($firstArgValue);
return $this->createFuncCall($secondArgValue, $functionName);
}

// method call
if ($firstArgValue instanceof Array_) {
return $this->createMethodCall($firstArgValue, $secondArgValue);
}

return null;
}

private function createFuncCall(Expr $expr, string $functionName): FuncCall
{
$args = [];
$args[] = new Arg($node->args[1]->value, false, true);
$args[] = new Arg($expr, false, true);

return $this->nodeFactory->createFuncCall($functionName, $args);
}

private function createMethodCall(Array_ $array, Expr $secondExpr): ?MethodCall
{
if (count($array->items) !== 2) {
return null;
}

$firstItem = $array->items[0];
$secondItem = $array->items[1];

if (! $firstItem instanceof ArrayItem) {
return null;
}

if (! $secondItem instanceof ArrayItem) {
return null;
}

if ($firstItem->value instanceof PropertyFetch) {
if (! $secondItem->value instanceof String_) {
return null;
}

$string = $secondItem->value;
$methodName = $string->value;

return new MethodCall($firstItem->value, $methodName, [new Arg($secondExpr, false, true)]);
}

return null;
}
}