mirror of
https://github.com/rectorphp/rector.git
synced 2025-02-24 11:44:14 +01:00
[DeprecationExtractor] provide more context to reported deprecations
This commit is contained in:
parent
1d5a01fcb0
commit
56840b0b51
@ -7,6 +7,7 @@ use Rector\DeprecationExtractor\DeprecationExtractor;
|
||||
use Rector\DeprecationExtractor\Rector\RectorGuesser;
|
||||
use Rector\DeprecationExtractor\RectorGuess\RectorGuess;
|
||||
use Rector\Naming\CommandNaming;
|
||||
use Rector\Node\Attribute;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
@ -94,12 +95,16 @@ final class ExtractDeprecationsCommand extends Command
|
||||
$this->symfonyStyle->warning($guessedRector->getGuessedRectorClass());
|
||||
}
|
||||
|
||||
$this->symfonyStyle->writeln(' ' . $guessedRector->getMessage());
|
||||
$this->symfonyStyle->newLine();
|
||||
|
||||
$this->symfonyStyle->writeln($guessedRector->getMessage());
|
||||
// @todo: add metadata like related class, method etc. - or maybe get from NODE like
|
||||
// $node->getAttribute(Attributes::CLASS_NODE)
|
||||
// $node->getAttribute(Attributes::METHOD_NODE)
|
||||
$node = $guessedRector->getNode();
|
||||
|
||||
if ($guessedRector->getGuessedRectorClass() !== 'REMOVAL') {
|
||||
$this->symfonyStyle->writeln(' Namespace: ' . $node->getAttribute(Attribute::NAMESPACE));
|
||||
$this->symfonyStyle->writeln(' Class: ' . $node->getAttribute(Attribute::CLASS_NAME));
|
||||
$this->symfonyStyle->writeln(' Scope: ' . $node->getAttribute(Attribute::SCOPE));
|
||||
}
|
||||
|
||||
$this->symfonyStyle->newLine(2);
|
||||
}
|
||||
|
@ -8,10 +8,10 @@ use PhpParser\Node;
|
||||
use Rector\DeprecationExtractor\Deprecation\Deprecation;
|
||||
use Rector\DeprecationExtractor\RectorGuess\RectorGuess;
|
||||
use Rector\DeprecationExtractor\RectorGuess\RectorGuessFactory;
|
||||
use Rector\DeprecationExtractor\Regex\ClassAndMethodMatcher;
|
||||
use Rector\Exception\NotImplementedException;
|
||||
use Rector\Node\Attribute;
|
||||
use Rector\NodeValueResolver\Message\ClassPrepender;
|
||||
use Rector\NodeValueResolver\NodeValueResolver;
|
||||
|
||||
/**
|
||||
* This class tries to guess, which Rector could be used to create refactoring
|
||||
@ -29,16 +29,21 @@ final class RectorGuesser
|
||||
*/
|
||||
private $unsupportedDeprecationFilter;
|
||||
|
||||
/**
|
||||
* @var ClassAndMethodMatcher
|
||||
*/
|
||||
private $classAndMethodMatcher;
|
||||
|
||||
public function __construct(
|
||||
// NodeValueResolver $nodeValueResolver,
|
||||
ClassPrepender $classPrepender,
|
||||
RectorGuessFactory $rectorGuessFactory,
|
||||
UnsupportedDeprecationFilter $unsupportedDeprecationFilter
|
||||
UnsupportedDeprecationFilter $unsupportedDeprecationFilter,
|
||||
ClassAndMethodMatcher $classAndMethodMatcher
|
||||
) {
|
||||
// $this->nodeValueResolver = $nodeValueResolver;
|
||||
$this->classPrepender = $classPrepender;
|
||||
$this->rectorGuessFactory = $rectorGuessFactory;
|
||||
$this->unsupportedDeprecationFilter = $unsupportedDeprecationFilter;
|
||||
$this->classAndMethodMatcher = $classAndMethodMatcher;
|
||||
}
|
||||
|
||||
public function guessForDeprecation(Deprecation $deprecation): ?RectorGuess
|
||||
@ -69,7 +74,6 @@ final class RectorGuesser
|
||||
if (count($result) === 2) {
|
||||
if (Strings::contains($message, 'class is deprecated')) {
|
||||
return $this->rectorGuessFactory->createClassReplacer(
|
||||
'...',
|
||||
$message,
|
||||
$deprecation->getNode()
|
||||
);
|
||||
@ -99,55 +103,55 @@ final class RectorGuesser
|
||||
return $guessedRectors;
|
||||
}
|
||||
|
||||
// private function guess(string $message, Node $node): ?RectorGuess
|
||||
// {
|
||||
// // @todo: per node resolver...
|
||||
// if ($node instanceof Class_) {
|
||||
// return $this->rectorGuessFactory->createClassReplacer(
|
||||
// $node->namespacedName->toString(),
|
||||
// $message,
|
||||
// $node
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// if ($node instanceof Node\Stmt\ClassMethod) {
|
||||
// $classWithMethod = $this->classAndMethodMatcher->matchClassWithMethod($message);
|
||||
// $localMethod = $this->classAndMethodMatcher->matchLocalMethod($message);
|
||||
//
|
||||
// $className = $node->getAttribute(Attribute::CLASS_NODE)->namespacedName->toString();
|
||||
// $methodName = (string) $node->name . '()';
|
||||
// $fqnMethodName = $className . '::' . $methodName;
|
||||
//
|
||||
// if ($classWithMethod === '' && $localMethod === '') {
|
||||
// return $this->rectorGuessFactory->createRemoval($message, $node);
|
||||
// }
|
||||
//
|
||||
// if ($localMethod) {
|
||||
// return $this->rectorGuessFactory->createRemoval(
|
||||
// $fqnMethodName . ' => ' . $className . '::' . $localMethod . '()' . $message,
|
||||
// $node
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// $namespacedClassWithMethod = $this->classAndMethodMatcher->matchNamespacedClassWithMethod($message);
|
||||
//
|
||||
// /** @var string[] $useStatements */
|
||||
// $useStatements = $node->getAttribute(Attribute::USE_STATEMENTS);
|
||||
// $fqnClassWithMethod = $this->completeNamespace($useStatements, $namespacedClassWithMethod);
|
||||
//
|
||||
// return $this->rectorGuessFactory->createRemoval(
|
||||
// $fqnMethodName . '=> ' . $fqnClassWithMethod,
|
||||
// $node
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// throw new NotImplementedException(sprintf(
|
||||
// '%s() was unable to create a Deprecation based on "%s" string and "%s" Node. Create a new method there.',
|
||||
// __METHOD__,
|
||||
// $message,
|
||||
// get_class($node)
|
||||
// ));
|
||||
// }
|
||||
private function guess(string $message, Node $node): ?RectorGuess
|
||||
{
|
||||
// @todo: per node resolver...
|
||||
if ($node instanceof Class_) {
|
||||
return $this->rectorGuessFactory->createClassReplacer(
|
||||
$node->namespacedName->toString(),
|
||||
$message,
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
if ($node instanceof Node\Stmt\ClassMethod) {
|
||||
$classWithMethod = $this->classAndMethodMatcher->matchClassWithMethod($message);
|
||||
$localMethod = $this->classAndMethodMatcher->matchLocalMethod($message);
|
||||
|
||||
$className = $node->getAttribute(Attribute::CLASS_NODE)->namespacedName->toString();
|
||||
$methodName = (string) $node->name . '()';
|
||||
$fqnMethodName = $className . '::' . $methodName;
|
||||
|
||||
if ($classWithMethod === '' && $localMethod === '') {
|
||||
return $this->rectorGuessFactory->createRemoval($message, $node);
|
||||
}
|
||||
|
||||
if ($localMethod) {
|
||||
return $this->rectorGuessFactory->createRemoval(
|
||||
$fqnMethodName . ' => ' . $className . '::' . $localMethod . '()' . $message,
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
$namespacedClassWithMethod = $this->classAndMethodMatcher->matchNamespacedClassWithMethod($message);
|
||||
|
||||
/** @var string[] $useStatements */
|
||||
$useStatements = $node->getAttribute(Attribute::USE_STATEMENTS);
|
||||
$fqnClassWithMethod = $this->completeNamespace($useStatements, $namespacedClassWithMethod);
|
||||
|
||||
return $this->rectorGuessFactory->createRemoval(
|
||||
$fqnMethodName . '=> ' . $fqnClassWithMethod,
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
throw new NotImplementedException(sprintf(
|
||||
'%s() was unable to create a Deprecation based on "%s" string and "%s" Node. Create a new method there.',
|
||||
__METHOD__,
|
||||
$message,
|
||||
get_class($node)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $useStatements
|
||||
|
@ -11,11 +11,11 @@ final class UnsupportedDeprecationFilter
|
||||
* @var string[]
|
||||
*/
|
||||
private $yamlDeprecationMessages = [
|
||||
'Autowiring-types are deprecated since',
|
||||
'Autowiring-types are deprecated',
|
||||
'The "=" suffix that used to disable strict references',
|
||||
'The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported',
|
||||
'The "strict" attribute used when referencing the "" service is deprecated since version 3.3 and will be removed in 4.0.',
|
||||
'Service names that start with an underscore are deprecated since Symfony 3.3 and will be reserved in 4.0',
|
||||
'The "strict" attribute used when referencing the "" service is deprecated',
|
||||
'Service names that start with an underscore are deprecated',
|
||||
'configuration key',
|
||||
];
|
||||
|
||||
|
@ -35,7 +35,7 @@ final class RectorGuess
|
||||
public function __construct(
|
||||
string $guessedRectorClass,
|
||||
Node $node,
|
||||
string $message = ''
|
||||
string $message
|
||||
) {
|
||||
$this->guessedRectorClass = $guessedRectorClass;
|
||||
$this->node = $node;
|
||||
|
@ -9,48 +9,28 @@ use Rector\Rector\Dynamic\MethodNameReplacerRector;
|
||||
|
||||
final class RectorGuessFactory
|
||||
{
|
||||
public function createRemoval(string $message, Node $node): RectorGuess
|
||||
public function createClassReplacer(string $message, Node $node): RectorGuess
|
||||
{
|
||||
return new RectorGuess(
|
||||
RectorGuess::TYPE_REMOVAL,
|
||||
$node,
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
public function createClassReplacer(string $className, string $message, Node $node): RectorGuess
|
||||
{
|
||||
return new RectorGuess(
|
||||
ClassReplacerRector::class,
|
||||
$node,
|
||||
$className . ' - ' . $message
|
||||
);
|
||||
return new RectorGuess(ClassReplacerRector::class, $node, $message);
|
||||
}
|
||||
|
||||
public function createMethodNameReplacerGuess(string $message, Node $node): RectorGuess
|
||||
{
|
||||
return new RectorGuess(
|
||||
MethodNameReplacerRector::class,
|
||||
$node,
|
||||
$message
|
||||
);
|
||||
return new RectorGuess(MethodNameReplacerRector::class, $node, $message);
|
||||
}
|
||||
|
||||
public function createNewArgument(string $message, Node $node): RectorGuess
|
||||
{
|
||||
return new RectorGuess(
|
||||
MethodArgumentChangerRector::class,
|
||||
$node,
|
||||
$message
|
||||
);
|
||||
return new RectorGuess(MethodArgumentChangerRector::class, $node, $message);
|
||||
}
|
||||
|
||||
public function createRemoval(string $message, Node $node): RectorGuess
|
||||
{
|
||||
return new RectorGuess(RectorGuess::TYPE_REMOVAL, $node, $message);
|
||||
}
|
||||
|
||||
public function createUnsupported(string $message, Node $node): RectorGuess
|
||||
{
|
||||
return new RectorGuess(
|
||||
RectorGuess::TYPE_UNSUPPORTED,
|
||||
$node,
|
||||
$message
|
||||
);
|
||||
return new RectorGuess(RectorGuess::TYPE_UNSUPPORTED, $node, $message);
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +30,6 @@ final class DeprecationCollectorTest extends AbstractContainerAwareTestCase
|
||||
__DIR__ . '/../../../../vendor/symfony/dependency-injection',
|
||||
]);
|
||||
|
||||
$deprecations = $this->deprecationCollector->getDeprecationTriggerErrors()
|
||||
+ $this->deprecationCollector->getDeprecationAnnotations();
|
||||
|
||||
$this->assertGreaterThanOrEqual(35, $deprecations);
|
||||
$this->assertGreaterThanOrEqual(35, $this->deprecationCollector->getDeprecations());
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace Rector\DeprecationExtractor\Tests;
|
||||
|
||||
use PhpParser\Node\Arg;
|
||||
use Rector\DeprecationExtractor\Deprecation\DeprecationCollector;
|
||||
use Rector\DeprecationExtractor\DeprecationExtractor;
|
||||
use Rector\Tests\AbstractContainerAwareTestCase;
|
||||
@ -25,16 +24,7 @@ final class DeprecationExtractorTest extends AbstractContainerAwareTestCase
|
||||
|
||||
public function testDeprectaionMessages(): void
|
||||
{
|
||||
$deprecationMessages = $this->deprecationCollector->getDeprecationAnnotations();
|
||||
$this->assertCount(0, $deprecationMessages);
|
||||
}
|
||||
|
||||
public function testDeprecationNodes(): void
|
||||
{
|
||||
$deprecationArgNodes = $this->deprecationCollector->getDeprecationTriggerErrors();
|
||||
$this->assertCount(2, $deprecationArgNodes);
|
||||
|
||||
$deprecationArgNode = $deprecationArgNodes[0];
|
||||
$this->assertInstanceOf(Arg::class, $deprecationArgNode);
|
||||
$deprecationMessages = $this->deprecationCollector->getDeprecations();
|
||||
$this->assertCount(2, $deprecationMessages);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user