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 51488c9

Browse files
Add support for env processor
1 parent 173610b commit 51488c9

File tree

6 files changed

+118
-2
lines changed

6 files changed

+118
-2
lines changed

‎src/Type/Symfony/ParameterDynamicReturnTypeExtension.php

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpParser\Node\Expr\MethodCall;
66
use PHPStan\Analyser\Scope;
7+
use PHPStan\PhpDoc\TypeStringResolver;
78
use PHPStan\Reflection\MethodReflection;
89
use PHPStan\Reflection\ParametersAcceptorSelector;
910
use PHPStan\ShouldNotHappenException;
@@ -22,8 +23,10 @@
2223
use PHPStan\Type\NullType;
2324
use PHPStan\Type\StringType;
2425
use PHPStan\Type\Type;
26+
use PHPStan\Type\TypeCombinator;
2527
use PHPStan\Type\TypeTraverser;
2628
use PHPStan\Type\UnionType;
29+
use Symfony\Component\DependencyInjection\EnvVarProcessor;
2730
use function in_array;
2831

2932
final class ParameterDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
@@ -44,13 +47,24 @@ final class ParameterDynamicReturnTypeExtension implements DynamicMethodReturnTy
4447
/** @var \PHPStan\Symfony\ParameterMap */
4548
private $parameterMap;
4649

47-
public function __construct(string $className, ?string $methodGet, ?string $methodHas, Configuration $configuration, ParameterMap $symfonyParameterMap)
50+
/** @var \PHPStan\PhpDoc\TypeStringResolver */
51+
private $typeStringResolver;
52+
53+
public function __construct(
54+
string $className,
55+
?string $methodGet,
56+
?string $methodHas,
57+
Configuration $configuration,
58+
ParameterMap $symfonyParameterMap,
59+
TypeStringResolver $typeStringResolver
60+
)
4861
{
4962
$this->className = $className;
5063
$this->methodGet = $methodGet;
5164
$this->methodHas = $methodHas;
5265
$this->constantHassers = $configuration->hasConstantHassers();
5366
$this->parameterMap = $symfonyParameterMap;
67+
$this->typeStringResolver = $typeStringResolver;
5468
}
5569

5670
public function getClass(): string
@@ -102,13 +116,46 @@ private function getGetTypeFromMethodCall(
102116
if ($parameterKey !== null) {
103117
$parameter = $this->parameterMap->getParameter($parameterKey);
104118
if ($parameter !== null) {
105-
return $this->generalizeType($scope->getTypeFromValue($parameter->getValue()));
119+
return $this->generalizeTypeFromValue($scope, $parameter->getValue());
106120
}
107121
}
108122

109123
return $returnType;
110124
}
111125

126+
/**
127+
* @param Scope $scope
128+
* @param array<mixed>|bool|float|int|string $value
129+
*/
130+
private function generalizeTypeFromValue(Scope $scope, $value): Type
131+
{
132+
if (is_array($value) && $value !== []) {
133+
return $this->generalizeType(
134+
new ArrayType(
135+
TypeCombinator::union(...array_map(function ($item) use ($scope): Type {
136+
return $this->generalizeTypeFromValue($scope, $item);
137+
}, array_keys($value))),
138+
TypeCombinator::union(...array_map(function ($item) use ($scope): Type {
139+
return $this->generalizeTypeFromValue($scope, $item);
140+
}, array_values($value)))
141+
)
142+
);
143+
}
144+
145+
if (
146+
class_exists(EnvVarProcessor::class)
147+
&& is_string($value)
148+
&& preg_match('/%env\((.*)\:.*\)%/U', $value, $matches) === 1
149+
&& strlen($matches[0]) === strlen($value)
150+
) {
151+
$providedTypes = EnvVarProcessor::getProvidedTypes();
152+
153+
return $this->typeStringResolver->resolve($providedTypes[$matches[1]] ?? 'bool|int|float|string|array');
154+
}
155+
156+
return $this->generalizeType($scope->getTypeFromValue($value));
157+
}
158+
112159
private function generalizeType(Type $type): Type
113160
{
114161
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 によって変換されたページ (->オリジナル) /