|
4 | 4 | namespace Rector\CodingStyle\Rector\FuncCall; |
5 | 5 |
|
6 | 6 | use PhpParser\Node; |
| 7 | +use PhpParser\Node\Arg; |
| 8 | +use PhpParser\Node\Expr; |
| 9 | +use PhpParser\Node\Expr\Array_; |
| 10 | +use PhpParser\Node\Expr\ClassConstFetch; |
| 11 | +use PhpParser\Node\Expr\FuncCall; |
| 12 | +use PhpParser\Node\Expr\MethodCall; |
| 13 | +use PhpParser\Node\Expr\StaticCall; |
| 14 | +use PhpParser\Node\Expr\Variable; |
| 15 | +use PhpParser\Node\Identifier; |
| 16 | +use PhpParser\Node\Name; |
| 17 | +use PhpParser\Node\Name\FullyQualified; |
| 18 | +use PhpParser\Node\Scalar\String_; |
| 19 | +use PhpParser\Node\VariadicPlaceholder; |
7 | 20 | use Rector\Rector\AbstractRector; |
8 | 21 | use Rector\ValueObject\PhpVersionFeature; |
9 | 22 | use Rector\VersionBonding\Contract\MinPhpVersionInterface; |
|
14 | 27 | */ |
15 | 28 | final class ClosureFromCallableToFirstClassCallableRector extends AbstractRector implements MinPhpVersionInterface |
16 | 29 | { |
17 | | - public function __construct() |
18 | | - { |
19 | | - } |
20 | 30 | public function getRuleDefinition() : RuleDefinition |
21 | 31 | { |
22 | | - return new RuleDefinition('Change `Closure::fromCallable()` to first class callable syntax', [new CodeSample('Closure::fromCallable([$obj, \'method\']);', '$obj->method(...);'), new CodeSample('Closure::fromCallable(\'trim\');', 'trim(...);'), new CodeSample('Closure::fromCallable([\'SomeClass\', \'staticMethod\']);', 'SomeClass::staticMethod(...);')]); |
| 32 | + return new RuleDefinition('Change `Closure::fromCallable()` to first class callable syntax', [new CodeSample('Closure::fromCallable([$obj, \'method\']);', '$obj->method(...);'), new CodeSample("Closure::fromCallable('trim');", 'trim(...);'), new CodeSample("Closure::fromCallable(['SomeClass', 'staticMethod']);", 'SomeClass::staticMethod(...);')]); |
23 | 33 | } |
24 | 34 | /** |
25 | 35 | * @return array<class-string<Node>> |
26 | 36 | */ |
27 | 37 | public function getNodeTypes() : array |
28 | 38 | { |
29 | | - return [Node\Expr\StaticCall::class]; |
| 39 | + return [StaticCall::class]; |
30 | 40 | } |
31 | 41 | /** |
32 | | - * @param Node\Expr\StaticCall $node |
| 42 | + * @param StaticCall $node |
33 | 43 | */ |
34 | 44 | public function refactor(Node $node) : ?Node |
35 | 45 | { |
36 | 46 | if ($this->shouldSkip($node)) { |
37 | 47 | return null; |
38 | 48 | } |
39 | 49 | $arg = $node->args[0]; |
40 | | - if (!$arg instanceof Node\Arg) { |
| 50 | + if (!$arg instanceof Arg) { |
41 | 51 | return null; |
42 | 52 | } |
43 | | - if ($arg->value instanceof Node\Scalar\String_) { |
44 | | - return new Node\Expr\FuncCall($this->toFullyQualified($arg->value->value), [new Node\VariadicPlaceholder()]); |
| 53 | + if ($arg->value instanceof String_) { |
| 54 | + return new FuncCall($this->toFullyQualified($arg->value->value), [new VariadicPlaceholder()]); |
45 | 55 | } |
46 | | - if ($arg->value instanceof Node\Expr\Array_) { |
47 | | - if (!\array_key_exists(0, $arg->value->items) || !\array_key_exists(1, $arg->value->items) || !$arg->value->items[1]->value instanceof Node\Scalar\String_) { |
| 56 | + if ($arg->value instanceof Array_) { |
| 57 | + if (!\array_key_exists(0, $arg->value->items) || !\array_key_exists(1, $arg->value->items) || !$arg->value->items[1]->value instanceof String_) { |
48 | 58 | return null; |
49 | 59 | } |
50 | | - if ($arg->value->items[0]->value instanceof Node\Expr\Variable) { |
51 | | - return new Node\Expr\MethodCall($arg->value->items[0]->value, $arg->value->items[1]->value->value, [new Node\VariadicPlaceholder()]); |
| 60 | + if ($arg->value->items[0]->value instanceof Variable) { |
| 61 | + return new MethodCall($arg->value->items[0]->value, $arg->value->items[1]->value->value, [new VariadicPlaceholder()]); |
52 | 62 | } |
53 | | - if ($arg->value->items[0]->value instanceof Node\Scalar\String_) { |
54 | | - $classNode = new Node\Name\FullyQualified($arg->value->items[0]->value->value); |
55 | | - } elseif ($arg->value->items[0]->value instanceof Node\Expr\ClassConstFetch) { |
56 | | - if ($arg->value->items[0]->value->class instanceof Node\Expr) { |
| 63 | + if ($arg->value->items[0]->value instanceof String_) { |
| 64 | + $classNode = new FullyQualified($arg->value->items[0]->value->value); |
| 65 | + } elseif ($arg->value->items[0]->value instanceof ClassConstFetch) { |
| 66 | + if ($arg->value->items[0]->value->class instanceof Expr) { |
57 | 67 | return null; |
58 | 68 | } |
59 | | - $classNode = new Node\Name\FullyQualified($arg->value->items[0]->value->class->name); |
60 | | - } elseif ($arg->value->items[0]->value instanceof Node\Name\FullyQualified) { |
61 | | - $classNode = new Node\Name\FullyQualified($arg->value->items[0]->value->name); |
| 69 | + $classNode = new FullyQualified($arg->value->items[0]->value->class->name); |
| 70 | + } elseif ($arg->value->items[0]->value instanceof FullyQualified) { |
| 71 | + $classNode = new FullyQualified($arg->value->items[0]->value->name); |
62 | 72 | } else { |
63 | 73 | return null; |
64 | 74 | } |
65 | | - return new Node\Expr\StaticCall($classNode, $arg->value->items[1]->value->value, [new Node\VariadicPlaceholder()]); |
| 75 | + return new StaticCall($classNode, $arg->value->items[1]->value->value, [new VariadicPlaceholder()]); |
66 | 76 | } |
67 | 77 | return $node; |
68 | 78 | } |
69 | 79 | public function provideMinPhpVersion() : int |
70 | 80 | { |
71 | 81 | return PhpVersionFeature::FIRST_CLASS_CALLABLE_SYNTAX; |
72 | 82 | } |
73 | | - public function shouldSkip(Node\Expr\StaticCall $node) : bool |
| 83 | + public function shouldSkip(StaticCall $staticCall) : bool |
74 | 84 | { |
75 | | - if (!$node->class instanceof Node\Name) { |
76 | | - return \true; |
77 | | - } |
78 | | - if (!$this->isName($node->class, 'Closure')) { |
| 85 | + if (!$staticCall->class instanceof Name) { |
79 | 86 | return \true; |
80 | 87 | } |
81 | | - if (!$node->name instanceof Node\Identifier || $node->name->name !== 'fromCallable') { |
| 88 | + if (!$this->isName($staticCall->class, 'Closure')) { |
82 | 89 | return \true; |
83 | 90 | } |
84 | | - if ($node->isFirstClassCallable()) { |
| 91 | + if (!$staticCall->name instanceof Identifier || $staticCall->name->name !== 'fromCallable') { |
85 | 92 | return \true; |
86 | 93 | } |
87 | | - $args = $node->getArgs(); |
88 | | - if (\count($args) !== 1) { |
| 94 | + if ($staticCall->isFirstClassCallable()) { |
89 | 95 | return \true; |
90 | 96 | } |
91 | | - return \false; |
| 97 | + $args = $staticCall->getArgs(); |
| 98 | + return \count($args) !== 1; |
92 | 99 | } |
93 | | - public function toFullyQualified(string $functionName) : Node\Name\FullyQualified |
| 100 | + public function toFullyQualified(string $functionName) : FullyQualified |
94 | 101 | { |
95 | 102 | // in case there's already a \ prefix, remove it |
96 | 103 | $functionName = \ltrim($functionName, '\\'); |
97 | | - return new Node\Name\FullyQualified($functionName); |
| 104 | + return new FullyQualified($functionName); |
98 | 105 | } |
99 | 106 | } |
0 commit comments