Skip to content

Commit e12afee

Browse files
Add support for env processor
1 parent 1e62ed3 commit e12afee

6 files changed

+123
-1
lines changed

src/Type/Symfony/ParameterDynamicReturnTypeExtension.php

+54-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PHPStan\Type\NullType;
2222
use PHPStan\Type\StringType;
2323
use PHPStan\Type\Type;
24+
use PHPStan\Type\TypeCombinator;
2425
use PHPStan\Type\TypeTraverser;
2526
use PHPStan\Type\UnionType;
2627
use function in_array;
@@ -101,13 +102,65 @@ private function getGetTypeFromMethodCall(
101102
if ($parameterKey !== null) {
102103
$parameter = $this->parameterMap->getParameter($parameterKey);
103104
if ($parameter !== null) {
104-
return $this->generalizeType($scope->getTypeFromValue($parameter->getValue()));
105+
return $this->generalizeTypeFromValue($scope, $parameter->getValue());
105106
}
106107
}
107108

108109
return $returnType;
109110
}
110111

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

tests/Type/Symfony/container.xml

+13
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

+11
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

+15
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

+15
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

+15
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)