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
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

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;
Expand All @@ -24,9 +23,15 @@
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
{
Expand Down Expand Up @@ -92,7 +97,11 @@ public function refactor(Node $node): ?Node
$name = RectorStrings::camelCaseToUnderscore($combined);

$symfonyRoutePhpDocTagValueNode = $this->createSymfonyRoutePhpDocTagValueNode($path, $name);
$this->addSymfonyRouteShortTagNodeWithUse($symfonyRoutePhpDocTagValueNode, $classMethod);

$this->implicitToExplicitRoutingAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
$classMethod,
$symfonyRoutePhpDocTagValueNode
);
}

return $node;
Expand All @@ -102,20 +111,4 @@ private function createSymfonyRoutePhpDocTagValueNode(string $path, string $name
{
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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Rector\CakePHPToSymfony\Tests\Rector\Class_\CakePHPImplicitRouteToExplicitRouteAnnotationRector\Fixture;

class SkipPrivateController extends \AppController
{
private function index()
{
}
}
10 changes: 10 additions & 0 deletions packages/FrameworkMigration/config/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
parameters:
project_directory: null

services:
_defaults:
public: true
autowire: true

Rector\FrameworkMigration\:
resource: '../src'
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,60 @@

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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
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;
Expand All @@ -35,11 +35,6 @@
*/
final class RouterListToControllerAnnotationsRector extends AbstractRector
{
/**
* @var string
*/
private const HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE = 'has_fresh_route_annotation';

/**
* @var ParsedNodesByType
*/
Expand All @@ -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
Expand Down Expand Up @@ -163,7 +165,10 @@ public function refactor(Node $node): ?Node

$symfonyRoutePhpDocTagValueNode = $this->createSymfonyRoutePhpDocTagValueNode($routeInfo);

$this->addSymfonyRouteShortTagNodeWithUse($symfonyRoutePhpDocTagValueNode, $classMethod);
$this->implicitToExplicitRoutingAnnotationDecorator->decorateClassMethodWithRouteAnnotation(
$classMethod,
$symfonyRoutePhpDocTagValueNode
);
}

// complete all other non-explicit methods, from "<presenter>/<action>"
Expand Down Expand Up @@ -240,21 +245,6 @@ private function createSymfonyRoutePhpDocTagValueNode(RouteInfo $routeInfo): Sym
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');
Expand All @@ -268,14 +258,14 @@ private function completeImplicitRoutes(): void
$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);
Expand Down Expand Up @@ -319,7 +309,7 @@ private function shouldSkipClassStmt(Node $node): bool
return true;
}

if ($node->getAttribute(self::HAS_FRESH_ROUTE_ANNOTATION_ATTRIBUTE)) {
if ($node->getAttribute(ImplicitToExplicitRoutingAnnotationDecorator::HAS_ROUTE_ANNOTATION)) {
return true;
}

Expand Down
5 changes: 0 additions & 5 deletions src/Rector/AbstractRector/NodeCommandersTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ protected function addUseType(ObjectType $objectType, Node $positionNode): void
$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);
Expand Down