Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions easy-coding-standard.neon
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ parameters:
- bin/rector.php
# test file
- tests/Rector/Contrib/Nette/Routing/BootstrapToRouterFactoryRector/Wrong/bootstrap.php
# value object
- packages/NodeTypeResolver/src/NodeVisitor/NamespaceResolver.php
13 changes: 7 additions & 6 deletions packages/NodeTypeResolver/src/NodeVisitor/NamespaceResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@

use PhpParser\Node;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\Use_;
use PhpParser\Node\Stmt\UseUse;
use PhpParser\NodeVisitorAbstract;
use Rector\Node\Attribute;
use Rector\NodeTypeResolver\UseStatements;

final class NamespaceResolver extends NodeVisitorAbstract
{
/**
* @var string[]
* @var UseStatements
*/
private $useStatements = [];
private $useStatements;

/**
* @var string|null
Expand All @@ -26,7 +27,7 @@ final class NamespaceResolver extends NodeVisitorAbstract
public function beforeTraverse(array $nodes): void
{
$this->namespace = null;
$this->useStatements = [];
$this->useStatements = new UseStatements;
}

public function enterNode(Node $node): void
Expand All @@ -35,8 +36,8 @@ public function enterNode(Node $node): void
$this->namespace = $node->name ? $node->name->toString() : '';
}

if ($node instanceof Use_) {
$this->useStatements[] = $node->uses[0]->name->toString();
if ($node instanceof UseUse) {
$this->useStatements->addUseStatement($node->name->toString());
}

$node->setAttribute(Attribute::NAMESPACE, $this->namespace);
Expand Down
24 changes: 24 additions & 0 deletions packages/NodeTypeResolver/src/UseStatements.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php declare(strict_types=1);

namespace Rector\NodeTypeResolver;

final class UseStatements
{
/**
* @var string[]
*/
private $useStatements = [];

public function addUseStatement(string $useStatement): void
{
$this->useStatements[] = $useStatement;
}

/**
* @return string[]
*/
public function getUseStatements(): array
{
return $this->useStatements;
}
}
7 changes: 6 additions & 1 deletion src/NodeAnalyzer/ClassConstAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ private function isClassName(ClassConstFetch $classConstFetchNode, string $class
/** @var FullyQualified $className */
$classFullyQualifiedName = $classConstFetchNode->class->getAttribute(Attribute::RESOLVED_NAME);

$nodeClassName = $classFullyQualifiedName->toString();
if ($classFullyQualifiedName instanceof FullyQualified) {
return $classFullyQualifiedName->toString() === $className;
}

// e.g. $form::FILLED
$nodeClassName = $classConstFetchNode->class->getAttribute(Attribute::CLASS_NAME);

return $nodeClassName === $className;
}
Expand Down
41 changes: 0 additions & 41 deletions src/Rector/AbstractClassReplacerRector.php

This file was deleted.

69 changes: 64 additions & 5 deletions src/Rector/Dynamic/ClassReplacerRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@

namespace Rector\Rector\Dynamic;

use Rector\Rector\AbstractClassReplacerRector;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Use_;
use PhpParser\Node\Stmt\UseUse;
use Rector\Node\Attribute;
use Rector\NodeTypeResolver\UseStatements;
use Rector\Rector\AbstractRector;

final class ClassReplacerRector extends AbstractClassReplacerRector
final class ClassReplacerRector extends AbstractRector
{
/**
* @var string[]
Expand All @@ -19,11 +26,63 @@ public function __construct(array $oldToNewClasses)
$this->oldToNewClasses = $oldToNewClasses;
}

public function isCandidate(Node $node): bool
{
if (! $node instanceof Name && ! $node instanceof Use_) {
return false;
}

$name = $this->resolveNameFromNode($node);

return isset($this->oldToNewClasses[$name]);
}

/**
* @return string[]
* @param Name|UseUse $node
*/
protected function getOldToNewClasses(): array
public function refactor(Node $node): ?Node
{
return $this->oldToNewClasses;
if ($node instanceof Name) {
$newName = $this->getNewName($node->toString());

return new FullyQualified($newName);
}

if ($node instanceof Use_) {
$name = $this->resolveNameFromNode($node);
$newName = $this->getNewName($name);

if ($this->isUseStatmenetAlreadyPresent($node, $newName)) {
$this->shouldRemoveNode = true;
}
}

return null;
}

private function getNewName(string $oldName): string
{
return $this->oldToNewClasses[$oldName];
}

private function isUseStatmenetAlreadyPresent(Use_ $useNode, string $newName): bool
{
/** @var UseStatements $useStatments */
$useStatments = $useNode->getAttribute(Attribute::USE_STATEMENTS);

return in_array($newName, $useStatments->getUseStatements(), true);
}

private function resolveNameFromNode(Node $node): string
{
if ($node instanceof Name) {
return $node->toString();
}

if ($node instanceof Use_) {
return $node->uses[0]->name->toString();
}

return '';
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?php declare(strict_types=1);

use Bagr;

use NewClass;

class SomeClass
{
public function create()
{
$newClass = new NewClass;

return new \NewClass;
}
}
5 changes: 5 additions & 0 deletions tests/Rector/Dynamic/ClassReplacerRector/wrong/wrong.php.inc
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<?php declare(strict_types=1);

use Bagr;
use OldClass;
use NewClass;

class SomeClass
{
public function create()
{
$newClass = new NewClass;

return new OldClass;
}
}