From d2f0447add75c7fc375d2c097cace52a13d85abf Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Wed, 11 Mar 2020 16:43:52 +0300 Subject: [PATCH] add class to codebase if service is used by id (#10) * add class to codebase if service is used by id * fix doc --- README.md | 9 +--- src/Handler/ContainerHandler.php | 12 +++++- src/Handler/ContainerXmlHandler.php | 8 ++-- .../acceptance/ContainerXml.feature | 42 +++++++++++++++++++ tests/acceptance/container.xml | 1 + 5 files changed, 59 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a3265d2..400c92d 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ vendor/bin/psalm-plugin enable seferov/symfony-psalm-plugin ### Features -- Detect `ContainerInterface::get()` result type. Works better if you [configure](https://github.com/seferov/symfony-psalm-plugin/#configuration) compiled container XML file. +- Detect `ContainerInterface::get()` result type. Works better if you [configure](#configuration) compiled container XML file. - Fixes `PossiblyInvalidArgument` for `Symfony\Component\HttpFoundation\Request::getContent`. The plugin calculates real return type by checking the given argument and marks return type as either string or resource. - Complains when `Container` is injected to a service. Use dependency-injection. @@ -22,12 +22,7 @@ If you followed installation instructions, psalm-plugin command would added plug ```xml - + diff --git a/src/Handler/ContainerHandler.php b/src/Handler/ContainerHandler.php index a6d1150..bcd8f8e 100644 --- a/src/Handler/ContainerHandler.php +++ b/src/Handler/ContainerHandler.php @@ -27,7 +27,7 @@ class ContainerHandler implements AfterMethodCallAnalysisInterface array &$file_replacements = [], Union &$return_type_candidate = null ) { - if (!in_array($declaring_method_id, ['Psr\Container\ContainerInterface::get', 'Symfony\Component\DependencyInjection\ContainerInterface::get'])) { + if (!self::isContainerGet($declaring_method_id)) { return; } @@ -36,4 +36,14 @@ class ContainerHandler implements AfterMethodCallAnalysisInterface $return_type_candidate = new Union([new TNamedObject($className)]); } } + + public static function isContainerGet(string $declaring_method_id): bool + { + return in_array($declaring_method_id, [ + 'Psr\Container\ContainerInterface::get', + 'Symfony\Component\DependencyInjection\ContainerInterface::get', + "Symfony\Bundle\FrameworkBundle\Controller\AbstractController::get", + "Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait::get", + ]); + } } diff --git a/src/Handler/ContainerXmlHandler.php b/src/Handler/ContainerXmlHandler.php index 252be25..9806e03 100644 --- a/src/Handler/ContainerXmlHandler.php +++ b/src/Handler/ContainerXmlHandler.php @@ -33,11 +33,7 @@ class ContainerXmlHandler implements AfterMethodCallAnalysisInterface array &$file_replacements = [], Union &$return_type_candidate = null ) { - if (!in_array($declaring_method_id, [ - 'Psr\Container\ContainerInterface::get', - 'Symfony\Component\DependencyInjection\ContainerInterface::get', - "Symfony\Bundle\FrameworkBundle\Controller\AbstractController::get", - ])) { + if (!ContainerHandler::isContainerGet($declaring_method_id)) { return; } @@ -68,6 +64,8 @@ class ContainerXmlHandler implements AfterMethodCallAnalysisInterface if ($service->isPublic()) { $class = $service->getClassName(); if ($class) { + /** @psalm-suppress InternalMethod */ + $codebase->classlikes->addFullyQualifiedClassName($class); $return_type_candidate = new Union([new TNamedObject($class)]); } } else { diff --git a/tests/acceptance/acceptance/ContainerXml.feature b/tests/acceptance/acceptance/ContainerXml.feature index 86719b9..f9ee2a8 100644 --- a/tests/acceptance/acceptance/ContainerXml.feature +++ b/tests/acceptance/acceptance/ContainerXml.feature @@ -56,3 +56,45 @@ Feature: Container XML config Then I see these errors | Type | Message | | ServiceNotFound | Service "not_a_service" not found | + + Scenario: Using service both via alias and class const + Given I have the following code + """ + container->get('http_kernel'); + $this->container->get(HttpKernelInterface::class); + } + } + """ + When I run Psalm + Then I see no errors + + Scenario: Using private service + Given I have the following code + """ + container->get('private_service'); + } + } + """ + When I run Psalm + Then I see these errors + | Type | Message | + | PrivateService | Private service "private_service" used in container::get() | + And I see no errors diff --git a/tests/acceptance/container.xml b/tests/acceptance/container.xml index d150c1a..5a3c089 100644 --- a/tests/acceptance/container.xml +++ b/tests/acceptance/container.xml @@ -15,5 +15,6 @@ +