mirror of
https://github.com/danog/psalm-plugin-symfony.git
synced 2024-11-30 04:29:10 +01:00
HeaderBag get default value return type (#49)
This commit is contained in:
parent
3b5b7016fc
commit
b9f4745e28
@ -17,7 +17,7 @@ to use InputArgument and InputOption constants as a part of best practise.
|
||||
- Detects correct Doctrine repository class if entities are configured with annotations.
|
||||
- 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.
|
||||
- Detect return type of `Symfony\Component\HttpFoundation\HeaderBag::get` (by checking third argument for < Symfony 4.4)
|
||||
- Detect return type of `Symfony\Component\HttpFoundation\HeaderBag::get` (by checking default value and third argument for < Symfony 4.4)
|
||||
- Detects service [naming convention](https://symfony.com/doc/current/contributing/code/standards.html#naming-conventions) violations
|
||||
- Complains when `Container` is injected to a service. Use dependency-injection.
|
||||
|
||||
|
@ -2,42 +2,48 @@
|
||||
|
||||
namespace Psalm\SymfonyPsalmPlugin\Handler;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use Psalm\Codebase;
|
||||
use PhpParser\Node\Expr\ConstFetch;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use Psalm\CodeLocation;
|
||||
use Psalm\Context;
|
||||
use Psalm\Plugin\Hook\AfterMethodCallAnalysisInterface;
|
||||
use Psalm\Plugin\Hook\MethodReturnTypeProviderInterface;
|
||||
use Psalm\StatementsSource;
|
||||
use Psalm\Type\Atomic\TArray;
|
||||
use Psalm\Type\Atomic\TInt;
|
||||
use Psalm\Type\Atomic\TNull;
|
||||
use Psalm\Type\Atomic\TString;
|
||||
use Psalm\Type\Union;
|
||||
use Symfony\Component\HttpFoundation\HeaderBag;
|
||||
|
||||
class HeaderBagHandler implements AfterMethodCallAnalysisInterface
|
||||
class HeaderBagHandler implements MethodReturnTypeProviderInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function afterMethodCallAnalysis(
|
||||
Expr $expr,
|
||||
string $method_id,
|
||||
string $appearing_method_id,
|
||||
string $declaring_method_id,
|
||||
Context $context,
|
||||
StatementsSource $statements_source,
|
||||
Codebase $codebase,
|
||||
array &$file_replacements = [],
|
||||
Union &$return_type_candidate = null
|
||||
) {
|
||||
if ('Symfony\Component\HttpFoundation\HeaderBag::get' === $declaring_method_id) {
|
||||
if ($return_type_candidate) {
|
||||
/** @psalm-suppress MixedArrayAccess */
|
||||
if (isset($expr->args[2]->value->name->parts[0]) && 'false' === $expr->args[2]->value->name->parts[0]) {
|
||||
$return_type_candidate = new Union([new TArray([new Union([new TInt()]), new Union([new TString()])])]);
|
||||
} else {
|
||||
$return_type_candidate = new Union([new TString(), new TNull()]);
|
||||
public static function getClassLikeNames(): array
|
||||
{
|
||||
return [
|
||||
HeaderBag::class,
|
||||
];
|
||||
}
|
||||
|
||||
public static function getMethodReturnType(StatementsSource $source, string $fq_classlike_name, string $method_name_lowercase, array $call_args, Context $context, CodeLocation $code_location, array $template_type_parameters = null, string $called_fq_classlike_name = null, string $called_method_name_lowercase = null)
|
||||
{
|
||||
if (HeaderBag::class !== $fq_classlike_name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ('get' === $method_name_lowercase) {
|
||||
if (3 === count($call_args) && (($arg = $call_args[2]->value) instanceof ConstFetch) && 'false' === $arg->name->parts[0]) {
|
||||
return new Union([new TArray([new Union([new TInt()]), new Union([new TString()])])]);
|
||||
}
|
||||
|
||||
if (isset($call_args[1])) {
|
||||
if ($call_args[1]->value instanceof String_) {
|
||||
return new Union([new TString()]);
|
||||
}
|
||||
}
|
||||
|
||||
return new Union([new TString(), new TNull()]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -15,14 +15,16 @@ Feature: Header get
|
||||
</plugins>
|
||||
</psalm>
|
||||
"""
|
||||
|
||||
Scenario: HeaderBag get method return type should return `?string` (unless third argument is provided for < Sf4.4)
|
||||
Given I have the following code
|
||||
And I have the following code preamble
|
||||
"""
|
||||
<?php
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
"""
|
||||
|
||||
Scenario: HeaderBag get method return type should return `?string` (unless third argument is provided for < Sf4.4)
|
||||
Given I have the following code
|
||||
"""
|
||||
class App
|
||||
{
|
||||
public function index(Request $request): void
|
||||
@ -38,3 +40,19 @@ Feature: Header get
|
||||
"""
|
||||
When I run Psalm
|
||||
Then I see no errors
|
||||
|
||||
Scenario: HeaderBag get method return type should return `string` if default value is provided with string
|
||||
Given I have the following code
|
||||
"""
|
||||
class App
|
||||
{
|
||||
public function index(Request $request): void
|
||||
{
|
||||
$string = $request->headers->get('string', 'string');
|
||||
|
||||
trim($string);
|
||||
}
|
||||
}
|
||||
"""
|
||||
When I run Psalm
|
||||
Then I see no errors
|
||||
|
Loading…
Reference in New Issue
Block a user