Skip to content

Commit 261955f

Browse files
authored
Support for parameterised service class
1 parent 5fe3c26 commit 261955f

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

Diff for: composer.json

+2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
"phpstan/phpstan-phpunit": "^1.0",
2727
"phpstan/phpstan-strict-rules": "^1.0",
2828
"phpunit/phpunit": "^9.5",
29+
"psr/container": "1.0 || 1.1.1",
2930
"symfony/config": "^4.2 || ^5.0",
3031
"symfony/console": "^4.0 || ^5.0",
32+
"symfony/dependency-injection": "^4.0 || ^5.0",
3133
"symfony/form": "^4.0 || ^5.0",
3234
"symfony/framework-bundle": "^4.4 || ^5.0",
3335
"symfony/http-foundation": "^5.1",

Diff for: src/Type/Symfony/ServiceDynamicReturnTypeExtension.php

+30-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
use PHPStan\Reflection\ParametersAcceptorSelector;
99
use PHPStan\ShouldNotHappenException;
1010
use PHPStan\Symfony\Configuration;
11+
use PHPStan\Symfony\ParameterMap;
12+
use PHPStan\Symfony\ServiceDefinition;
1113
use PHPStan\Symfony\ServiceMap;
1214
use PHPStan\Type\Constant\ConstantBooleanType;
1315
use PHPStan\Type\DynamicMethodReturnTypeExtension;
1416
use PHPStan\Type\ObjectType;
1517
use PHPStan\Type\Type;
18+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
1619
use function in_array;
1720

1821
final class ServiceDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
@@ -27,11 +30,20 @@ final class ServiceDynamicReturnTypeExtension implements DynamicMethodReturnType
2730
/** @var ServiceMap */
2831
private $serviceMap;
2932

30-
public function __construct(string $className, Configuration $configuration, ServiceMap $symfonyServiceMap)
33+
/** @var ParameterBag */
34+
private $parameterBag;
35+
36+
public function __construct(
37+
string $className,
38+
Configuration $configuration,
39+
ServiceMap $symfonyServiceMap,
40+
ParameterMap $symfonyParameterMap
41+
)
3142
{
3243
$this->className = $className;
3344
$this->constantHassers = $configuration->hasConstantHassers();
3445
$this->serviceMap = $symfonyServiceMap;
46+
$this->parameterBag = $this->createParameterBag($symfonyParameterMap);
3547
}
3648

3749
public function getClass(): string
@@ -70,7 +82,7 @@ private function getGetTypeFromMethodCall(
7082
if ($serviceId !== null) {
7183
$service = $this->serviceMap->getService($serviceId);
7284
if ($service !== null && (!$service->isSynthetic() || $service->getClass() !== null)) {
73-
return new ObjectType($service->getClass() ?? $serviceId);
85+
return new ObjectType($this->determineServiceClass($service) ?? $serviceId);
7486
}
7587
}
7688

@@ -97,4 +109,20 @@ private function getHasTypeFromMethodCall(
97109
return $returnType;
98110
}
99111

112+
private function determineServiceClass(ServiceDefinition $service): ?string
113+
{
114+
return $this->parameterBag->resolveValue($service->getClass());
115+
}
116+
117+
private function createParameterBag(ParameterMap $symfonyParameterMap): ParameterBag
118+
{
119+
$parameters = [];
120+
121+
foreach ($symfonyParameterMap->getParameters() as $parameterDefinition) {
122+
$parameters[$parameterDefinition->getKey()] = $parameterDefinition->getValue();
123+
}
124+
125+
return new ParameterBag($parameters);
126+
}
127+
100128
}

Diff for: tests/Type/Symfony/container.xml

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
33
<parameters>
4+
<parameter key="app.class">Foo</parameter>
45
<parameter key="app.string">abcdef</parameter>
56
<parameter key="app.int">123</parameter>
67
<parameter key="app.int_as_string" type="string">123</parameter>
@@ -51,6 +52,8 @@
5152

5253
<services>
5354
<service id="foo" class="Foo" public="true"></service>
55+
<service id="parameterised_foo" class="%app.class%"></service>
56+
<service id="parameterised_bar" class="%app.class%\Bar"></service>
5457
<service id="synthetic" class="Synthetic" public="true" synthetic="true" />
5558
</services>
5659
</container>

Diff for: tests/Type/Symfony/data/ExampleAbstractController.php

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ final class ExampleAbstractController extends AbstractController
1313
public function services(): void
1414
{
1515
assertType('Foo', $this->get('foo'));
16+
assertType('Foo', $this->get('parameterised_foo'));
17+
assertType('Foo\Bar', $this->get('parameterised_bar'));
1618
assertType('Synthetic', $this->get('synthetic'));
1719
assertType('object', $this->get('bar'));
1820
assertType('object', $this->get(doFoo()));

Diff for: tests/Type/Symfony/data/ExampleController.php

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ final class ExampleController extends Controller
1313
public function services(): void
1414
{
1515
assertType('Foo', $this->get('foo'));
16+
assertType('Foo', $this->get('parameterised_foo'));
17+
assertType('Foo\Bar', $this->get('parameterised_bar'));
1618
assertType('Synthetic', $this->get('synthetic'));
1719
assertType('object', $this->get('bar'));
1820
assertType('object', $this->get(doFoo()));

0 commit comments

Comments
 (0)