Skip to content

Commit

Permalink
Avoid parent node lookup in RemoveEmptyClassMethodRector (#4129)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Jun 8, 2023
1 parent 059783f commit 8268750
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 58 deletions.
38 changes: 24 additions & 14 deletions rules/CodeQuality/Rector/New_/NewStaticToNewSelfRector.php
Expand Up @@ -25,7 +25,7 @@ public function getRuleDefinition(): RuleDefinition
return new RuleDefinition('Change unsafe new static() to new self()', [
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
final class SomeClass
{
public function build()
{
Expand All @@ -36,7 +36,7 @@ public function build()

,
<<<'CODE_SAMPLE'
class SomeClass
final class SomeClass
{
public function build()
{
Expand All @@ -53,29 +53,39 @@ public function build()
*/
public function getNodeTypes(): array
{
return [New_::class];
return [Class_::class];
}

/**
* @param New_ $node
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
if (! $node->isFinal()) {
return null;
}

if (! $class->isFinal()) {
return null;
}
$hasChanged = false;

if (! $this->isName($node->class, ObjectReference::STATIC)) {
return null;
}
$this->traverseNodesWithCallable($node, function (Node $node) use (&$hasChanged): ?New_ {
if (! $node instanceof New_) {
return null;
}

$node->class = new Name(ObjectReference::SELF);
if (! $this->isName($node->class, ObjectReference::STATIC)) {
return null;
}

$hasChanged = true;

$node->class = new Name(ObjectReference::SELF);
return $node;
});

if ($hasChanged) {
return $node;
}

return $node;
return null;
}
}
53 changes: 31 additions & 22 deletions rules/DeadCode/Rector/ClassMethod/RemoveEmptyClassMethodRector.php
Expand Up @@ -8,7 +8,6 @@
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\NodeTraverser;
use Rector\Core\NodeAnalyzer\ParamAnalyzer;
use Rector\Core\NodeManipulator\ClassMethodManipulator;
use Rector\Core\Rector\AbstractRector;
Expand Down Expand Up @@ -59,40 +58,50 @@ class OrphanClass
*/
public function getNodeTypes(): array
{
return [ClassMethod::class];
return [Class_::class];
}

/**
* @param ClassMethod $node
* @param Class_ $node
*/
public function refactor(Node $node): ?int
public function refactor(Node $node): ?Class_
{
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}
$hasChanged = false;

if ($node->stmts !== null && $node->stmts !== []) {
return null;
}
foreach ($node->stmts as $key => $stmt) {
if (! $stmt instanceof ClassMethod) {
continue;
}

if ($node->isAbstract()) {
return null;
}
if ($stmt->stmts !== null && $stmt->stmts !== []) {
continue;
}

if ($node->isFinal() && ! $classLike->isFinal()) {
return null;
}
if ($stmt->isAbstract()) {
continue;
}

if ($stmt->isFinal() && ! $node->isFinal()) {
continue;
}

if ($this->shouldSkipNonFinalNonPrivateClassMethod($node, $stmt)) {
continue;
}

if ($this->shouldSkipClassMethod($node, $stmt)) {
continue;
}

if ($this->shouldSkipNonFinalNonPrivateClassMethod($classLike, $node)) {
return null;
unset($node->stmts[$key]);
$hasChanged = true;
}

if ($this->shouldSkipClassMethod($classLike, $node)) {
return null;
if ($hasChanged) {
return $node;
}

return NodeTraverser::REMOVE_NODE;
return null;
}

private function shouldSkipNonFinalNonPrivateClassMethod(Class_ $class, ClassMethod $classMethod): bool
Expand Down
Expand Up @@ -6,8 +6,6 @@

use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Enum\ObjectReference;
use Rector\Core\Rector\AbstractRector;
Expand Down Expand Up @@ -55,40 +53,42 @@ public function callOnMe()
*/
public function getNodeTypes(): array
{
return [ClassConstFetch::class];
return [Class_::class];
}

/**
* @param ClassConstFetch $node
* @param Class_ $node
*/
public function refactor(Node $node): ?ClassConstFetch
public function refactor(Node $node): ?Class_
{
if (! $node->class instanceof Name) {
if (! $node->isFinal()) {
return null;
}

if (! $node->name instanceof Identifier) {
return null;
}
$hasChanged = false;

if ($node->class->toString() !== ObjectReference::STATIC) {
return null;
}
$this->traverseNodesWithCallable($node, function (Node $node) use (&$hasChanged): ?ClassConstFetch {
if (! $node instanceof ClassConstFetch) {
return null;
}

if ($node->name->toString() !== 'class') {
return null;
}
if (! $this->isName($node->class, ObjectReference::STATIC)) {
return null;
}

$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
return null;
}
if (! $this->isName($node->name, 'class')) {
return null;
}

if (! $class->isFinal()) {
return null;
$hasChanged = true;
return $this->nodeFactory->createSelfFetchConstant('class');
});

if ($hasChanged) {
return $node;
}

return $this->nodeFactory->createSelfFetchConstant('class');
return null;
}

public function provideMinPhpVersion(): int
Expand Down

0 comments on commit 8268750

Please sign in to comment.