From c67e025b617c522abe2fab1c5ce77c95459122ce Mon Sep 17 00:00:00 2001 From: Luca Tumedei Date: Fri, 20 Oct 2023 13:00:17 +0200 Subject: [PATCH] build(rector) add rules to handle EventDispatcher versions --- composer.json | 7 ++- config/rector-35.php | 10 ++- ...SwapEventDispatcherEventNameParameters.php | 62 +++++++++++++++++++ src/Events/Dispatcher.php | 11 ++-- src/Events/LegacyEvent.php | 30 --------- .../WPBrowser/Events/DispatcherTest.php | 17 ++--- 6 files changed, 88 insertions(+), 49 deletions(-) create mode 100644 config/rector/src/SwapEventDispatcherEventNameParameters.php delete mode 100644 src/Events/LegacyEvent.php diff --git a/composer.json b/composer.json index 29ea47150..19206e7d4 100644 --- a/composer.json +++ b/composer.json @@ -43,9 +43,11 @@ "lucatume/codeception-snapshot-assertions": "^1.0.0", "gumlet/php-image-resize": "^1.6", "szepeviktor/phpstan-wordpress": "^1.3", + "phpstan/phpstan": "*", "phpstan/extension-installer": "^1.3", "phpstan/phpstan-symfony": "^1.3", - "squizlabs/php_codesniffer": "^3.7" + "squizlabs/php_codesniffer": "^3.7", + "rector/rector": "^0.18.5" }, "autoload": { "psr-4": { @@ -63,7 +65,8 @@ }, "autoload-dev": { "psr-4": { - "lucatume\\WPBrowser\\Tests\\": "tests/_support" + "lucatume\\WPBrowser\\Tests\\": "tests/_support", + "lucatume\\Rector\\": "config/rector/src" } }, "extra": { diff --git a/config/rector-35.php b/config/rector-35.php index bdada9df6..b32a9df57 100644 --- a/config/rector-35.php +++ b/config/rector-35.php @@ -2,7 +2,9 @@ declare( strict_types=1 ); +use lucatume\Rector\SwapEventDispatcherEventNameParameters; use Rector\Config\RectorConfig; +use Rector\Renaming\Rector\Name\RenameClassRector; use Rector\Set\ValueObject\DowngradeLevelSetList; use Rector\TypeDeclaration\Rector\ClassMethod\ArrayShapeFromConstantArrayReturnRector; use Rector\TypeDeclaration\Rector\Closure\AddClosureReturnTypeRector; @@ -14,5 +16,11 @@ dirname(__DIR__) . '/tests', ]); - $rectorConfig->sets([ DowngradeLevelSetList::DOWN_TO_PHP_71 ]); + $rectorConfig->ruleWithConfiguration(RenameClassRector::class,[ + 'Symfony\Contracts\EventDispatcher\Event' => 'Symfony\Component\EventDispatcher\Event' + ]); + + $rectorConfig->rule(SwapEventDispatcherEventNameParameters::class); + + $rectorConfig->sets([ DowngradeLevelSetList::DOWN_TO_PHP_71 ]); }; diff --git a/config/rector/src/SwapEventDispatcherEventNameParameters.php b/config/rector/src/SwapEventDispatcherEventNameParameters.php new file mode 100644 index 000000000..45cd2e7a3 --- /dev/null +++ b/config/rector/src/SwapEventDispatcherEventNameParameters.php @@ -0,0 +1,62 @@ +dispatch($event, $eventName);', + '$eventDispatcher->dispatch($eventName, $event);' + ) + ] + ); + } + + public function getNodeTypes(): array + { + return [MethodCall::class]; + } + + /** + * @param MethodCall $node + */ + public function refactor(Node $node): ?Node + { + $methodCallName = $this->getName($node->name); + if ($methodCallName !== 'dispatch') { + return null; + } + + if (!$this->isObjectType( + $node->var, + new ObjectType('Symfony\Component\EventDispatcher\EventDispatcherInterface') + )) { + return null; + } + + $args = $node->args; + + if (!($args[0] instanceof Node\Arg && $args[1] instanceof Node\Arg + && $args[0]->value?->name === 'event' + && $args[1]->value?->name === 'name')) { + return null; + } + + $node->args = [$args[1], $args[0]]; + + return $node; + } +} diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 85eab74a2..b59a3f458 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -87,12 +87,13 @@ public static function addListener(string $eventName, callable $listener, int $p */ public static function dispatch(string $name, mixed $origin = null, array $context = []): ?object { - if (class_exists(\Symfony\Contracts\EventDispatcher\Event::class)) { - $event = new Event($name, $context, $origin); - return self::getEventDispatcher()?->dispatch($event, $name); + $eventDispatcher = self::getEventDispatcher(); + + if (!$eventDispatcher) { + return null; } - $event = new LegacyEvent($name, $context, $origin); - return self::getEventDispatcher()?->dispatch($name, $event); //@phpstan-ignore-line + $event = new Event($name, $context, $origin); + return $eventDispatcher->dispatch($event, $name); } } diff --git a/src/Events/LegacyEvent.php b/src/Events/LegacyEvent.php deleted file mode 100644 index 6dd3fc0dc..000000000 --- a/src/Events/LegacyEvent.php +++ /dev/null @@ -1,30 +0,0 @@ - $context - */ - public function __construct(private string $name, private array $context, private mixed $origin = null) - { - } - - public function get(string $key, mixed $default): mixed - { - return $this->context[$key] ?? $default; - } - - public function getName(): string - { - return $this->name; - } - - public function getOrigin(): mixed - { - return $this->origin; - } - } -} diff --git a/tests/unit/lucatume/WPBrowser/Events/DispatcherTest.php b/tests/unit/lucatume/WPBrowser/Events/DispatcherTest.php index fa3fd545c..7be6da337 100644 --- a/tests/unit/lucatume/WPBrowser/Events/DispatcherTest.php +++ b/tests/unit/lucatume/WPBrowser/Events/DispatcherTest.php @@ -46,10 +46,7 @@ function should_allow_listening_to_and_dispatching_events() $callStack[] = 'first'; }, 100); - $eventClass = class_exists(\Symfony\Contracts\EventDispatcher\Event::class) ? - Event::class : LegacyEvent::class; - - $this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT')); + $this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT')); $this->assertEquals([ 'first', @@ -62,7 +59,7 @@ function should_allow_listening_to_and_dispatching_events() $callStack[] = 'new first'; }, 200); - $this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT')); + $this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT')); $this->assertEquals([ 'new first', @@ -75,7 +72,7 @@ function should_allow_listening_to_and_dispatching_events() $removeThird(); $removeFirst(); - $this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT')); + $this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT')); $this->assertEquals([ 'new first', @@ -113,9 +110,7 @@ function should_return_a_purposely_built_dispatcher_when_the_codeception_instanc $callStack[] = 'first'; }, 100); - $eventClass = class_exists(\Symfony\Contracts\EventDispatcher\Event::class) ? - Event::class : LegacyEvent::class; - $this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT')); + $this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT')); $this->assertEquals([ 'first', @@ -128,7 +123,7 @@ function should_return_a_purposely_built_dispatcher_when_the_codeception_instanc $callStack[] = 'new first'; }, 200); - $this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT')); + $this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT')); $this->assertEquals([ 'new first', @@ -141,7 +136,7 @@ function should_return_a_purposely_built_dispatcher_when_the_codeception_instanc $removeThird(); $removeFirst(); - $this->assertInstanceOf($eventClass, Dispatcher::dispatch('TEST_EVENT')); + $this->assertInstanceOf(Event::class, Dispatcher::dispatch('TEST_EVENT')); $this->assertEquals([ 'new first',