add class to codebase if service is used by id (#10)

* add class to codebase if service is used by id

* fix doc
This commit is contained in:
Farhad Safarov 2020-03-11 16:43:52 +03:00 committed by GitHub
parent 268c1cd67d
commit d2f0447add
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 59 additions and 13 deletions

View File

@ -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
<?xml version="1.0"?>
<psalm
totallyTyped="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<psalm totallyTyped="true">
<!-- project configuration -->
<plugins>

View File

@ -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",
]);
}
}

View File

@ -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 {

View File

@ -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
"""
<?php
use Symfony\Component\HttpKernel\HttpKernelInterface;
class SomeController
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
{
$this->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
"""
<?php
class SomeController
{
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
public function index(): void
{
$this->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

View File

@ -15,5 +15,6 @@
</service>
<service id="Symfony\Component\HttpKernel\HttpKernelInterface" alias="http_kernel" public="true"/>
<service id="Foo\Bar" class="Foo\Bar" public="false"/>
<service id="private_service" class="Foo\Bar" public="false"/>
</services>
</container>