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 @@ -4,3 +4,4 @@ services:
Rector\NetteKdyby\Rector\Class_\KdybyEventSubscriberToContributteEventSubscriberRector: null
Rector\NetteKdyby\Rector\MethodCall\ReplaceMagicPropertyEventWithEventClassRector: null
Rector\NetteKdyby\Rector\ClassMethod\ReplaceMagicEventPropertySubscriberWithEventClassSubscriberRector: null
Rector\NetteKdyby\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector: null
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,4 @@ parameters:
- '#Cognitive complexity for "Rector\\TypeDeclaration\\PHPStan\\Type\\ObjectTypeSpecifier\:\:matchShortenedObjectType\(\)" is 10, keep it under 9#'
- '#Parameter \#1 \$objectType of method Rector\\Core\\Naming\\PropertyNaming\:\:fqnToVariableName\(\) expects PHPStan\\Type\\ObjectType\|string, PHPStan\\Type\\Type given#'
- '#Parameter \#1 \$type of method PhpParser\\Builder\\FunctionLike\:\:setReturnType\(\) expects PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|string, PhpParser\\Node\\Identifier\|PhpParser\\Node\\Name\|PhpParser\\Node\\NullableType\|PhpParser\\Node\\UnionType given#'
- '#Cognitive complexity for "Rector\\Core\\PhpParser\\Node\\Value\\ValueResolver\:\:getValue\(\)" is \d+, keep it under 9#'
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ private function addConstructorDependencyWithProperty(
string $name,
ObjectType $objectType
): void {
$assign = $this->createSameNameThisAssign($name);
$assign = $this->nodeFactory->createPropertyAssignment($name);
$classMethod->stmts[] = new Expression($assign);

$this->addPropertyToClass($class, $objectType, $name);
Expand Down Expand Up @@ -296,16 +296,6 @@ private function isRegistryGetManagerMethodCall(Assign $assign): bool
return $this->isName($assign->expr->name, self::GET_MANAGER);
}

/**
* Creates: "$this->value = $value;"
*/
private function createSameNameThisAssign(string $name): Assign
{
$propertyFetch = new PropertyFetch(new Variable('this'), $name);

return new Assign($propertyFetch, new Variable($name));
}

private function removeManagerRegistryProperty(Class_ $class, Assign $assign): void
{
$managerRegistryPropertyName = $this->getName($assign->var);
Expand Down
25 changes: 17 additions & 8 deletions rules/nette-kdyby/src/Naming/EventClassNaming.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,28 @@ public function resolveEventFileLocation(MethodCall $methodCall): string
return $fileInfo->getPath() . DIRECTORY_SEPARATOR . 'Event' . DIRECTORY_SEPARATOR . $shortEventClassName . '.php';
}

public function createEventClassNameFromClassAndProperty(string $className, string $methodName): string
{
$shortEventClass = $this->createShortEventClassNameFromClassAndProperty($className, $methodName);

return $this->prependShortClassEventWithNamespace($shortEventClass, $className);
}

public function createEventClassNameFromClassPropertyReference(string $classAndPropertyName): string
{
[$class, $property] = Strings::split($classAndPropertyName, '#::#');

$shortEventClass = $this->createShortEventClassNameFromClassAndProperty($class, $property);

return $this->prependShortClassEventWithNamespace($shortEventClass, $class);
}

/**
* TomatoMarket, onBuy
* ↓
* TomatoMarketBuyEvent
*/
public function createShortEventClassNameFromClassAndProperty(string $class, string $property): string
private function createShortEventClassNameFromClassAndProperty(string $class, string $property): string
{
$shortClassName = $this->classNaming->getShortName($class);

Expand All @@ -69,13 +85,6 @@ public function createShortEventClassNameFromClassAndProperty(string $class, str
return $shortClassName . $shortPropertyName . 'Event';
}

public function createEventClassNameFromClassAndProperty(string $className, string $methodName): string
{
$shortEventClass = $this->createShortEventClassNameFromClassAndProperty($className, $methodName);

return $this->prependShortClassEventWithNamespace($shortEventClass, $className);
}

private function getShortEventClassName(MethodCall $methodCall): string
{
/** @var string $methodName */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,13 @@ private function replaceEventPropertyReferenceWithEventClassReference(ClassMetho
return null;
}

[$class, $property] = Strings::split($eventPropertyReferenceName, '#::#');

if (! property_exists($class, $property)) {
$eventClassName = $this->eventClassNaming->createEventClassNameFromClassPropertyReference(
$eventPropertyReferenceName
);
if ($eventClassName === null) {
return null;
}

$eventClassName = $this->eventClassNaming->createEventClassNameFromClassAndProperty($class, $property);

$node->key = $this->createClassConstantReference($eventClassName);
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<?php

declare(strict_types=1);

namespace Rector\NetteKdyby\Rector\MethodCall;

use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NetteKdyby\Naming\EventClassNaming;

/**
* @see \Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector\ReplaceEventManagerWithEventSubscriberRectorTest
*/
final class ReplaceEventManagerWithEventSubscriberRector extends AbstractRector
{
/**
* @var EventClassNaming
*/
private $eventClassNaming;

public function __construct(EventClassNaming $eventClassNaming)
{
$this->eventClassNaming = $eventClassNaming;
}

public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Change Kdyby EventManager to EventDispatcher', [
new CodeSample(
<<<'PHP'
use Kdyby\Events\EventManager;

final class SomeClass
{
/**
* @var EventManager
*/
private $eventManager;

public function __construct(EventManager $eventManager)
{
$this->eventManager = eventManager;
}

public function run()
{
$key = '2000';
$this->eventManager->dispatchEvent(static::class . '::onCopy', new EventArgsList([$this, $key]));
}
}
PHP
,
<<<'PHP'
use Kdyby\Events\EventManager;

final class SomeClass
{
/**
* @var EventManager
*/
private $eventManager;

public function __construct(EventManager $eventManager)
{
$this->eventManager = eventManager;
}

public function run()
{
$key = '2000';
$this->eventManager->dispatch(new SomeClassCopyEvent($this, $key));
}
}
PHP

),
]);
}

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

/**
* @param MethodCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType($node->var, 'Kdyby\Events\EventManager')) {
return null;
}

if (! $this->isName($node->name, 'dispatchEvent')) {
return null;
}

$node->name = new Identifier('dispatch');

$oldArgs = $node->args;
$node->args = [];

$eventReference = $oldArgs[0]->value;

$classAndStaticProperty = $this->getValue($eventReference, true);
$eventCass = $this->eventClassNaming->createEventClassNameFromClassPropertyReference($classAndStaticProperty);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo: also create the event class


$args = [];
if ($oldArgs[1]->value instanceof New_) {
/** @var New_ $new */
$new = $oldArgs[1]->value;

$array = $new->args[0]->value;
if ($array instanceof Array_) {
foreach ($array->items as $arrayItem) {
$args[] = new Arg($arrayItem->value);
}
}
}

$class = new New_(new FullyQualified($eventCass), $args);
$node->args[] = new Arg($class);

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

namespace Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector\Fixture;

use Kdyby\Events\EventManager;

final class SomeClass
{
/**
* @var EventManager
*/
private $eventManager;

public function __construct(EventManager $eventManager)
{
$this->eventManager = eventManager;
}

public function run()
{
$key = '2000';
$this->eventManager->dispatchEvent(static::class . '::onCopy', new EventArgsList([$this, $key]));
}
}

?>
-----
<?php

namespace Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector\Fixture;

use Kdyby\Events\EventManager;

final class SomeClass
{
/**
* @var EventManager
*/
private $eventManager;

public function __construct(EventManager $eventManager)
{
$this->eventManager = eventManager;
}

public function run()
{
$key = '2000';
$this->eventManager->dispatch(new \Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector\Fixture\Event\SomeClassCopyEvent($this, $key));
}
}

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

declare(strict_types=1);

namespace Rector\NetteKdyby\Tests\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector;

use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\NetteKdyby\Rector\MethodCall\ReplaceEventManagerWithEventSubscriberRector;

final class ReplaceEventManagerWithEventSubscriberRectorTest 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 ReplaceEventManagerWithEventSubscriberRector::class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,7 @@ function (Node $node) use ($objectType): bool {
$paramBuilder->setType(new FullyQualified($staticType));
$param = $paramBuilder->getNode();

$propertyFetch = new PropertyFetch(new Variable('this'), $variableName);
$assign = new Assign($propertyFetch, new Variable($variableName));
$assign = $this->nodeFactory->createPropertyAssignment($variableName);

$setEntityFactoryMethod = $this->createSetEntityFactoryClassMethod($variableName, $param, $assign);

Expand Down
17 changes: 11 additions & 6 deletions rules/solid/src/NodeFactory/InjectMethodFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@

use PhpParser\Builder\Method;
use PhpParser\Builder\Param;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\ObjectType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\CodingStyle\Naming\ClassNaming;
use Rector\Core\Naming\PropertyNaming;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\SOLID\Rector\Class_\MultiParentingToAbstractDependencyRector;

Expand All @@ -40,16 +38,23 @@ final class InjectMethodFactory
*/
private $typeFactory;

/**
* @var NodeFactory
*/
private $nodeFactory;

public function __construct(
PhpDocInfoFactory $phpDocInfoFactory,
PropertyNaming $propertyNaming,
ClassNaming $classNaming,
TypeFactory $typeFactory
TypeFactory $typeFactory,
NodeFactory $nodeFactory
) {
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->propertyNaming = $propertyNaming;
$this->classNaming = $classNaming;
$this->typeFactory = $typeFactory;
$this->nodeFactory = $nodeFactory;
}

/**
Expand All @@ -72,8 +77,8 @@ public function createFromTypes(array $objectTypes, string $className, string $f
$param->setType(new FullyQualified($objectType->getClassName()));
$methodBuilder->addParam($param);

$propertyFetch = new PropertyFetch(new Variable('this'), $propertyName);
$assign = new Assign($propertyFetch, new Variable($propertyName));
$assign = $this->nodeFactory->createPropertyAssignment($propertyName);

$methodBuilder->addStmt($assign);
}

Expand Down
Loading