Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service subscriber does not support custom service names #172

Closed
annuh opened this issue Apr 18, 2021 · 2 comments · Fixed by #204
Closed

Service subscriber does not support custom service names #172

annuh opened this issue Apr 18, 2021 · 2 comments · Fixed by #204

Comments

@annuh
Copy link

annuh commented Apr 18, 2021

Possibly related issue(s): #101

It seems the Psalm Symfony plugin doesn't support service subscribers using a custom service name.

Here is the related documentation: https://symfony.com/doc/current/service_container/service_subscribers_locators.html#including-services

For example the following PHP code

<?php

use Psr\Container\ContainerInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;

class ServiceProvider implements ServiceSubscriberInterface
{
    public function __construct(private ContainerInterface $container) {}

    public function getFooService(): FooService
    {
        return $this->container->get('foo');
    }

    public static function getSubscribedServices(): array
    {
        return [
            'foo' => FooService::class,
        ];
    }
}

results in the following error:

ERROR: ServiceNotFound - src/Service/ServiceProvider.php- Service "foo" not found
        return $this->container->get('foo');

Is this a missing feature or am I doing something wrong? 🙂

@seferov
Copy link
Member

seferov commented Apr 21, 2021

@annuh thank you for the report.

According to related tests defined here https://github.com/psalm/psalm-plugin-symfony/blob/master/tests/acceptance/acceptance/ServiceSubscriber.feature the feature is working as expected. Could you please provide a test case that fails with your scenario?

@annuh
Copy link
Author

annuh commented Jul 2, 2021

It turns this issue is caused by using const service names.

Here is a test case to reproduce our scenario:

  Scenario: Asserting psalm recognizes return type of services defined in getSubscribedServices
    Given I have the following code
      """
      <?php

      use Doctrine\ORM\EntityManagerInterface;
      use Psr\Container\ContainerInterface;
      use Symfony\Contracts\Service\ServiceSubscriberInterface;
      use Symfony\Component\Validator\Validator\ValidatorInterface;

      class SomeController implements ServiceSubscriberInterface
      {
        private const EM_SERVICE_NAME = 'em2';
        private $container;

        public function __construct(ContainerInterface $container)
        {
          $this->container = $container;
        }

        public function __invoke()
        {
          /** @psalm-trace $entityManager */
          $entityManager = $this->container->get('em');

          /** @psalm-trace $entityManager2 */
          $entityManager2 = $this->container->get(self::EM_SERVICE_NAME);

          /** @psalm-trace $validator */
          $validator = $this->container->get(ValidatorInterface::class);
        }

        public static function getSubscribedServices()
        {
          return [
            'em' => EntityManagerInterface::class, // with key
            self::EM_SERVICE_NAME => EntityManagerInterface::class, // with constant
            ValidatorInterface::class, // without key
          ];
        }
      }
      """
    When I run Psalm
    Then I see these errors
      | Type  | Message                                                              |
      | Trace | $entityManager: Doctrine\ORM\EntityManagerInterface                  |
      | Trace | $validator: Symfony\Component\Validator\Validator\ValidatorInterface |
    And I see no other errors

This results now in this error:

1) Service Subscriber: Asserting psalm recognizes return type of services defined in getSubscribedServices
 Test  tests/acceptance/acceptance/ServiceSubscriber.feature:Asserting psalm recognizes return type of services defined in getSubscribedServices
There were errors: 
| MixedAssignment | Unable to determine the type that $entityManager2 is being assigned to |
| Trace           | $entityManager2: mixed                                                 |
| ServiceNotFound | Service "self" not found                                               |

Is Psalm even capable of understanding const in this case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants