diff --git a/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/event-object.php.inc b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/event-object.php.inc new file mode 100644 index 00000000000..7cae8e234a5 --- /dev/null +++ b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/event-object.php.inc @@ -0,0 +1,16 @@ +<?php + +namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture; + +class EventObject +{ + /** @var \League\Event\EventDispatcher */ + private $dispatcher; + + public function run() + { + $this->dispatcher->dispatch(new \League\Event\Event('my-event')); + } +} + +?> diff --git a/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/fixture.php.inc b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/fixture.php.inc index 89ee1e788b7..affba56944b 100644 --- a/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/fixture.php.inc +++ b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/fixture.php.inc @@ -26,11 +26,16 @@ class Fixture public function run() { - $this->dispatcher->dispatch(new class implements \League\Event\HasEventName + $this->dispatcher->dispatch(new class('my-event') implements \League\Event\HasEventName { + private $name; + public function __construct(string $name) + { + $this->name = $name; + } public function eventName(): string { - return 'my-event'; + return $this->name; } }); } diff --git a/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/method-call.php.inc b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/method-call.php.inc new file mode 100644 index 00000000000..dba79eaee61 --- /dev/null +++ b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/method-call.php.inc @@ -0,0 +1,54 @@ +<?php + +namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture; + +class MethodCall +{ + /** @var \League\Event\EventDispatcher */ + private $dispatcher; + + public function run() + { + $this->dispatcher->dispatch($this->createEventName()); + } + + private function createEventName(): string + { + return 'my-event'; + } +} + +?> +----- +<?php + +namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture; + +class MethodCall +{ + /** @var \League\Event\EventDispatcher */ + private $dispatcher; + + public function run() + { + $this->dispatcher->dispatch(new class($this->createEventName()) implements \League\Event\HasEventName + { + private $name; + public function __construct(string $name) + { + $this->name = $name; + } + public function eventName(): string + { + return $this->name; + } + }); + } + + private function createEventName(): string + { + return 'my-event'; + } +} + +?> diff --git a/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/variable.php.inc b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/variable.php.inc new file mode 100644 index 00000000000..09936d99499 --- /dev/null +++ b/rules-tests/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector/Fixture/variable.php.inc @@ -0,0 +1,46 @@ +<?php + +namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture; + +class Variable +{ + /** @var \League\Event\EventDispatcher */ + private $dispatcher; + + public function run() + { + $name = 'my-event'; + $this->dispatcher->dispatch($name); + } +} + +?> +----- +<?php + +namespace Rector\Tests\LeagueEvent\Rector\MethodCall\DispatchStringToObjectRector\Fixture; + +class Variable +{ + /** @var \League\Event\EventDispatcher */ + private $dispatcher; + + public function run() + { + $name = 'my-event'; + $this->dispatcher->dispatch(new class($name) implements \League\Event\HasEventName + { + private $name; + public function __construct(string $name) + { + $this->name = $name; + } + public function eventName(): string + { + return $this->name; + } + }); + } +} + +?> diff --git a/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php b/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php index 4b85a778e83..fe2004e8594 100644 --- a/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php +++ b/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php @@ -5,14 +5,21 @@ namespace Rector\LeagueEvent\Rector\MethodCall; use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\New_; +use PhpParser\Node\Expr\Variable; use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\Param; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Expression; +use PhpParser\Node\Stmt\Property; +use PhpParser\Node\Stmt\PropertyProperty; use PhpParser\Node\Stmt\Return_; use PHPStan\Type\ObjectType; +use PHPStan\Type\StringType; use Rector\Core\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -90,10 +97,14 @@ CODE_SAMPLE return true; } - return ! $this->nodeTypeResolver->isObjectTypes($methodCall->var, [ + if (! $this->nodeTypeResolver->isObjectTypes($methodCall->var, [ new ObjectType('League\Event\EventDispatcher'), new ObjectType('League\Event\Emitter'), - ]); + ])) { + return true; + } + + return ! $this->getStaticType($methodCall->args[0]->value) instanceof StringType; } private function updateNode(MethodCall $methodCall): MethodCall @@ -108,21 +119,42 @@ CODE_SAMPLE return new New_(new Class_(null, [ 'implements' => $implements, - 'stmts' => $this->createAnonymousEventClassBody($expr), - ])); + 'stmts' => $this->createAnonymousEventClassBody(), + ]), [new Arg($expr)]); } /** * @return Stmt[] */ - private function createAnonymousEventClassBody(Expr $expr): array + private function createAnonymousEventClassBody(): array { return [ + new Property(Class_::MODIFIER_PRIVATE, [new PropertyProperty('name')]), + new ClassMethod('__construct', [ + 'flags' => Class_::MODIFIER_PUBLIC, + 'params' => $this->createConstructParams(), + 'stmts' => [new Expression($this->createConstructAssign())], + ]), new ClassMethod('eventName', [ 'flags' => Class_::MODIFIER_PUBLIC, 'returnType' => 'string', - 'stmts' => [new Return_($expr)], + 'stmts' => [new Return_(new Variable('this->name'))], ]), ]; } + + /** + * @return Param[] + */ + private function createConstructParams(): array + { + return [ + new Param(new Variable('name'), null, 'string') + ]; + } + + private function createConstructAssign(): Assign + { + return new Assign(new Variable('this->name'), new Variable('name')); + } }