diff --git a/src/Handler/ContainerHandler.php b/src/Handler/ContainerHandler.php index 4e498f6..573b4fe 100644 --- a/src/Handler/ContainerHandler.php +++ b/src/Handler/ContainerHandler.php @@ -118,7 +118,12 @@ class ContainerHandler implements AfterMethodCallAnalysisInterface, AfterClassLi } if (!$service->isPublic()) { - $isTestContainer = $context->parent && ('Symfony\Bundle\FrameworkBundle\Test\KernelTestCase' === $context->parent || is_subclass_of($context->parent, 'Symfony\Bundle\FrameworkBundle\Test\KernelTestCase')); + /** @var class-string $kernelTestCaseClass */ + $kernelTestCaseClass = 'Symfony\Bundle\FrameworkBundle\Test\KernelTestCase'; + $isTestContainer = $context->parent && + ($kernelTestCaseClass === $context->parent + || is_subclass_of($context->parent, $kernelTestCaseClass) + ); if (!$isTestContainer) { IssueBuffer::accepts( new PrivateService($serviceId, new CodeLocation($statements_source, $expr->args[0]->value)), diff --git a/src/Stubs/5/Component/HttpFoundation/InputBag.stubphp b/src/Stubs/5/Component/HttpFoundation/InputBag.stubphp index 28c8968..48a25fa 100644 --- a/src/Stubs/5/Component/HttpFoundation/InputBag.stubphp +++ b/src/Stubs/5/Component/HttpFoundation/InputBag.stubphp @@ -2,14 +2,17 @@ namespace Symfony\Component\HttpFoundation; +/** + * @template T of string|int|float|bool + */ final class InputBag extends ParameterBag { /** * Returns a string input value by name. * - * @template D of string|int|float|bool|null + * @template D of T|null * @psalm-param D $default - * @psalm-return string|int|float|bool|D + * @psalm-return D|T * @psalm-taint-source input */ public function get(string $key, $default = null) {} diff --git a/src/Stubs/5/Component/HttpFoundation/Request.stubphp b/src/Stubs/5/Component/HttpFoundation/Request.stubphp index ae16255..edda81c 100644 --- a/src/Stubs/5/Component/HttpFoundation/Request.stubphp +++ b/src/Stubs/5/Component/HttpFoundation/Request.stubphp @@ -8,4 +8,14 @@ class Request * @psalm-var InputBag */ public $request; + + /** + * @psalm-var InputBag + */ + public $query; + + /** + * @psalm-var InputBag + */ + public $cookies; } diff --git a/tests/acceptance/acceptance/InputBag.feature b/tests/acceptance/acceptance/InputBag.feature index 53baf9d..a69feb6 100644 --- a/tests/acceptance/acceptance/InputBag.feature +++ b/tests/acceptance/acceptance/InputBag.feature @@ -11,7 +11,24 @@ Feature: InputBag get return type use Symfony\Component\HttpFoundation\Request; """ - Scenario Outline: Return type is not null if default argument is string. + Scenario: Return type is scalar for request property if default argument is string. + Given I have the following code + """ + class App + { + public function __invoke(Request $request): void + { + $string = $request->request->get('foo', 'bar'); + trim($string); + } + } + """ + When I run Psalm + Then I see these errors + | Type | Message | + | InvalidScalarArgument | Argument 1 of trim expects string, scalar provided | + + Scenario Outline: Return type is string if default argument is string. Given I have the following code """ class App @@ -24,14 +41,29 @@ Feature: InputBag get return type } """ When I run Psalm - Then I see these errors - | Type | Message | - | InvalidScalarArgument | Argument 1 of trim expects string, scalar provided | + Then I see no errors Examples: | property | | query | | cookies | - | request | + + Scenario: Return type is nullable for request property if default argument is not provided. + Given I have the following code + """ + class App + { + public function __invoke(Request $request): void + { + $nullableString = $request->request->get('foo'); + trim($nullableString); + } + } + """ + When I run Psalm + Then I see these errors + | Type | Message | + | InvalidScalarArgument | Argument 1 of trim expects string, null\|scalar provided | + And I see no other errors Scenario Outline: Return type is nullable if default argument is not provided. Given I have the following code @@ -47,11 +79,10 @@ Feature: InputBag get return type """ When I run Psalm Then I see these errors - | Type | Message | - | InvalidScalarArgument | Argument 1 of trim expects string, null\|scalar provided | + | Type | Message | + | PossiblyNullArgument | Argument 1 of trim cannot be null, possibly null value provided | And I see no other errors Examples: | property | | query | | cookies | - | request |