mirror of
https://github.com/rectorphp/rector.git
synced 2025-01-17 21:38:22 +01:00
Merge pull request #2792 from rectorphp/cake-route
decopule ImplicitToExplicitRoutingAnnotationDecorator
This commit is contained in:
commit
29c8de530b
@ -6,11 +6,10 @@ namespace Rector\CakePHPToSymfony\Rector\Class_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Symfony\SymfonyRouteTagValueNode;
|
||||
use Rector\CakePHPToSymfony\Rector\AbstractCakePHPRector;
|
||||
use Rector\FrameworkMigration\Symfony\ImplicitToExplicitRoutingAnnotationDecorator;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
use Rector\Util\RectorStrings;
|
||||
@ -24,9 +23,15 @@ use Rector\Util\RectorStrings;
|
||||
final class CakePHPImplicitRouteToExplicitRouteAnnotationRector extends AbstractCakePHPRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @var ImplicitToExplicitRoutingAnnotationDecorator
|
||||
*/
|
||||
private const HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE = 'has_fresh_route_annotation';
|
||||
private $implicitToExplicitRoutingAnnotationDecorator;
|
||||
|
||||
public function __construct(
|
||||
ImplicitToExplicitRoutingAnnotationDecorator $implicitToExplicitRoutingAnnotationDecorator
|
||||
) {
|
||||
$this->implicitToExplicitRoutingAnnotationDecorator = $implicitToExplicitRoutingAnnotationDecorator;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
@ -92,7 +97,11 @@ PHP
|
||||
$name = RectorStrings::camelCaseToUnderscore($combined);
|
||||
|
||||
$symfonyRoutePhpDocTagValueNode = $this->createSymfonyRoutePhpDocTagValueNode($path, $name);
|
||||
$this->addSymfonyRouteShortTagNodeWithUse($symfonyRoutePhpDocTagValueNode, $classMethod);
|
||||
|
||||
$this->implicitToExplicitRoutingAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
|
||||
$classMethod,
|
||||
$symfonyRoutePhpDocTagValueNode
|
||||
);
|
||||
}
|
||||
|
||||
return $node;
|
||||
@ -102,20 +111,4 @@ PHP
|
||||
{
|
||||
return new SymfonyRouteTagValueNode($path, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo reuse from RouterListToControllerAnnotationsRector
|
||||
*/
|
||||
private function addSymfonyRouteShortTagNodeWithUse(
|
||||
SymfonyRouteTagValueNode $symfonyRouteTagValueNode,
|
||||
ClassMethod $classMethod
|
||||
): void {
|
||||
// @todo use empty phpdoc info
|
||||
$this->docBlockManipulator->addTagValueNodeWithShortName($classMethod, $symfonyRouteTagValueNode);
|
||||
|
||||
$symfonyRouteUseObjectType = new FullyQualifiedObjectType(SymfonyRouteTagValueNode::CLASS_NAME);
|
||||
$this->addUseType($symfonyRouteUseObjectType, $classMethod);
|
||||
|
||||
$classMethod->setAttribute(self::HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE, true);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Rector\CakePHPToSymfony\Tests\Rector\Class_\CakePHPImplicitRouteToExplicitRouteAnnotationRector\Fixture;
|
||||
|
||||
class SkipPrivateController extends \AppController
|
||||
{
|
||||
private function index()
|
||||
{
|
||||
}
|
||||
}
|
10
packages/FrameworkMigration/config/config.yaml
Normal file
10
packages/FrameworkMigration/config/config.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
parameters:
|
||||
project_directory: null
|
||||
|
||||
services:
|
||||
_defaults:
|
||||
public: true
|
||||
autowire: true
|
||||
|
||||
Rector\FrameworkMigration\:
|
||||
resource: '../src'
|
@ -4,7 +4,60 @@ declare(strict_types=1);
|
||||
|
||||
namespace Rector\FrameworkMigration\Symfony;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Symfony\SymfonyRouteTagValueNode;
|
||||
use Rector\CodingStyle\Application\UseAddingCommander;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
|
||||
use Rector\PHPStan\Type\AliasedObjectType;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
|
||||
final class ImplicitToExplicitRoutingAnnotationDecorator
|
||||
{
|
||||
// ...
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const HAS_ROUTE_ANNOTATION = 'has_route_annotation';
|
||||
|
||||
/**
|
||||
* @var DocBlockManipulator
|
||||
*/
|
||||
private $docBlockManipulator;
|
||||
|
||||
/**
|
||||
* @var UseAddingCommander
|
||||
*/
|
||||
private $useAddingCommander;
|
||||
|
||||
public function __construct(DocBlockManipulator $docBlockManipulator, UseAddingCommander $useAddingCommander)
|
||||
{
|
||||
$this->docBlockManipulator = $docBlockManipulator;
|
||||
$this->useAddingCommander = $useAddingCommander;
|
||||
}
|
||||
|
||||
public function decorateClassMethodWithRouteAnnotation(
|
||||
ClassMethod $classMethod,
|
||||
SymfonyRouteTagValueNode $symfonyRouteTagValueNode
|
||||
): void {
|
||||
$this->docBlockManipulator->addTagValueNodeWithShortName($classMethod, $symfonyRouteTagValueNode);
|
||||
|
||||
$symfonyRouteUseObjectType = new FullyQualifiedObjectType(SymfonyRouteTagValueNode::CLASS_NAME);
|
||||
$this->addUseType($symfonyRouteUseObjectType, $classMethod);
|
||||
|
||||
// remove
|
||||
$this->useAddingCommander->removeShortUse($classMethod, 'Route');
|
||||
|
||||
$classMethod->setAttribute(self::HAS_ROUTE_ANNOTATION, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FullyQualifiedObjectType|AliasedObjectType $objectType
|
||||
*/
|
||||
private function addUseType(ObjectType $objectType, Node $positionNode): void
|
||||
{
|
||||
assert($objectType instanceof FullyQualifiedObjectType || $objectType instanceof AliasedObjectType);
|
||||
|
||||
$this->useAddingCommander->addUseImport($positionNode, $objectType);
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,11 @@ use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\BetterPhpDocParser\PhpDocNode\Symfony\SymfonyRouteTagValueNode;
|
||||
use Rector\FrameworkMigration\Symfony\ImplicitToExplicitRoutingAnnotationDecorator;
|
||||
use Rector\NetteToSymfony\Route\RouteInfoFactory;
|
||||
use Rector\NetteToSymfony\ValueObject\RouteInfo;
|
||||
use Rector\NodeContainer\ParsedNodesByType;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
use Rector\Rector\AbstractRector;
|
||||
use Rector\RectorDefinition\CodeSample;
|
||||
use Rector\RectorDefinition\RectorDefinition;
|
||||
@ -35,11 +35,6 @@ use ReflectionMethod;
|
||||
*/
|
||||
final class RouterListToControllerAnnotationsRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private const HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE = 'has_fresh_route_annotation';
|
||||
|
||||
/**
|
||||
* @var ParsedNodesByType
|
||||
*/
|
||||
@ -55,14 +50,21 @@ final class RouterListToControllerAnnotationsRector extends AbstractRector
|
||||
*/
|
||||
private $returnTypeInferer;
|
||||
|
||||
/**
|
||||
* @var ImplicitToExplicitRoutingAnnotationDecorator
|
||||
*/
|
||||
private $implicitToExplicitRoutingAnnotationDecorator;
|
||||
|
||||
public function __construct(
|
||||
ParsedNodesByType $parsedNodesByType,
|
||||
RouteInfoFactory $routeInfoFactory,
|
||||
ReturnTypeInferer $returnTypeInferer
|
||||
ReturnTypeInferer $returnTypeInferer,
|
||||
ImplicitToExplicitRoutingAnnotationDecorator $implicitToExplicitRoutingAnnotationDecorator
|
||||
) {
|
||||
$this->parsedNodesByType = $parsedNodesByType;
|
||||
$this->routeInfoFactory = $routeInfoFactory;
|
||||
$this->returnTypeInferer = $returnTypeInferer;
|
||||
$this->implicitToExplicitRoutingAnnotationDecorator = $implicitToExplicitRoutingAnnotationDecorator;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
@ -163,7 +165,10 @@ PHP
|
||||
|
||||
$symfonyRoutePhpDocTagValueNode = $this->createSymfonyRoutePhpDocTagValueNode($routeInfo);
|
||||
|
||||
$this->addSymfonyRouteShortTagNodeWithUse($symfonyRoutePhpDocTagValueNode, $classMethod);
|
||||
$this->implicitToExplicitRoutingAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
|
||||
$classMethod,
|
||||
$symfonyRoutePhpDocTagValueNode
|
||||
);
|
||||
}
|
||||
|
||||
// complete all other non-explicit methods, from "<presenter>/<action>"
|
||||
@ -240,21 +245,6 @@ PHP
|
||||
return new SymfonyRouteTagValueNode($routeInfo->getPath(), null, $routeInfo->getHttpMethods());
|
||||
}
|
||||
|
||||
private function addSymfonyRouteShortTagNodeWithUse(
|
||||
SymfonyRouteTagValueNode $symfonyRouteTagValueNode,
|
||||
ClassMethod $classMethod
|
||||
): void {
|
||||
$this->docBlockManipulator->addTagValueNodeWithShortName($classMethod, $symfonyRouteTagValueNode);
|
||||
|
||||
$symfonyRouteUseObjectType = new FullyQualifiedObjectType(SymfonyRouteTagValueNode::CLASS_NAME);
|
||||
$this->addUseType($symfonyRouteUseObjectType, $classMethod);
|
||||
|
||||
// remove
|
||||
$this->removeShortUse('Route', $classMethod);
|
||||
|
||||
$classMethod->setAttribute(self::HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE, true);
|
||||
}
|
||||
|
||||
private function completeImplicitRoutes(): void
|
||||
{
|
||||
$presenterClasses = $this->classLikeParsedNodesFinder->findClassesBySuffix('Presenter');
|
||||
@ -268,14 +258,14 @@ PHP
|
||||
$path = $this->resolvePathFromClassAndMethodNodes($presenterClass, $classMethod);
|
||||
$symfonyRoutePhpDocTagValueNode = new SymfonyRouteTagValueNode($path);
|
||||
|
||||
$this->addSymfonyRouteShortTagNodeWithUse($symfonyRoutePhpDocTagValueNode, $classMethod);
|
||||
$this->implicitToExplicitRoutingAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
|
||||
$classMethod,
|
||||
$symfonyRoutePhpDocTagValueNode
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo allow extension with custom resolvers
|
||||
*/
|
||||
private function isRouteStaticCallMatch(StaticCall $staticCall): bool
|
||||
{
|
||||
$className = $this->getName($staticCall->class);
|
||||
@ -319,7 +309,7 @@ PHP
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($node->getAttribute(self::HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE)) {
|
||||
if ($node->getAttribute(ImplicitToExplicitRoutingAnnotationDecorator::HAS_ROUTE_ANNOTATION)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -87,11 +87,6 @@ trait NodeCommandersTrait
|
||||
$this->useAddingCommander->addUseImport($positionNode, $objectType);
|
||||
}
|
||||
|
||||
protected function removeShortUse(string $shortUse, Node $positionNode): void
|
||||
{
|
||||
$this->useAddingCommander->removeShortUse($positionNode, $shortUse);
|
||||
}
|
||||
|
||||
protected function addNodeAfterNode(Node $newNode, Node $positionNode): void
|
||||
{
|
||||
$this->nodeAddingCommander->addNodeAfterNode($newNode, $positionNode);
|
||||
|
Loading…
x
Reference in New Issue
Block a user