Skip to content

Commit

Permalink
[Php74] Add CurlyToSquareBracketArrayStringRector (#858)
Browse files Browse the repository at this point in the history
* [Php74] Add CurlyToSquareBracketArrayStringRector

* add fixture

* check type

* use ArrayDimFetch

* implemented

* skip already square

* phpstan

* register to php 7.4 config set

* set ORIGINAL_NODE = null

* eol

* handle constant array type

* [ci-review] Rector Rectify

* Fixed 🎉

* fix

* cs fix

* add comment for original node null

Co-authored-by: GitHub Action <action@github.com>
  • Loading branch information
samsonasik and actions-user committed Sep 11, 2021
1 parent bcde56b commit c71f6ee
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 0 deletions.
3 changes: 3 additions & 0 deletions config/set/php74.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

declare(strict_types=1);

use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Rector\Php74\Rector\Assign\NullCoalescingOperatorRector;
use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
use Rector\Php74\Rector\Double\RealToFloatTypeCastRector;
Expand Down Expand Up @@ -61,4 +62,6 @@
$services->set(ChangeReflectionTypeToStringToGetNameRector::class);

$services->set(RestoreDefaultNullToNullableTypePropertyRector::class);

$services->set(CurlyToSquareBracketArrayStringRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
use Symplify\SmartFileSystem\SmartFileInfo;

final class CurlyToSquareBracketArrayStringRectorTest 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';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace Rector\Tests\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector\Fixture;

class Fixture
{
public function runString(string $string)
{
return $string{0};
}

public function runArray(array $array)
{
return $array{0};
}

public function runArray2()
{
$array = ['a'];
return $array{0};
}
}

?>
-----
<?php

namespace Rector\Tests\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector\Fixture;

class Fixture
{
public function runString(string $string)
{
return $string[0];
}

public function runArray(array $array)
{
return $array[0];
}

public function runArray2()
{
$array = ['a'];
return $array[0];
}
}

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

namespace Rector\Tests\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector\Fixture;

class SkipAlreadySquare
{
public function runString(string $alreadySquare)
{
return $alreadySquare[0];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

use Rector\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(CurlyToSquareBracketArrayStringRector::class);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace Rector\Php74\Rector\ArrayDimFetch;

use PhpParser\Node;
use PhpParser\Node\Expr\ArrayDimFetch;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Php74\Tokenizer\FollowedByCurlyBracketAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* @changelog https://www.php.net/manual/en/migration74.deprecated.php
* @see \Rector\Tests\Php74\Rector\ArrayDimFetch\CurlyToSquareBracketArrayStringRector\CurlyToSquareBracketArrayStringRectorTest
*/
final class CurlyToSquareBracketArrayStringRector extends AbstractRector
{
public function __construct(private FollowedByCurlyBracketAnalyzer $followedByCurlyBracketAnalyzer)
{
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
'Change curly based array and string to square bracket',
[
new CodeSample(
<<<'CODE_SAMPLE'
$string = 'test';
echo $string{0};
$array = ['test'];
echo $array{0};
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
$string = 'test';
echo $string[0];
$array = ['test'];
echo $array[0];
CODE_SAMPLE
),
]
);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ArrayDimFetch::class];
}

/**
* @param ArrayDimFetch $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->followedByCurlyBracketAnalyzer->isFollowed($this->file, $node)) {
return null;
}

// re-draw the ArrayDimFetch to use [] bracket
$node->setAttribute(AttributeKey::ORIGINAL_NODE, null);
return $node;
}
}
19 changes: 19 additions & 0 deletions rules/Php74/Tokenizer/FollowedByCurlyBracketAnalyzer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Rector\Php74\Tokenizer;

use PhpParser\Node;
use Rector\Core\ValueObject\Application\File;

final class FollowedByCurlyBracketAnalyzer
{
public function isFollowed(File $file, Node $node): bool
{
$oldTokens = $file->getOldTokens();
$endTokenPost = $node->getEndTokenPos();

return isset($oldTokens[$endTokenPost]) && $oldTokens[$endTokenPost] === '}';
}
}

0 comments on commit c71f6ee

Please sign in to comment.