From ebf2770e93194bcb055a9b7c9f887aa1c7ff2d7f Mon Sep 17 00:00:00 2001 From: Matt Glaman Date: Wed, 31 Jan 2024 15:07:42 -0600 Subject: [PATCH 1/4] test crash when using autowiring --- .../phpstan_fixtures/phpstan_fixtures.services.yml | 8 ++++++++ .../drupal/modules/phpstan_fixtures/src/Bar.php | 14 ++++++++++++++ .../modules/phpstan_fixtures/src/BarInterface.php | 8 ++++++++ .../drupal/modules/phpstan_fixtures/src/Foo.php | 7 +++++++ 4 files changed, 37 insertions(+) create mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.services.yml create mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/src/Bar.php create mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/src/BarInterface.php create mode 100644 tests/fixtures/drupal/modules/phpstan_fixtures/src/Foo.php diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.services.yml b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.services.yml new file mode 100644 index 00000000..f036e072 --- /dev/null +++ b/tests/fixtures/drupal/modules/phpstan_fixtures/phpstan_fixtures.services.yml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + + Drupal\phpstan_fixtures\Foo: + Drupal\phpstan_fixtures\BarInterface: '@Drupal\phpstan_fixtures\Bar' + Drupal\phpstan_fixtures\Bar: + decorates: Drupal\phpstan_fixtures\Foo diff --git a/tests/fixtures/drupal/modules/phpstan_fixtures/src/Bar.php b/tests/fixtures/drupal/modules/phpstan_fixtures/src/Bar.php new file mode 100644 index 00000000..13214a71 --- /dev/null +++ b/tests/fixtures/drupal/modules/phpstan_fixtures/src/Bar.php @@ -0,0 +1,14 @@ + Date: Wed, 31 Jan 2024 15:33:46 -0600 Subject: [PATCH 2/4] Work on handling aliases --- src/Drupal/ServiceMap.php | 21 ++- tests/src/ServiceMapFactoryTest.php | 241 ++++++++++++++++++---------- 2 files changed, 170 insertions(+), 92 deletions(-) diff --git a/src/Drupal/ServiceMap.php b/src/Drupal/ServiceMap.php index b27c5e4b..999f9fed 100644 --- a/src/Drupal/ServiceMap.php +++ b/src/Drupal/ServiceMap.php @@ -28,6 +28,21 @@ public function setDrupalServices(array $drupalServices): void $decorators = []; foreach ($drupalServices as $serviceId => $serviceDefinition) { + // @todo this duplicates \Symfony\Component\DependencyInjection\Loader\YamlFileLoader::parseDefinition() + // Can we re-use the YamlFileLoader instead of this manual parsing? + if (is_string($serviceDefinition) && strpos($serviceDefinition, '@') === 0) { + $serviceDefinition = [ + 'alias' => substr($serviceDefinition, 1) + ]; + } + if (is_null($serviceDefinition)) { + $serviceDefinition = []; + } + + if (!is_array($serviceDefinition)) { + continue; + } + if (isset($serviceDefinition['alias'], $drupalServices[$serviceDefinition['alias']])) { $serviceDefinition = $drupalServices[$serviceDefinition['alias']]; } @@ -41,11 +56,7 @@ public function setDrupalServices(array $drupalServices): void // @todo support factories if (!isset($serviceDefinition['class'])) { - if (class_exists($serviceId)) { - $serviceDefinition['class'] = $serviceId; - } else { - continue; - } + $serviceDefinition['class'] = $serviceId; } self::$services[$serviceId] = new DrupalServiceDefinition( (string) $serviceId, diff --git a/tests/src/ServiceMapFactoryTest.php b/tests/src/ServiceMapFactoryTest.php index 5834bb9e..200a407d 100644 --- a/tests/src/ServiceMapFactoryTest.php +++ b/tests/src/ServiceMapFactoryTest.php @@ -24,95 +24,10 @@ final class ServiceMapFactoryTest extends TestCase * @covers \mglaman\PHPStanDrupal\Drupal\ServiceMap::getService * @covers \mglaman\PHPStanDrupal\Drupal\ServiceMap::resolveParentDefinition */ - public function testFactory(string $id, callable $validator): void + public function testFactory(string $id, array $serviceMap, callable $validator): void { $service = new ServiceMap(); - $service->setDrupalServices([ - 'entity_type.manager' => [ - 'class' => 'Drupal\Core\Entity\EntityTypeManager' - ], - 'skipped_factory' => [ - 'factory' => 'cache_factory:get', - 'arguments' => ['cache'], - ], - 'config.storage.staging' => [ - 'class' => 'Drupal\Core\Config\FileStorage', - ], - 'config.storage.sync' => [ - 'alias' => 'config.storage.staging', - ], - 'abstract_service' => [ - 'abstract' => true, - 'class' => 'Drupal\service_map\MyService', - ], - 'concrete_service' => [ - 'parent' => 'abstract_service', - ], - 'concrete_service_with_a_parent_which_has_a_parent' => [ - 'parent' => 'concrete_service', - ], - 'abstract_service_private' => [ - 'abstract' => true, - 'class' => 'Drupal\service_map\MyService', - 'public' => false, - ], - 'concrete_service_overriding_definition_of_its_parent' => [ - 'parent' => 'abstract_service_private', - 'class' => 'Drupal\service_map\Override', - 'public' => true, - ], - 'service_with_unknown_parent' => [ - 'parent' => 'unknown_parent', - ], - 'service_with_unknown_parent_overriding_definition_of_its_parent' => [ - 'parent' => 'unknown_parent', - 'class' => 'Drupal\service_map\Override', - 'public' => false, - ], - 'service_map.base' => [ - 'class' => 'Drupal\service_map\Base', - 'public' => false, - 'abstract' => true, - ], - 'service_map.second_base' => [ - 'parent' => 'service_map.base', - 'class' => 'Drupal\service_map\SecondBase', - 'abstract' => true, - ], - 'service_map.concrete_overriding_its_parent_which_has_a_parent' => [ - 'parent' => 'service_map.second_base', - 'class' => 'Drupal\service_map\Concrete', - 'public' => true, - ], - 'logger.channel_base' => [ - 'abstract' => true, - 'class' => LoggerChannel::class, - 'factory' => ['@logger.factory', 'get'], - ], - 'logger.channel.workspaces' => [ - 'parent' => 'logger.channel_base', - 'arguments' => ['workspaces'], - ], - 'Psr\Log\LoggerInterface $loggerWorkspaces' => [ - 'alias' => 'logger.channel.workspaces' - ], - 'service_map.base_to_be_decorated' => [ - 'class' => 'Drupal\service_map\Base', - 'abstract' => true, - ], - 'service_map.deocrating_base' => [ - 'decorates' => 'service_map.base_to_be_decorated', - 'class' => 'Drupal\service_map\SecondBase', - ], - 'service_map.decorates_decorating_base' => [ - 'decorates' => 'service_map.deocrating_base', - 'class' => 'Drupal\service_map\Override', - ], - 'decorating_an_unknown_service' => [ - 'decorates' => 'unknown', - 'class' => 'Drupal\service_map\Override', - ], - ]); + $service->setDrupalServices($serviceMap); $validator($service->getService($id)); } @@ -120,12 +35,18 @@ public function getServiceProvider(): \Iterator { yield [ 'unknown', + [], function (?DrupalServiceDefinition $service): void { self::assertNull($service, 'unknown'); }, ]; yield [ 'entity_type.manager', + [ + 'entity_type.manager' => [ + 'class' => 'Drupal\Core\Entity\EntityTypeManager' + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('entity_type.manager', $service->getId()); self::assertEquals('Drupal\Core\Entity\EntityTypeManager', $service->getClass()); @@ -136,18 +57,41 @@ function (DrupalServiceDefinition $service): void { // For now factories are skipped. yield [ 'skipped_factory', + [ + 'skipped_factory' => [ + 'factory' => 'cache_factory:get', + 'arguments' => ['cache'], + ], + ], function (?DrupalServiceDefinition $service): void { self::assertNull($service); }, ]; yield [ 'config.storage.sync', + [ + 'config.storage.staging' => [ + 'class' => 'Drupal\Core\Config\FileStorage', + ], + 'config.storage.sync' => [ + 'alias' => 'config.storage.staging', + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('Drupal\Core\Config\FileStorage', $service->getClass()); } ]; yield [ 'concrete_service', + [ + 'abstract_service' => [ + 'abstract' => true, + 'class' => 'Drupal\service_map\MyService', + ], + 'concrete_service' => [ + 'parent' => 'abstract_service', + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('concrete_service', $service->getId()); self::assertEquals('Drupal\service_map\MyService', $service->getClass()); @@ -157,6 +101,18 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'concrete_service_with_a_parent_which_has_a_parent', + [ + 'abstract_service' => [ + 'abstract' => true, + 'class' => 'Drupal\service_map\MyService', + ], + 'concrete_service' => [ + 'parent' => 'abstract_service', + ], + 'concrete_service_with_a_parent_which_has_a_parent' => [ + 'parent' => 'concrete_service', + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('concrete_service_with_a_parent_which_has_a_parent', $service->getId()); self::assertEquals('Drupal\service_map\MyService', $service->getClass()); @@ -166,6 +122,13 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'abstract_service_private', + [ + 'abstract_service_private' => [ + 'abstract' => true, + 'class' => 'Drupal\service_map\MyService', + 'public' => false, + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('abstract_service_private', $service->getId()); self::assertEquals('Drupal\service_map\MyService', $service->getClass()); @@ -175,6 +138,18 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'concrete_service_overriding_definition_of_its_parent', + [ + 'abstract_service_private' => [ + 'abstract' => true, + 'class' => 'Drupal\service_map\MyService', + 'public' => false, + ], + 'concrete_service_overriding_definition_of_its_parent' => [ + 'parent' => 'abstract_service_private', + 'class' => 'Drupal\service_map\Override', + 'public' => true, + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('concrete_service_overriding_definition_of_its_parent', $service->getId()); self::assertEquals('Drupal\service_map\Override', $service->getClass()); @@ -184,12 +159,27 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_with_unknown_parent', + [ + 'service_with_unknown_parent' => [ + 'parent' => 'unknown_parent', + ], + ], function (?DrupalServiceDefinition $service): void { self::assertNull($service); } ]; yield [ 'service_with_unknown_parent_overriding_definition_of_its_parent', + [ + 'service_with_unknown_parent' => [ + 'parent' => 'unknown_parent', + ], + 'service_with_unknown_parent_overriding_definition_of_its_parent' => [ + 'parent' => 'unknown_parent', + 'class' => 'Drupal\service_map\Override', + 'public' => false, + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_with_unknown_parent_overriding_definition_of_its_parent', $service->getId()); self::assertEquals('Drupal\service_map\Override', $service->getClass()); @@ -199,6 +189,13 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_map.base', + [ + 'service_map.base' => [ + 'class' => 'Drupal\service_map\Base', + 'public' => false, + 'abstract' => true, + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_map.base', $service->getId()); self::assertEquals('Drupal\service_map\Base', $service->getClass()); @@ -208,6 +205,18 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_map.second_base', + [ + 'service_map.base' => [ + 'class' => 'Drupal\service_map\Base', + 'public' => false, + 'abstract' => true, + ], + 'service_map.second_base' => [ + 'parent' => 'service_map.base', + 'class' => 'Drupal\service_map\SecondBase', + 'abstract' => true, + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_map.second_base', $service->getId()); self::assertEquals('Drupal\service_map\SecondBase', $service->getClass()); @@ -217,6 +226,23 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_map.concrete_overriding_its_parent_which_has_a_parent', + [ + 'service_map.base' => [ + 'class' => 'Drupal\service_map\Base', + 'public' => false, + 'abstract' => true, + ], + 'service_map.second_base' => [ + 'parent' => 'service_map.base', + 'class' => 'Drupal\service_map\SecondBase', + 'abstract' => true, + ], + 'service_map.concrete_overriding_its_parent_which_has_a_parent' => [ + 'parent' => 'service_map.second_base', + 'class' => 'Drupal\service_map\Concrete', + 'public' => true, + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_map.concrete_overriding_its_parent_which_has_a_parent', $service->getId()); self::assertEquals('Drupal\service_map\Concrete', $service->getClass()); @@ -226,12 +252,40 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'Psr\Log\LoggerInterface $loggerWorkspaces', + [ + 'logger.channel_base' => [ + 'abstract' => true, + 'class' => LoggerChannel::class, + 'factory' => ['@logger.factory', 'get'], + ], + 'logger.channel.workspaces' => [ + 'parent' => 'logger.channel_base', + 'arguments' => ['workspaces'], + ], + 'Psr\Log\LoggerInterface $loggerWorkspaces' => [ + 'alias' => 'logger.channel.workspaces' + ], + ], function (DrupalServiceDefinition $service): void { self::assertEquals(LoggerChannel::class, $service->getClass()); } ]; yield [ 'service_map.base_to_be_decorated', + [ + 'service_map.deocrating_base' => [ + 'decorates' => 'service_map.base_to_be_decorated', + 'class' => 'Drupal\service_map\SecondBase', + ], + 'service_map.decorates_decorating_base' => [ + 'decorates' => 'service_map.deocrating_base', + 'class' => 'Drupal\service_map\Override', + ], + 'service_map.base_to_be_decorated' => [ + 'class' => 'Drupal\service_map\Base', + 'abstract' => true, + ], + ], function (DrupalServiceDefinition $service): void { $decorators = $service->getDecorators(); self::assertCount(1, $decorators); @@ -241,6 +295,19 @@ function (DrupalServiceDefinition $service): void { self::assertArrayHasKey('service_map.decorates_decorating_base', $child_decorators); } ]; + yield [ + 'Drupal\phpstan_example\Foo', + [ + 'Drupal\phpstan_example\Foo' => null, + 'Drupal\phpstan_example\BarInterface' => '@Drupal\phpstan_example\Bar', + 'Drupal\phpstan_example\Bar' => [ + 'decorates' => 'Drupal\phpstan_example\Foo' + ], + ], + function (DrupalServiceDefinition $service): void { + self::assertCount(2, $service->getDecorators()); + } + ]; } } From 8038972c6c6b322fd1e5bc441716d8f9fbec04f2 Mon Sep 17 00:00:00 2001 From: Matt Glaman Date: Wed, 31 Jan 2024 17:09:21 -0600 Subject: [PATCH 3/4] provide a basic fix --- src/Drupal/DrupalAutoloader.php | 7 - src/Drupal/ServiceMap.php | 21 ++- tests/src/ServiceMapFactoryTest.php | 247 +++++++++++----------------- tests/src/data/bug-693.php | 18 ++ 4 files changed, 131 insertions(+), 162 deletions(-) create mode 100644 tests/src/data/bug-693.php diff --git a/src/Drupal/DrupalAutoloader.php b/src/Drupal/DrupalAutoloader.php index 9b681dd5..b1ef6546 100644 --- a/src/Drupal/DrupalAutoloader.php +++ b/src/Drupal/DrupalAutoloader.php @@ -188,13 +188,6 @@ public function register(Container $container): void continue; } foreach ($yaml['services'] as $serviceId => $serviceDefinition) { - // Check if this is an alias shortcut. - // @link https://symfony.com/doc/4.4/service_container/alias_private.html#aliasing - if (is_string($serviceDefinition)) { - $serviceDefinition = [ - 'alias' => str_replace('@', '', $serviceDefinition), - ]; - } // Prevent \Nette\DI\ContainerBuilder::completeStatement from array_walk_recursive into the arguments // and thinking these are real services for PHPStan's container. if (isset($serviceDefinition['arguments']) && is_array($serviceDefinition['arguments'])) { diff --git a/src/Drupal/ServiceMap.php b/src/Drupal/ServiceMap.php index 999f9fed..10ca68f7 100644 --- a/src/Drupal/ServiceMap.php +++ b/src/Drupal/ServiceMap.php @@ -55,8 +55,16 @@ public function setDrupalServices(array $drupalServices): void } // @todo support factories + if (isset($serviceDefinition['factory'])) { + continue; + } + if (!isset($serviceDefinition['class'])) { - $serviceDefinition['class'] = $serviceId; + if (class_exists($serviceId)) { + $serviceDefinition['class'] = $serviceId; + } else { + continue; + } } self::$services[$serviceId] = new DrupalServiceDefinition( (string) $serviceId, @@ -71,11 +79,14 @@ public function setDrupalServices(array $drupalServices): void } foreach ($decorators as $decorated_service_id => $services) { - foreach ($services as $dcorating_service_id) { - if (!isset(self::$services[$decorated_service_id])) { + if (!isset(self::$services[$decorated_service_id])) { + continue; + } + foreach ($services as $decorating_service_id) { + if (!isset(self::$services[$decorating_service_id])) { continue; } - self::$services[$decorated_service_id]->addDecorator(self::$services[$dcorating_service_id]); + self::$services[$decorated_service_id]->addDecorator(self::$services[$decorating_service_id]); } } } @@ -84,7 +95,7 @@ private function resolveParentDefinition(string $parentId, array $serviceDefinit { $parentDefinition = $drupalServices[$parentId] ?? []; if ([] === $parentDefinition) { - return $serviceDefinition; + return $parentDefinition; } if (isset($parentDefinition['parent'])) { diff --git a/tests/src/ServiceMapFactoryTest.php b/tests/src/ServiceMapFactoryTest.php index 200a407d..7fafb239 100644 --- a/tests/src/ServiceMapFactoryTest.php +++ b/tests/src/ServiceMapFactoryTest.php @@ -24,10 +24,102 @@ final class ServiceMapFactoryTest extends TestCase * @covers \mglaman\PHPStanDrupal\Drupal\ServiceMap::getService * @covers \mglaman\PHPStanDrupal\Drupal\ServiceMap::resolveParentDefinition */ - public function testFactory(string $id, array $serviceMap, callable $validator): void + public function testFactory(string $id, callable $validator): void { + require_once __DIR__ . '/data/bug-693.php'; + $service = new ServiceMap(); - $service->setDrupalServices($serviceMap); + $service->setDrupalServices([ + 'entity_type.manager' => [ + 'class' => 'Drupal\Core\Entity\EntityTypeManager' + ], + 'skipped_factory' => [ + 'factory' => 'cache_factory:get', + 'arguments' => ['cache'], + ], + 'config.storage.staging' => [ + 'class' => 'Drupal\Core\Config\FileStorage', + ], + 'config.storage.sync' => [ + 'alias' => 'config.storage.staging', + ], + 'abstract_service' => [ + 'abstract' => true, + 'class' => 'Drupal\service_map\MyService', + ], + 'concrete_service' => [ + 'parent' => 'abstract_service', + ], + 'concrete_service_with_a_parent_which_has_a_parent' => [ + 'parent' => 'concrete_service', + ], + 'abstract_service_private' => [ + 'abstract' => true, + 'class' => 'Drupal\service_map\MyService', + 'public' => false, + ], + 'concrete_service_overriding_definition_of_its_parent' => [ + 'parent' => 'abstract_service_private', + 'class' => 'Drupal\service_map\Override', + 'public' => true, + ], + 'service_with_unknown_parent' => [ + 'parent' => 'unknown_parent', + ], + 'service_with_unknown_parent_overriding_definition_of_its_parent' => [ + 'parent' => 'unknown_parent', + 'class' => 'Drupal\service_map\Override', + 'public' => false, + ], + 'service_map.base' => [ + 'class' => 'Drupal\service_map\Base', + 'public' => false, + 'abstract' => true, + ], + 'service_map.second_base' => [ + 'parent' => 'service_map.base', + 'class' => 'Drupal\service_map\SecondBase', + 'abstract' => true, + ], + 'service_map.concrete_overriding_its_parent_which_has_a_parent' => [ + 'parent' => 'service_map.second_base', + 'class' => 'Drupal\service_map\Concrete', + 'public' => true, + ], + 'logger.channel_base' => [ + 'abstract' => true, + 'class' => LoggerChannel::class, + 'factory' => ['@logger.factory', 'get'], + ], + 'logger.channel.workspaces' => [ + 'parent' => 'logger.channel_base', + 'arguments' => ['workspaces'], + ], + 'Psr\Log\LoggerInterface $loggerWorkspaces' => [ + 'alias' => 'logger.channel.workspaces' + ], + 'service_map.base_to_be_decorated' => [ + 'class' => 'Drupal\service_map\Base', + 'abstract' => true, + ], + 'service_map.deocrating_base' => [ + 'decorates' => 'service_map.base_to_be_decorated', + 'class' => 'Drupal\service_map\SecondBase', + ], + 'service_map.decorates_decorating_base' => [ + 'decorates' => 'service_map.deocrating_base', + 'class' => 'Drupal\service_map\Override', + ], + 'decorating_an_unknown_service' => [ + 'decorates' => 'unknown', + 'class' => 'Drupal\service_map\Override', + ], + 'Bug693\Foo' => null, + 'Bug693\BarInterface' => '@Bug693\Bar', + 'Bug693\Bar' => [ + 'decorates' => 'Bug693\Foo' + ], + ]); $validator($service->getService($id)); } @@ -35,18 +127,12 @@ public function getServiceProvider(): \Iterator { yield [ 'unknown', - [], function (?DrupalServiceDefinition $service): void { self::assertNull($service, 'unknown'); }, ]; yield [ 'entity_type.manager', - [ - 'entity_type.manager' => [ - 'class' => 'Drupal\Core\Entity\EntityTypeManager' - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('entity_type.manager', $service->getId()); self::assertEquals('Drupal\Core\Entity\EntityTypeManager', $service->getClass()); @@ -57,41 +143,18 @@ function (DrupalServiceDefinition $service): void { // For now factories are skipped. yield [ 'skipped_factory', - [ - 'skipped_factory' => [ - 'factory' => 'cache_factory:get', - 'arguments' => ['cache'], - ], - ], function (?DrupalServiceDefinition $service): void { self::assertNull($service); }, ]; yield [ 'config.storage.sync', - [ - 'config.storage.staging' => [ - 'class' => 'Drupal\Core\Config\FileStorage', - ], - 'config.storage.sync' => [ - 'alias' => 'config.storage.staging', - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('Drupal\Core\Config\FileStorage', $service->getClass()); } ]; yield [ 'concrete_service', - [ - 'abstract_service' => [ - 'abstract' => true, - 'class' => 'Drupal\service_map\MyService', - ], - 'concrete_service' => [ - 'parent' => 'abstract_service', - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('concrete_service', $service->getId()); self::assertEquals('Drupal\service_map\MyService', $service->getClass()); @@ -101,18 +164,6 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'concrete_service_with_a_parent_which_has_a_parent', - [ - 'abstract_service' => [ - 'abstract' => true, - 'class' => 'Drupal\service_map\MyService', - ], - 'concrete_service' => [ - 'parent' => 'abstract_service', - ], - 'concrete_service_with_a_parent_which_has_a_parent' => [ - 'parent' => 'concrete_service', - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('concrete_service_with_a_parent_which_has_a_parent', $service->getId()); self::assertEquals('Drupal\service_map\MyService', $service->getClass()); @@ -122,13 +173,6 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'abstract_service_private', - [ - 'abstract_service_private' => [ - 'abstract' => true, - 'class' => 'Drupal\service_map\MyService', - 'public' => false, - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('abstract_service_private', $service->getId()); self::assertEquals('Drupal\service_map\MyService', $service->getClass()); @@ -138,18 +182,6 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'concrete_service_overriding_definition_of_its_parent', - [ - 'abstract_service_private' => [ - 'abstract' => true, - 'class' => 'Drupal\service_map\MyService', - 'public' => false, - ], - 'concrete_service_overriding_definition_of_its_parent' => [ - 'parent' => 'abstract_service_private', - 'class' => 'Drupal\service_map\Override', - 'public' => true, - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('concrete_service_overriding_definition_of_its_parent', $service->getId()); self::assertEquals('Drupal\service_map\Override', $service->getClass()); @@ -159,27 +191,12 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_with_unknown_parent', - [ - 'service_with_unknown_parent' => [ - 'parent' => 'unknown_parent', - ], - ], function (?DrupalServiceDefinition $service): void { self::assertNull($service); } ]; yield [ 'service_with_unknown_parent_overriding_definition_of_its_parent', - [ - 'service_with_unknown_parent' => [ - 'parent' => 'unknown_parent', - ], - 'service_with_unknown_parent_overriding_definition_of_its_parent' => [ - 'parent' => 'unknown_parent', - 'class' => 'Drupal\service_map\Override', - 'public' => false, - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_with_unknown_parent_overriding_definition_of_its_parent', $service->getId()); self::assertEquals('Drupal\service_map\Override', $service->getClass()); @@ -189,13 +206,6 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_map.base', - [ - 'service_map.base' => [ - 'class' => 'Drupal\service_map\Base', - 'public' => false, - 'abstract' => true, - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_map.base', $service->getId()); self::assertEquals('Drupal\service_map\Base', $service->getClass()); @@ -205,18 +215,6 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_map.second_base', - [ - 'service_map.base' => [ - 'class' => 'Drupal\service_map\Base', - 'public' => false, - 'abstract' => true, - ], - 'service_map.second_base' => [ - 'parent' => 'service_map.base', - 'class' => 'Drupal\service_map\SecondBase', - 'abstract' => true, - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_map.second_base', $service->getId()); self::assertEquals('Drupal\service_map\SecondBase', $service->getClass()); @@ -226,23 +224,6 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'service_map.concrete_overriding_its_parent_which_has_a_parent', - [ - 'service_map.base' => [ - 'class' => 'Drupal\service_map\Base', - 'public' => false, - 'abstract' => true, - ], - 'service_map.second_base' => [ - 'parent' => 'service_map.base', - 'class' => 'Drupal\service_map\SecondBase', - 'abstract' => true, - ], - 'service_map.concrete_overriding_its_parent_which_has_a_parent' => [ - 'parent' => 'service_map.second_base', - 'class' => 'Drupal\service_map\Concrete', - 'public' => true, - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals('service_map.concrete_overriding_its_parent_which_has_a_parent', $service->getId()); self::assertEquals('Drupal\service_map\Concrete', $service->getClass()); @@ -252,40 +233,12 @@ function (DrupalServiceDefinition $service): void { ]; yield [ 'Psr\Log\LoggerInterface $loggerWorkspaces', - [ - 'logger.channel_base' => [ - 'abstract' => true, - 'class' => LoggerChannel::class, - 'factory' => ['@logger.factory', 'get'], - ], - 'logger.channel.workspaces' => [ - 'parent' => 'logger.channel_base', - 'arguments' => ['workspaces'], - ], - 'Psr\Log\LoggerInterface $loggerWorkspaces' => [ - 'alias' => 'logger.channel.workspaces' - ], - ], function (DrupalServiceDefinition $service): void { self::assertEquals(LoggerChannel::class, $service->getClass()); } ]; yield [ 'service_map.base_to_be_decorated', - [ - 'service_map.deocrating_base' => [ - 'decorates' => 'service_map.base_to_be_decorated', - 'class' => 'Drupal\service_map\SecondBase', - ], - 'service_map.decorates_decorating_base' => [ - 'decorates' => 'service_map.deocrating_base', - 'class' => 'Drupal\service_map\Override', - ], - 'service_map.base_to_be_decorated' => [ - 'class' => 'Drupal\service_map\Base', - 'abstract' => true, - ], - ], function (DrupalServiceDefinition $service): void { $decorators = $service->getDecorators(); self::assertCount(1, $decorators); @@ -296,16 +249,10 @@ function (DrupalServiceDefinition $service): void { } ]; yield [ - 'Drupal\phpstan_example\Foo', - [ - 'Drupal\phpstan_example\Foo' => null, - 'Drupal\phpstan_example\BarInterface' => '@Drupal\phpstan_example\Bar', - 'Drupal\phpstan_example\Bar' => [ - 'decorates' => 'Drupal\phpstan_example\Foo' - ], - ], + 'Bug693\Foo', function (DrupalServiceDefinition $service): void { - self::assertCount(2, $service->getDecorators()); + self::assertCount(1, $service->getDecorators()); + self::arrayHasKey('Bug693\\Bar', $service->getDecorators()); } ]; } diff --git a/tests/src/data/bug-693.php b/tests/src/data/bug-693.php new file mode 100644 index 00000000..8b978edc --- /dev/null +++ b/tests/src/data/bug-693.php @@ -0,0 +1,18 @@ + Date: Wed, 31 Jan 2024 17:13:07 -0600 Subject: [PATCH 4/4] fix assert --- tests/src/ServiceMapFactoryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/ServiceMapFactoryTest.php b/tests/src/ServiceMapFactoryTest.php index 7fafb239..dca90d21 100644 --- a/tests/src/ServiceMapFactoryTest.php +++ b/tests/src/ServiceMapFactoryTest.php @@ -252,7 +252,7 @@ function (DrupalServiceDefinition $service): void { 'Bug693\Foo', function (DrupalServiceDefinition $service): void { self::assertCount(1, $service->getDecorators()); - self::arrayHasKey('Bug693\\Bar', $service->getDecorators()); + self::assertArrayHasKey('Bug693\\Bar', $service->getDecorators()); } ]; }