Skip to content

Commit

Permalink
[Transform] Adds ArrayDimFetchToMethodCallRector rule (#5723)
Browse files Browse the repository at this point in the history
* Adds ArrayDimFetchToMethodCallRector rule

* Swap checks
  • Loading branch information
peterfox committed Mar 15, 2024
1 parent a844e40 commit cdde425
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 1 deletion.
17 changes: 16 additions & 1 deletion build/target-repository/docs/rector_rules_overview.md
Expand Up @@ -56,7 +56,7 @@

- [Strict](#strict) (5)

- [Transform](#transform) (24)
- [Transform](#transform) (25)

- [TypeDeclaration](#typedeclaration) (45)

Expand Down Expand Up @@ -5869,6 +5869,21 @@ Add interface by used trait

<br>

### ArrayDimFetchToMethodCallRector

Change array dim fetch to method call

:wrench: **configure it!**

- class: [`Rector\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector`](../rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php)

```diff
-$app['someService'];
+$app->make('someService');
```

<br>

### AttributeKeyToClassConstFetchRector

Replace key value on specific attribute to class constant
Expand Down
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector;

use Iterator;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class ArrayDimFetchToMethodCallRectorTest extends AbstractRectorTestCase
{
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
@@ -0,0 +1,17 @@
<?php

namespace Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector\Fixture;

/** @var \SomeClass $object */
$object['key']->get()

?>
-----
<?php

namespace Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector\Fixture;

/** @var \SomeClass $object */
$object->make('key')->get()

?>
@@ -0,0 +1,8 @@
<?php

namespace Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector\Fixture;

/** @var \SomeOtherClass $object */
$object['key']->get()

?>
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector\Source;

final class ChoiceControl
{

}
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector;
use Rector\Transform\ValueObject\ArrayDimFetchToMethodCall;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig
->ruleWithConfiguration(ArrayDimFetchToMethodCallRector::class, [
new ArrayDimFetchToMethodCall('SomeClass', 'make'),
]);
};
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace Rector\Transform\Rector\ArrayDimFetch;

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PHPStan\Type\ObjectType;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector;
use Rector\Transform\ValueObject\ArrayDimFetchToMethodCall;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Webmozart\Assert\Assert;

/**
* @see \Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector\ArrayDimFetchToMethodCallRectorTest
*/
class ArrayDimFetchToMethodCallRector extends AbstractRector implements ConfigurableRectorInterface
{
/**
* @var ArrayDimFetchToMethodCall[]
*/
private array $arrayDimFetchToMethodCalls;

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Change array dim fetch to method call', [
new ConfiguredCodeSample(
<<<'CODE_SAMPLE'
$app['someService'];
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
$app->make('someService');
CODE_SAMPLE
,
[new ArrayDimFetchToMethodCall('SomeClass', 'make')]
),
]);
}

public function getNodeTypes(): array
{
return [ArrayDimFetch::class];
}

/**
* @param ArrayDimFetch $node
*/
public function refactor(Node $node): ?MethodCall
{
if (! $node->var instanceof Variable) {
return null;
}

foreach ($this->arrayDimFetchToMethodCalls as $arrayDimFetchToMethodCall) {
if (! $node->dim instanceof Node) {
return null;
}

if (! $this->isObjectType($node->var, new ObjectType($arrayDimFetchToMethodCall->getClass()))) {
return null;
}

return new MethodCall($node->var, $arrayDimFetchToMethodCall->getMethod(), [new Arg($node->dim)]);
}

return null;
}

public function configure(array $configuration): void
{
Assert::allIsInstanceOf($configuration, ArrayDimFetchToMethodCall::class);

$this->arrayDimFetchToMethodCalls = $configuration;
}
}
24 changes: 24 additions & 0 deletions rules/Transform/ValueObject/ArrayDimFetchToMethodCall.php
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Rector\Transform\ValueObject;

class ArrayDimFetchToMethodCall
{
public function __construct(
private readonly string $class,
private readonly string $method
) {
}

public function getClass(): string
{
return $this->class;
}

public function getMethod(): string
{
return $this->method;
}
}

0 comments on commit cdde425

Please sign in to comment.