Skip to content

Commit 8a062af

Browse files
leongersenondrejmirtes
authored andcommitted
Add support for InputBag::all (Symfony 5+)
1 parent 3a9a45c commit 8a062af

File tree

5 files changed

+45
-7
lines changed

5 files changed

+45
-7
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ This extension provides following features:
1313
* Provides correct return type for `Request::getContent()` method based on the `$asResource` parameter.
1414
* Provides correct return type for `HeaderBag::get()` method based on the `$first` parameter.
1515
* Provides correct return type for `Envelope::all()` method based on the `$stampFqcn` parameter.
16+
* Provides correct return type for `InputBag::get()` method based on the `$default` parameter.
17+
* Provides correct return type for `InputBag::all()` method based on the `$key` parameter.
1618
* Provides correct return types for `TreeBuilder` and `NodeDefinition` objects.
1719
* Notifies you when you try to get an unregistered service from the container.
1820
* Notifies you when you try to get a private service from the container.

phpstan.neon

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ parameters:
1313
- tests/*/console_application_loader.php
1414
- tests/*/envelope_all.php
1515
- tests/*/header_bag_get.php
16-
- tests/*/input_bag_get.php
16+
- tests/*/input_bag.php
1717
- tests/*/kernel_interface.php
1818
- tests/*/request_get_content.php
1919
- tests/*/request_get_session.php

src/Type/Symfony/InputBagDynamicReturnTypeExtension.php

+33-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\MethodReflection;
88
use PHPStan\Reflection\ParametersAcceptorSelector;
9+
use PHPStan\ShouldNotHappenException;
10+
use PHPStan\Type\ArrayType;
911
use PHPStan\Type\DynamicMethodReturnTypeExtension;
12+
use PHPStan\Type\MixedType;
1013
use PHPStan\Type\NullType;
1114
use PHPStan\Type\StringType;
1215
use PHPStan\Type\Type;
16+
use PHPStan\Type\UnionType;
1317

1418
final class InputBagDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
1519
{
@@ -21,14 +25,31 @@ public function getClass(): string
2125

2226
public function isMethodSupported(MethodReflection $methodReflection): bool
2327
{
24-
return $methodReflection->getName() === 'get';
28+
return in_array($methodReflection->getName(), ['get', 'all'], true);
2529
}
2630

2731
public function getTypeFromMethodCall(
2832
MethodReflection $methodReflection,
2933
MethodCall $methodCall,
3034
Scope $scope
3135
): Type
36+
{
37+
if ($methodReflection->getName() === 'get') {
38+
return $this->getGetTypeFromMethodCall($methodReflection, $methodCall, $scope);
39+
}
40+
41+
if ($methodReflection->getName() === 'all') {
42+
return $this->getAllTypeFromMethodCall($methodCall);
43+
}
44+
45+
throw new ShouldNotHappenException();
46+
}
47+
48+
private function getGetTypeFromMethodCall(
49+
MethodReflection $methodReflection,
50+
MethodCall $methodCall,
51+
Scope $scope
52+
): Type
3253
{
3354
if (isset($methodCall->args[1])) {
3455
$argType = $scope->getType($methodCall->args[1]->value);
@@ -43,4 +64,15 @@ public function getTypeFromMethodCall(
4364
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
4465
}
4566

67+
private function getAllTypeFromMethodCall(
68+
MethodCall $methodCall
69+
): Type
70+
{
71+
if (isset($methodCall->args[0])) {
72+
return new ArrayType(new MixedType(), new StringType());
73+
}
74+
75+
return new ArrayType(new StringType(), new UnionType([new StringType(), new ArrayType(new MixedType(), new StringType())]));
76+
}
77+
4678
}

tests/Type/Symfony/InputBagDynamicReturnTypeExtensionTest.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ final class InputBagDynamicReturnTypeExtensionTest extends ExtensionTestCase
88
{
99

1010
/**
11-
* @dataProvider getProvider
11+
* @dataProvider inputBagProvider
1212
*/
13-
public function testGet(string $expression, string $type): void
13+
public function testInputBag(string $expression, string $type): void
1414
{
1515
if (!class_exists('Symfony\\Component\\HttpFoundation\\InputBag')) {
1616
self::markTestSkipped('The test needs Symfony\Component\HttpFoundation\InputBag class.');
1717
}
1818

1919
$this->processFile(
20-
__DIR__ . '/input_bag_get.php',
20+
__DIR__ . '/input_bag.php',
2121
$expression,
2222
$type,
2323
[new InputBagDynamicReturnTypeExtension()]
@@ -27,12 +27,14 @@ public function testGet(string $expression, string $type): void
2727
/**
2828
* @return \Iterator<array{string, string}>
2929
*/
30-
public function getProvider(): Iterator
30+
public function inputBagProvider(): Iterator
3131
{
3232
yield ['$test1', 'string|null'];
3333
yield ['$test2', 'string|null'];
3434
yield ['$test3', 'string'];
3535
yield ['$test4', 'string'];
36+
yield ['$test5', 'array<string, array<string>|string>'];
37+
yield ['$test6', 'array<string>'];
3638
}
3739

3840
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
<?php declare(strict_types = 1);
22

3-
$bag = new \Symfony\Component\HttpFoundation\InputBag(['foo' => 'bar']);
3+
$bag = new \Symfony\Component\HttpFoundation\InputBag(['foo' => 'bar', 'bar' => ['x']]);
44

55
$test1 = $bag->get('foo');
66
$test2 = $bag->get('foo', null);
77
$test3 = $bag->get('foo', '');
88
$test4 = $bag->get('foo', 'baz');
9+
$test5 = $bag->all();
10+
$test6 = $bag->all('bar');
911

1012
die;

0 commit comments

Comments
 (0)