Skip to content

Commit

Permalink
[Php55][Renaming] Handle rename string on combination StringClassName…
Browse files Browse the repository at this point in the history
…ToClassConstantRector+RenameStringRector (#4869)

* [Php55][Renaming] Handle rename string on combination StringClassNameToClassConstantRector+RenameStringRector

* [ci-review] Rector Rectify

* it works 🎉

* fix

* [ci-review] Rector Rectify

---------

Co-authored-by: GitHub Action <actions@github.com>
  • Loading branch information
samsonasik and actions-user authored Aug 28, 2023
1 parent 1c56aa9 commit 684a317
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 5 deletions.
6 changes: 6 additions & 0 deletions packages/NodeTypeResolver/Node/AttributeKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ final class AttributeKey
*/
public const CREATED_BY_RULE = 'created_by_rule';

/**
* Helps with skipped below node
* @var string
*/
public const SKIPPED_BY_RECTOR_RULE = 'skipped_rector_rule';

/**
* @var string
*/
Expand Down
6 changes: 5 additions & 1 deletion src/ProcessAnalyzer/RectifiedAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ public function hasRectified(string $rectorClass, Node $node): bool
return true;
}

return $this->isJustReprintedOverlappedTokenStart($node, $originalNode);
if ($this->isJustReprintedOverlappedTokenStart($node, $originalNode)) {
return true;
}

return $node->getAttribute(AttributeKey::SKIPPED_BY_RECTOR_RULE) === $rectorClass;
}

/**
Expand Down
33 changes: 29 additions & 4 deletions src/Rector/AbstractRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,16 @@ final public function enterNode(Node $node): int|Node|null
if (is_int($refactoredNode)) {
$this->createdByRuleDecorator->decorate($node, $originalNode, static::class);

// notify this rule changing code
$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);
if (! in_array($refactoredNode, [NodeTraverser::DONT_TRAVERSE_CHILDREN, NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN], true)) {
// notify this rule changing code
$rectorWithLineChange = new RectorWithLineChange(static::class, $originalNode->getLine());
$this->file->addRectorClassWithLine($rectorWithLineChange);

return $refactoredNode;
return $refactoredNode;
}

$this->decorateCurrentAndChildren($node);
return null;
}

// nothing to change → continue
Expand All @@ -215,6 +220,26 @@ final public function enterNode(Node $node): int|Node|null
return $this->postRefactorProcess($originalNode, $node, $refactoredNode, $filePath);
}

private function decorateCurrentAndChildren(Node $node): void
{
// filter only types that
// 1. registered in getNodesTypes() method
// 2. different with current node type, as already decorated above
//
$types = array_filter(
$this->getNodeTypes(),
static fn (string $nodeType): bool => $nodeType !== $node::class
);
$this->traverseNodesWithCallable($node, static function (Node $subNode) use ($types) {
if (in_array($subNode::class, $types, true)) {
$subNode->setAttribute(AttributeKey::SKIPPED_BY_RECTOR_RULE, static::class);
$subNode->setAttribute(AttributeKey::SKIPPED_BY_RECTOR_RULE, static::class);
}

return null;
});
}

/**
* Replacing nodes in leaveNode() method avoids infinite recursion
* see"infinite recursion" in /~https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
Expand Down
35 changes: 35 additions & 0 deletions tests/Issues/RenameString/Fixture/rename_string.php.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Rector\Core\Tests\Issues\DoubleRun\Fixture;

final class RenameString
{
public function run($variable)
{
return is_a(
$variable,
'Rector\Core\Tests\Issues\DoubleRun\Fixture\RenameString',
true
);
}
}

?>
-----
<?php

namespace Rector\Core\Tests\Issues\DoubleRun\Fixture;

final class RenameString
{
public function run($variable)
{
return is_a(
$variable,
'new test',
true
);
}
}

?>
28 changes: 28 additions & 0 deletions tests/Issues/RenameString/RenameStringTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Rector\Core\Tests\Issues\RenameString;

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

final class RenameStringTest 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';
}
}
18 changes: 18 additions & 0 deletions tests/Issues/RenameString/config/configured_rule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
use Rector\Renaming\Rector\String_\RenameStringRector;

use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->rule(StringClassNameToClassConstantRector::class);

$rectorConfig->ruleWithConfiguration(
RenameStringRector::class,
[
'Rector\Core\Tests\Issues\DoubleRun\Fixture\RenameString' => 'new test',
]
);
};

0 comments on commit 684a317

Please sign in to comment.