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 5e928d4

Browse files
Add support for env processor
1 parent 1e62ed3 commit 5e928d4

File tree

6 files changed

+125
-1
lines changed

6 files changed

+125
-1
lines changed

‎src/Type/Symfony/ParameterDynamicReturnTypeExtension.php‎

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
use PHPStan\Reflection\MethodReflection;
88
use PHPStan\Reflection\ParametersAcceptorSelector;
99
use PHPStan\ShouldNotHappenException;
10+
use PHPStan\Symfony\ParameterDefinition;
1011
use PHPStan\Symfony\ParameterMap;
1112
use PHPStan\Type\ArrayType;
13+
use PHPStan\Type\BenevolentUnionType;
1214
use PHPStan\Type\BooleanType;
1315
use PHPStan\Type\Constant\ConstantArrayType;
1416
use PHPStan\Type\Constant\ConstantBooleanType;
@@ -21,6 +23,7 @@
2123
use PHPStan\Type\NullType;
2224
use PHPStan\Type\StringType;
2325
use PHPStan\Type\Type;
26+
use PHPStan\Type\TypeCombinator;
2427
use PHPStan\Type\TypeTraverser;
2528
use PHPStan\Type\UnionType;
2629
use function in_array;
@@ -101,13 +104,65 @@ private function getGetTypeFromMethodCall(
101104
if ($parameterKey !== null) {
102105
$parameter = $this->parameterMap->getParameter($parameterKey);
103106
if ($parameter !== null) {
104-
return $this->generalizeType($scope->getTypeFromValue($parameter->getValue()));
107+
return $this->generalizeTypeFromValue($scope, $parameter->getValue());
105108
}
106109
}
107110

108111
return $returnType;
109112
}
110113

114+
private function generalizeTypeFromValue(Scope $scope, $value): Type
115+
{
116+
if (is_array($value) && [] !== $value) {
117+
return $this->generalizeType(
118+
new ArrayType(
119+
TypeCombinator::union(...array_map(function ($item) use ($scope): Type {
120+
return $this->generalizeTypeFromValue($scope, $item);
121+
}, array_keys($value))),
122+
TypeCombinator::union(...array_map(function ($item) use ($scope): Type {
123+
return $this->generalizeTypeFromValue($scope, $item);
124+
}, array_values($value)))
125+
)
126+
);
127+
}
128+
129+
if (
130+
is_string($value)
131+
&& 1 === preg_match('/%env\((.*)\:.*\)%/U', $value, $matches)
132+
&& strlen($matches[0]) === strlen($value)
133+
) {
134+
switch ($matches[1]) {
135+
case 'base64':
136+
case 'file':
137+
case 'resolve':
138+
case 'string':
139+
case 'trim':
140+
return new StringType();
141+
case 'bool':
142+
return new BooleanType();
143+
case 'int':
144+
return new IntegerType();
145+
case 'float':
146+
return new FloatType();
147+
case 'csv':
148+
case 'json':
149+
case 'url':
150+
case 'query_string':
151+
return new ArrayType(new MixedType(), new MixedType());
152+
default:
153+
return new UnionType([
154+
new ArrayType(new MixedType(), new MixedType()),
155+
new BooleanType(),
156+
new FloatType(),
157+
new IntegerType(),
158+
new StringType(),
159+
]);
160+
}
161+
}
162+
163+
return $this->generalizeType($scope->getTypeFromValue($value));
164+
}
165+
111166
private function generalizeType(Type $type): Type
112167
{
113168
return TypeTraverser::map($type, function (Type $type, callable $traverse): Type {

‎tests/Type/Symfony/container.xml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,28 @@
44
<parameter key="app.string">abcdef</parameter>
55
<parameter key="app.int">123</parameter>
66
<parameter key="app.int_as_string" type="string">123</parameter>
7+
<parameter key="app.int_as_processor">%env(int:APP_INT)%</parameter>
78
<parameter key="app.float">123.45</parameter>
89
<parameter key="app.float_as_string" type="string">123.45</parameter>
10+
<parameter key="app.float_as_processor">%env(float:APP_FLOAT)%</parameter>
911
<parameter key="app.boolean">true</parameter>
1012
<parameter key="app.boolean_as_string" type="string">true</parameter>
13+
<parameter key="app.boolean_as_processor">%env(bool:APP_BOOL)%</parameter>
1114
<parameter key="app.list" type="collection">
1215
<parameter>en</parameter>
1316
<parameter>es</parameter>
1417
<parameter>fr</parameter>
1518
</parameter>
19+
<parameter key="app.list_of_int" type="collection">
20+
<parameter>123</parameter>
21+
<parameter>456</parameter>
22+
<parameter>789</parameter>
23+
</parameter>
24+
<parameter key="app.list_of_int_as_processor" type="collection">
25+
<parameter>%env(int:APP_INT)%</parameter>
26+
<parameter>%env(int:APP_INT)%</parameter>
27+
<parameter>%env(int:APP_INT)%</parameter>
28+
</parameter>
1629
<parameter key="app.list_of_list" type="collection">
1730
<parameter type="collection">
1831
<parameter key="name">the name</parameter>

‎tests/Type/Symfony/data/ExampleAbstractController.php‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
3939
assertType("string", $container->getParameter('app.int_as_string'));
4040
assertType("string", $parameterBag->get('app.int_as_string'));
4141
assertType("string", $this->getParameter('app.int_as_string'));
42+
assertType('int', $container->getParameter('app.int_as_processor'));
43+
assertType('int', $parameterBag->get('app.int_as_processor'));
44+
assertType('int', $this->getParameter('app.int_as_processor'));
4245
assertType('float', $container->getParameter('app.float'));
4346
assertType('float', $parameterBag->get('app.float'));
4447
assertType('float', $this->getParameter('app.float'));
@@ -54,6 +57,12 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
5457
assertType("array<int, string>", $container->getParameter('app.list'));
5558
assertType("array<int, string>", $parameterBag->get('app.list'));
5659
assertType("array<int, string>", $this->getParameter('app.list'));
60+
assertType("array<int, int>", $container->getParameter('app.list_of_int'));
61+
assertType("array<int, int>", $parameterBag->get('app.list_of_int'));
62+
assertType("array<int, int>", $this->getParameter('app.list_of_int'));
63+
assertType("array<int, int>", $container->getParameter('app.list_of_int_as_processor'));
64+
assertType("array<int, int>", $parameterBag->get('app.list_of_int_as_processor'));
65+
assertType("array<int, int>", $this->getParameter('app.list_of_int_as_processor'));
5766
assertType("array<int, array<string, string>>", $container->getParameter('app.list_of_list'));
5867
assertType("array<int, array<string, string>>", $parameterBag->get('app.list_of_list'));
5968
assertType("array<int, array<string, string>>", $this->getParameter('app.list_of_list'));
@@ -77,6 +86,8 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
7786
assertType('true', $parameterBag->has('app.int'));
7887
assertType('true', $container->hasParameter('app.int_as_string'));
7988
assertType('true', $parameterBag->has('app.int_as_string'));
89+
assertType('true', $container->hasParameter('app.int_as_processor'));
90+
assertType('true', $parameterBag->has('app.int_as_processor'));
8091
assertType('true', $container->hasParameter('app.float'));
8192
assertType('true', $parameterBag->has('app.float'));
8293
assertType('true', $container->hasParameter('app.float_as_string'));

‎tests/Type/Symfony/data/ExampleAbstractControllerWithoutContainer.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,27 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
3838
assertType('array|bool|float|int|string|null', $container->getParameter('app.int_as_string'));
3939
assertType('array|bool|float|int|string|null', $parameterBag->get('app.int_as_string'));
4040
assertType('array|bool|float|int|string|null', $this->getParameter('app.int_as_string'));
41+
assertType('array|bool|float|int|string|null', $container->getParameter('app.int_as_processor'));
42+
assertType('array|bool|float|int|string|null', $parameterBag->get('app.int_as_processor'));
43+
assertType('array|bool|float|int|string|null', $this->getParameter('app.int_as_processor'));
4144
assertType('array|bool|float|int|string|null', $container->getParameter('app.float'));
4245
assertType('array|bool|float|int|string|null', $parameterBag->get('app.float'));
4346
assertType('array|bool|float|int|string|null', $this->getParameter('app.float'));
4447
assertType('array|bool|float|int|string|null', $container->getParameter('app.float_as_string'));
4548
assertType('array|bool|float|int|string|null', $parameterBag->get('app.float_as_string'));
4649
assertType('array|bool|float|int|string|null', $this->getParameter('app.float_as_string'));
50+
assertType('array|bool|float|int|string|null', $container->getParameter('app.float_as_processor'));
51+
assertType('array|bool|float|int|string|null', $parameterBag->get('app.float_as_processor'));
52+
assertType('array|bool|float|int|string|null', $this->getParameter('app.float_as_processor'));
4753
assertType('array|bool|float|int|string|null', $container->getParameter('app.boolean'));
4854
assertType('array|bool|float|int|string|null', $parameterBag->get('app.boolean'));
4955
assertType('array|bool|float|int|string|null', $this->getParameter('app.boolean'));
5056
assertType('array|bool|float|int|string|null', $container->getParameter('app.boolean_as_string'));
5157
assertType('array|bool|float|int|string|null', $parameterBag->get('app.boolean_as_string'));
5258
assertType('array|bool|float|int|string|null', $this->getParameter('app.boolean_as_string'));
59+
assertType('array|bool|float|int|string|null', $container->getParameter('app.boolean_as_processor'));
60+
assertType('array|bool|float|int|string|null', $parameterBag->get('app.boolean_as_processor'));
61+
assertType('array|bool|float|int|string|null', $this->getParameter('app.boolean_as_processor'));
5362
assertType('array|bool|float|int|string|null', $container->getParameter('app.list'));
5463
assertType('array|bool|float|int|string|null', $parameterBag->get('app.list'));
5564
assertType('array|bool|float|int|string|null', $this->getParameter('app.list'));
@@ -74,14 +83,20 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
7483
assertType('bool', $parameterBag->has('app.int'));
7584
assertType('bool', $container->hasParameter('app.int_as_string'));
7685
assertType('bool', $parameterBag->has('app.int_as_string'));
86+
assertType('bool', $container->hasParameter('app.int_as_processor'));
87+
assertType('bool', $parameterBag->has('app.int_as_processor'));
7788
assertType('bool', $container->hasParameter('app.float'));
7889
assertType('bool', $parameterBag->has('app.float'));
7990
assertType('bool', $container->hasParameter('app.float_as_string'));
8091
assertType('bool', $parameterBag->has('app.float_as_string'));
92+
assertType('bool', $container->hasParameter('app.float_as_processor'));
93+
assertType('bool', $parameterBag->has('app.float_as_processor'));
8194
assertType('bool', $container->hasParameter('app.boolean'));
8295
assertType('bool', $parameterBag->has('app.boolean'));
8396
assertType('bool', $container->hasParameter('app.boolean_as_string'));
8497
assertType('bool', $parameterBag->has('app.boolean_as_string'));
98+
assertType('bool', $container->hasParameter('app.boolean_as_processor'));
99+
assertType('bool', $parameterBag->has('app.boolean_as_processor'));
85100
assertType('bool', $container->hasParameter('app.list'));
86101
assertType('bool', $parameterBag->has('app.list'));
87102
assertType('bool', $container->hasParameter('app.list_of_list'));

‎tests/Type/Symfony/data/ExampleController.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,27 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
3939
assertType("string", $container->getParameter('app.int_as_string'));
4040
assertType("string", $parameterBag->get('app.int_as_string'));
4141
assertType("string", $this->getParameter('app.int_as_string'));
42+
assertType('int', $container->getParameter('app.int_as_processor'));
43+
assertType('int', $parameterBag->get('app.int_as_processor'));
44+
assertType('int', $this->getParameter('app.int_as_processor'));
4245
assertType('float', $container->getParameter('app.float'));
4346
assertType('float', $parameterBag->get('app.float'));
4447
assertType('float', $this->getParameter('app.float'));
4548
assertType("string", $container->getParameter('app.float_as_string'));
4649
assertType("string", $parameterBag->get('app.float_as_string'));
4750
assertType("string", $this->getParameter('app.float_as_string'));
51+
assertType('float', $container->getParameter('app.float_as_processor'));
52+
assertType('float', $parameterBag->get('app.float_as_processor'));
53+
assertType('float', $this->getParameter('app.float_as_processor'));
4854
assertType('bool', $container->getParameter('app.boolean'));
4955
assertType('bool', $parameterBag->get('app.boolean'));
5056
assertType('bool', $this->getParameter('app.boolean'));
5157
assertType("string", $container->getParameter('app.boolean_as_string'));
5258
assertType("string", $parameterBag->get('app.boolean_as_string'));
5359
assertType("string", $this->getParameter('app.boolean_as_string'));
60+
assertType('bool', $container->getParameter('app.boolean_as_processor'));
61+
assertType('bool', $parameterBag->get('app.boolean_as_processor'));
62+
assertType('bool', $this->getParameter('app.boolean_as_processor'));
5463
assertType("array<int, string>", $container->getParameter('app.list'));
5564
assertType("array<int, string>", $parameterBag->get('app.list'));
5665
assertType("array<int, string>", $this->getParameter('app.list'));
@@ -75,14 +84,20 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
7584
assertType('true', $parameterBag->has('app.int'));
7685
assertType('true', $container->hasParameter('app.int_as_string'));
7786
assertType('true', $parameterBag->has('app.int_as_string'));
87+
assertType('true', $container->hasParameter('app.int_as_processor'));
88+
assertType('true', $parameterBag->has('app.int_as_processor'));
7889
assertType('true', $container->hasParameter('app.float'));
7990
assertType('true', $parameterBag->has('app.float'));
8091
assertType('true', $container->hasParameter('app.float_as_string'));
8192
assertType('true', $parameterBag->has('app.float_as_string'));
93+
assertType('true', $container->hasParameter('app.float_as_processor'));
94+
assertType('true', $parameterBag->has('app.float_as_processor'));
8295
assertType('true', $container->hasParameter('app.boolean'));
8396
assertType('true', $parameterBag->has('app.boolean'));
8497
assertType('true', $container->hasParameter('app.boolean_as_string'));
8598
assertType('true', $parameterBag->has('app.boolean_as_string'));
99+
assertType('true', $container->hasParameter('app.boolean_as_processor'));
100+
assertType('true', $parameterBag->has('app.boolean_as_processor'));
86101
assertType('true', $container->hasParameter('app.list'));
87102
assertType('true', $parameterBag->has('app.list'));
88103
assertType('true', $container->hasParameter('app.list_of_list'));

‎tests/Type/Symfony/data/ExampleControllerWithoutContainer.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,27 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
3838
assertType('array|bool|float|int|string|null', $container->getParameter('app.int_as_string'));
3939
assertType('array|bool|float|int|string|null', $parameterBag->get('app.int_as_string'));
4040
assertType('array|bool|float|int|string|null', $this->getParameter('app.int_as_string'));
41+
assertType('array|bool|float|int|string|null', $container->getParameter('app.int_as_processor'));
42+
assertType('array|bool|float|int|string|null', $parameterBag->get('app.int_as_processor'));
43+
assertType('array|bool|float|int|string|null', $this->getParameter('app.int_as_processor'));
4144
assertType('array|bool|float|int|string|null', $container->getParameter('app.float'));
4245
assertType('array|bool|float|int|string|null', $parameterBag->get('app.float'));
4346
assertType('array|bool|float|int|string|null', $this->getParameter('app.float'));
4447
assertType('array|bool|float|int|string|null', $container->getParameter('app.float_as_string'));
4548
assertType('array|bool|float|int|string|null', $parameterBag->get('app.float_as_string'));
4649
assertType('array|bool|float|int|string|null', $this->getParameter('app.float_as_string'));
50+
assertType('array|bool|float|int|string|null', $container->getParameter('app.float_as_processor'));
51+
assertType('array|bool|float|int|string|null', $parameterBag->get('app.float_as_processor'));
52+
assertType('array|bool|float|int|string|null', $this->getParameter('app.float_as_processor'));
4753
assertType('array|bool|float|int|string|null', $container->getParameter('app.boolean'));
4854
assertType('array|bool|float|int|string|null', $parameterBag->get('app.boolean'));
4955
assertType('array|bool|float|int|string|null', $this->getParameter('app.boolean'));
5056
assertType('array|bool|float|int|string|null', $container->getParameter('app.boolean_as_string'));
5157
assertType('array|bool|float|int|string|null', $parameterBag->get('app.boolean_as_string'));
5258
assertType('array|bool|float|int|string|null', $this->getParameter('app.boolean_as_string'));
59+
assertType('array|bool|float|int|string|null', $container->getParameter('app.boolean_as_processor'));
60+
assertType('array|bool|float|int|string|null', $parameterBag->get('app.boolean_as_processor'));
61+
assertType('array|bool|float|int|string|null', $this->getParameter('app.boolean_as_processor'));
5362
assertType('array|bool|float|int|string|null', $container->getParameter('app.list'));
5463
assertType('array|bool|float|int|string|null', $parameterBag->get('app.list'));
5564
assertType('array|bool|float|int|string|null', $this->getParameter('app.list'));
@@ -74,14 +83,20 @@ public function parameters(ContainerInterface $container, ParameterBagInterface
7483
assertType('bool', $parameterBag->has('app.int'));
7584
assertType('bool', $container->hasParameter('app.int_as_string'));
7685
assertType('bool', $parameterBag->has('app.int_as_string'));
86+
assertType('bool', $container->hasParameter('app.int_as_processor'));
87+
assertType('bool', $parameterBag->has('app.int_as_processor'));
7788
assertType('bool', $container->hasParameter('app.float'));
7889
assertType('bool', $parameterBag->has('app.float'));
7990
assertType('bool', $container->hasParameter('app.float_as_string'));
8091
assertType('bool', $parameterBag->has('app.float_as_string'));
92+
assertType('bool', $container->hasParameter('app.float_as_processor'));
93+
assertType('bool', $parameterBag->has('app.float_as_processor'));
8194
assertType('bool', $container->hasParameter('app.boolean'));
8295
assertType('bool', $parameterBag->has('app.boolean'));
8396
assertType('bool', $container->hasParameter('app.boolean_as_string'));
8497
assertType('bool', $parameterBag->has('app.boolean_as_string'));
98+
assertType('bool', $container->hasParameter('app.boolean_as_processor'));
99+
assertType('bool', $parameterBag->has('app.boolean_as_processor'));
85100
assertType('bool', $container->hasParameter('app.list'));
86101
assertType('bool', $parameterBag->has('app.list'));
87102
assertType('bool', $container->hasParameter('app.list_of_list'));

0 commit comments

Comments
(0)

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