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 b27c5e4b..10ca68f7 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']]; } @@ -40,6 +55,10 @@ public function setDrupalServices(array $drupalServices): void } // @todo support factories + if (isset($serviceDefinition['factory'])) { + continue; + } + if (!isset($serviceDefinition['class'])) { if (class_exists($serviceId)) { $serviceDefinition['class'] = $serviceId; @@ -60,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]); } } } @@ -73,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/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 @@ +setDrupalServices([ 'entity_type.manager' => [ @@ -112,6 +114,11 @@ public function testFactory(string $id, callable $validator): void 'decorates' => 'unknown', 'class' => 'Drupal\service_map\Override', ], + 'Bug693\Foo' => null, + 'Bug693\BarInterface' => '@Bug693\Bar', + 'Bug693\Bar' => [ + 'decorates' => 'Bug693\Foo' + ], ]); $validator($service->getService($id)); } @@ -241,6 +248,13 @@ function (DrupalServiceDefinition $service): void { self::assertArrayHasKey('service_map.decorates_decorating_base', $child_decorators); } ]; + yield [ + 'Bug693\Foo', + function (DrupalServiceDefinition $service): void { + self::assertCount(1, $service->getDecorators()); + self::assertArrayHasKey('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 @@ +