[DeadCode] Make RemoveDefaultArgumentValueRector skip native fu… (#2145)

[DeadCode] Make RemoveDefaultArgumentValueRector skip native functions
This commit is contained in:
Tomáš Votruba 2019-10-12 15:38:20 +02:00 committed by GitHub
commit 8e46b7225b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 73 deletions

View File

@ -102,7 +102,7 @@ PHP
*/
public function refactor(Node $node): ?Node
{
if ($node->args === []) {
if ($this->shouldSkip($node)) {
return null;
}
@ -227,13 +227,26 @@ PHP
return $defaultValues;
}
$coreFunctionReflection = $this->functionReflectionResolver->resolveCoreStubFunctionNode($nodeName);
return [];
}
// unable to found
if ($coreFunctionReflection === null) {
return [];
/**
* @param MethodCall|StaticCall|FuncCall $node
*/
private function shouldSkip(Node $node): bool
{
if ($node->args === []) {
return true;
}
return $this->resolveDefaultParamValuesFromFunctionLike($coreFunctionReflection);
if (! $node instanceof FuncCall) {
return false;
}
// skip native functions, hard to analyze without stubs (stubs would make working with IDE non-practical)
/** @var string $functionName */
$functionName = $this->getName($node);
return $this->functionReflectionResolver->isPhpNativeFunction($functionName);
}
}

View File

@ -9,19 +9,3 @@ class SystemFunction
trigger_error('Error message', E_USER_NOTICE);
}
}
?>
-----
<?php
namespace Rector\DeadCode\Tests\Rector\MethodCall\RemoveDefaultArgumentValueRector\Fixture;
class SystemFunction
{
public function run()
{
trigger_error('Error message');
}
}
?>

View File

@ -22,7 +22,7 @@ final class RemoveDefaultArgumentValueRectorTest extends AbstractRectorTestCase
yield [__DIR__ . '/Fixture/skip_previous_order.php.inc'];
yield [__DIR__ . '/Fixture/function.php.inc'];
yield [__DIR__ . '/Fixture/user_vendor_function.php.inc'];
yield [__DIR__ . '/Fixture/system_function.php.inc'];
yield [__DIR__ . '/Fixture/skip_system_function.php.inc'];
}
protected function getRectorClass(): string

View File

@ -25,3 +25,6 @@ services:
PHPStan\Analyser\ScopeFactory:
factory: ['@Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory', 'createScopeFactory']
PHPStan\Reflection\SignatureMap\SignatureMapProvider:
factory: ['@Rector\NodeTypeResolver\DependencyInjection\PHPStanServicesFactory', 'createSignatureMapProvider']

View File

@ -8,6 +8,7 @@ use PHPStan\Analyser\ScopeFactory;
use PHPStan\Analyser\TypeSpecifier;
use PHPStan\Broker\Broker;
use PHPStan\DependencyInjection\ContainerFactory;
use PHPStan\Reflection\SignatureMap\SignatureMapProvider;
final class PHPStanServicesFactory
{
@ -47,6 +48,11 @@ final class PHPStanServicesFactory
return $this->container->getByType(TypeSpecifier::class);
}
public function createSignatureMapProvider(): SignatureMapProvider
{
return $this->container->getByType(SignatureMapProvider::class);
}
public function createScopeFactory(): ScopeFactory
{
return $this->container->getByType(ScopeFactory::class);

View File

@ -2,65 +2,22 @@
namespace Rector\Reflection;
use PhpParser\Node;
use PhpParser\Node\Stmt\Function_;
use Rector\Exception\ShouldNotHappenException;
use Rector\PhpParser\Node\BetterNodeFinder;
use Rector\PhpParser\Parser\Parser;
use PHPStan\Reflection\SignatureMap\SignatureMapProvider;
final class FunctionReflectionResolver
{
/**
* @var string[]
* @var SignatureMapProvider
*/
private const POSSIBLE_CORE_STUB_LOCATIONS = [
__DIR__ . '/../../../../jetbrains/phpstorm-stubs/Core/Core.php',
__DIR__ . '/../../vendor/jetbrains/phpstorm-stubs/Core/Core.php',
];
private $signatureMapProvider;
/**
* @var Parser
*/
private $parser;
/**
* @var BetterNodeFinder
*/
private $betterNodeFinder;
public function __construct(Parser $parser, BetterNodeFinder $betterNodeFinder)
public function __construct(SignatureMapProvider $signatureMapProvider)
{
$this->parser = $parser;
$this->betterNodeFinder = $betterNodeFinder;
$this->signatureMapProvider = $signatureMapProvider;
}
public function resolveCoreStubFunctionNode(string $nodeName): ?Function_
public function isPhpNativeFunction(string $functionName): bool
{
$stubFileLocation = $this->resolveCoreStubLocation();
$nodes = $this->parser->parseFile($stubFileLocation);
/** @var Function_|null $function */
$function = $this->betterNodeFinder->findFirst($nodes, function (Node $node) use ($nodeName): bool {
if (! $node instanceof Function_) {
return false;
}
return (string) $node->name === $nodeName;
});
return $function;
}
private function resolveCoreStubLocation(): string
{
foreach (self::POSSIBLE_CORE_STUB_LOCATIONS as $possibleCoreStubLocation) {
if (file_exists($possibleCoreStubLocation)) {
/** @var string $possibleCoreStubLocation */
return $possibleCoreStubLocation;
}
}
throw new ShouldNotHappenException();
return $this->signatureMapProvider->hasFunctionSignature($functionName);
}
}