Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 11221af

Browse files
Add dynamic return type to ResponseHeaderBag::getCookies
1 parent 784e7a0 commit 11221af

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

‎extension.neon‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,8 @@ services:
273273
-
274274
factory: PHPStan\Type\Symfony\CommandGetHelperDynamicReturnTypeExtension
275275
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
276+
277+
# ResponseHeaderBag::getCookies() return type
278+
-
279+
factory: PHPStan\Type\Symfony\ResponseHeaderBagDynamicReturnTypeExtension
280+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Type\Symfony;
4+
5+
use PhpParser\Node\Expr\ClassConstFetch;
6+
use PhpParser\Node\Expr\MethodCall;
7+
use PhpParser\Node\Identifier;
8+
use PhpParser\Node\Name;
9+
use PHPStan\Analyser\Scope;
10+
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Type\ArrayType;
12+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
13+
use PHPStan\Type\IntegerType;
14+
use PHPStan\Type\ObjectType;
15+
use PHPStan\Type\StringType;
16+
use PHPStan\Type\Type;
17+
use Symfony\Component\HttpFoundation\Cookie;
18+
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
19+
20+
final class ResponseHeaderBagDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
21+
{
22+
23+
public function getClass(): string
24+
{
25+
return ResponseHeaderBag::class;
26+
}
27+
28+
public function isMethodSupported(MethodReflection $methodReflection): bool
29+
{
30+
return $methodReflection->getName() === 'getCookies';
31+
}
32+
33+
public function getTypeFromMethodCall(
34+
MethodReflection $methodReflection,
35+
MethodCall $methodCall,
36+
Scope $scope
37+
): Type
38+
{
39+
if (isset($methodCall->getArgs()[0])) {
40+
$node = $methodCall->getArgs()[0]->value;
41+
42+
if (
43+
$node instanceof ClassConstFetch &&
44+
$node->class instanceof Name &&
45+
$node->name instanceof Identifier &&
46+
$node->class->toString() === ResponseHeaderBag::class &&
47+
$node->name->name === 'COOKIES_ARRAY'
48+
) {
49+
return new ArrayType(
50+
new StringType(),
51+
new ArrayType(
52+
new StringType(),
53+
new ArrayType(
54+
new StringType(),
55+
new ObjectType(Cookie::class)
56+
)
57+
)
58+
);
59+
}
60+
}
61+
62+
return new ArrayType(new IntegerType(), new ObjectType(Cookie::class));
63+
}
64+
65+
}

‎tests/Type/Symfony/ExtensionTest.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public function dataFileAsserts(): iterable
1414
{
1515
yield from $this->gatherAssertTypes(__DIR__ . '/data/envelope_all.php');
1616
yield from $this->gatherAssertTypes(__DIR__ . '/data/header_bag_get.php');
17+
yield from $this->gatherAssertTypes(__DIR__ . '/data/response_header_bag_get_cookies.php');
1718

1819
if (class_exists('Symfony\Component\HttpFoundation\InputBag')) {
1920
yield from $this->gatherAssertTypes(__DIR__ . '/data/input_bag.php');
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php declare(strict_types = 1);
2+
3+
use Symfony\Component\HttpFoundation\Cookie;
4+
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
5+
use function PHPStan\Testing\assertType;
6+
7+
$headerBag = new ResponseHeaderBag();
8+
$headerBag->setCookie(Cookie::create('cookie_name'));
9+
10+
assertType('array<int, Symfony\Component\HttpFoundation\Cookie>', $headerBag->getCookies());
11+
assertType('array<int, Symfony\Component\HttpFoundation\Cookie>', $headerBag->getCookies(ResponseHeaderBag::COOKIES_FLAT));
12+
assertType('array<string, array<string, array<string, Symfony\Component\HttpFoundation\Cookie>>>', $headerBag->getCookies(ResponseHeaderBag::COOKIES_ARRAY));

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /