Skip to content
Merged
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
1 change: 1 addition & 0 deletions config/set/dead-code/dead-code.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ services:
Rector\DeadCode\Rector\ClassConst\RemoveUnusedClassConstantRector: null
Rector\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector: null
Rector\DeadCode\Rector\FunctionLike\RemoveDuplicatedIfReturnRector: null
Rector\DeadCode\Rector\Function_\RemoveUnusedFunctionRector: null
23 changes: 22 additions & 1 deletion docs/AllRectorsOverview.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# All 467 Rectors Overview
# All 468 Rectors Overview

- [Projects](#projects)
- [General](#general)
Expand Down Expand Up @@ -3062,6 +3062,27 @@ Remove unused key in foreach

<br>

### `RemoveUnusedFunctionRector`

- class: [`Rector\DeadCode\Rector\Function_\RemoveUnusedFunctionRector`](/../master/rules/dead-code/src/Rector/Function_/RemoveUnusedFunctionRector.php)
- [test fixtures](/../master/rules/dead-code/tests/Rector/Function_/RemoveUnusedFunctionRector/Fixture)

Remove unused function

```diff
-function removeMe()
-{
-}
-
function useMe()
{
}

useMe();
```

<br>

### `RemoveUnusedParameterRector`

- class: [`Rector\DeadCode\Rector\ClassMethod\RemoveUnusedParameterRector`](/../master/rules/dead-code/src/Rector/ClassMethod/RemoveUnusedParameterRector.php)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
Expand Down Expand Up @@ -36,6 +37,11 @@ final class ParsedFunctionLikeNodeCollector
*/
private $functionsByName = [];

/**
* @var FuncCall[][]
*/
private $funcCallsByName = [];

/**
* @var MethodCall[][][]|StaticCall[][][]
*/
Expand Down Expand Up @@ -100,12 +106,13 @@ public function collect(Node $node): void

if ($node instanceof Function_) {
$functionName = $this->nodeNameResolver->getName($node);
if ($functionName === null) {
return;
}

$this->functionsByName[$functionName] = $node;
}

if ($node instanceof FuncCall) {
$functionName = $this->nodeNameResolver->getName($node);
$this->funcCallsByName[$functionName][] = $node;
}
}

public function findFunction(string $name): ?Function_
Expand Down Expand Up @@ -145,6 +152,11 @@ public function findMethod(string $className, string $methodName): ?ClassMethod
return null;
}

public function isFunctionUsed(string $functionName): bool
{
return isset($this->funcCallsByName[$functionName]);
}

private function addMethod(ClassMethod $classMethod): void
{
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public function resolve(Node $node): ?string
}

$functionName = $node->name;

if (! $functionName instanceof Name) {
return (string) $functionName;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Rector\NodeNameResolver\NodeNameResolver;

use PhpParser\Node;
use PhpParser\Node\Stmt\Function_;
use Rector\NodeNameResolver\Contract\NodeNameResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;

final class FunctionNameResolver implements NodeNameResolverInterface
{
public function getNode(): string
{
return Function_::class;
}

/**
* @param Function_ $node
*/
public function resolve(Node $node): ?string
{
$bareName = (string) $node->name;

$namespaceName = $node->getAttribute(AttributeKey::NAMESPACE_NAME);

if ($namespaceName) {
return $namespaceName . '\\' . $bareName;
}

return $bareName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

declare(strict_types=1);

namespace Rector\DeadCode\Rector\Function_;

use PhpParser\Node;
use PhpParser\Node\Stmt\Function_;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeCollector\NodeCollector\ParsedFunctionLikeNodeCollector;

/**
* @see \Rector\DeadCode\Tests\Rector\Function_\RemoveUnusedFunctionRector\RemoveUnusedFunctionRectorTest
*/
final class RemoveUnusedFunctionRector extends AbstractRector
{
/**
* @var ParsedFunctionLikeNodeCollector
*/
private $parsedFunctionLikeNodeCollector;

public function __construct(ParsedFunctionLikeNodeCollector $parsedFunctionLikeNodeCollector)
{
$this->parsedFunctionLikeNodeCollector = $parsedFunctionLikeNodeCollector;
}

public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Remove unused function', [
new CodeSample(
<<<'PHP'
function removeMe()
{
}

function useMe()
{
}

useMe();
PHP
,
<<<'PHP'
function useMe()
{
}

useMe();
PHP

),
]);
}

/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [Function_::class];
}

/**
* @param Function_ $node
*/
public function refactor(Node $node): ?Node
{
/** @var string $functionName */
$functionName = $this->getName($node);

if ($this->parsedFunctionLikeNodeCollector->isFunctionUsed($functionName)) {
return null;
}

$this->removeNode($node);

return $node;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private function shouldSkip(Node $node): bool
return true;
}

$functionName = $this->getName($node->name);
$functionName = $this->getName($node);
if ($functionName === null) {
return false;
}
Expand All @@ -137,8 +137,7 @@ private function shouldSkip(Node $node): bool
*/
private function resolveDefaultValuesFromCall(Node $node): array
{
/** @var string|null $nodeName */
$nodeName = $this->getName($node->name);
$nodeName = $this->resolveNodeName($node);
if ($nodeName === null) {
return [];
}
Expand Down Expand Up @@ -242,4 +241,16 @@ private function resolveDefaultParamValuesFromFunctionLike(FunctionLike $functio

return $defaultValues;
}

/**
* @param StaticCall|FuncCall|MethodCall $node
*/
private function resolveNodeName(Node $node): ?string
{
if ($node instanceof FuncCall) {
return $this->getName($node);
}

return $this->getName($node->name);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Rector\DeadCode\Tests\Rector\Function_\RemoveUnusedFunctionRector\Fixture;

function removeMe()
{
}

function useMe()
{
}

useMe();

?>
-----
<?php

namespace Rector\DeadCode\Tests\Rector\Function_\RemoveUnusedFunctionRector\Fixture;

function useMe()
{
}
useMe();

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

declare(strict_types=1);

namespace Rector\DeadCode\Tests\Rector\Function_\RemoveUnusedFunctionRector;

use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\DeadCode\Rector\Function_\RemoveUnusedFunctionRector;

final class RemoveUnusedFunctionRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $file): void
{
$this->doTestFile($file);
}

public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

protected function getRectorClass(): string
{
return RemoveUnusedFunctionRector::class;
}
}