Skip to content

Commit 534b45d

Browse files
committed
Support aliases on #[AutowireLocator] attribute in ContainerInterfacePrivateServiceRule
We now create an AutowireLocator instance and check if the service exists there. This also removes a lot of nested foreach loops and thus decreases the complexity of the isAutowireLocatorService method a lot. https://symfony.com/blog/new-in-symfony-6-4-autowirelocator-and-autowireiterator-attributes
1 parent b49fdc7 commit 534b45d

File tree

1 file changed

+12
-38
lines changed

1 file changed

+12
-38
lines changed

src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php

+12-38
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010
use PHPStan\Reflection\ClassReflection;
1111
use PHPStan\Rules\Rule;
1212
use PHPStan\Rules\RuleErrorBuilder;
13-
use PHPStan\Symfony\ServiceDefinition;
1413
use PHPStan\Symfony\ServiceMap;
1514
use PHPStan\TrinaryLogic;
1615
use PHPStan\Type\ObjectType;
1716
use PHPStan\Type\Type;
1817
use Symfony\Component\DependencyInjection\Attribute\AutowireLocator;
1918
use function class_exists;
20-
use function get_class;
2119
use function sprintf;
2220

2321
/**
@@ -77,20 +75,16 @@ public function processNode(Node $node, Scope $scope): array
7775
return [];
7876
}
7977

80-
$service = $this->serviceMap->getService($serviceId);
81-
if (!$service instanceof ServiceDefinition) {
82-
return [];
83-
}
84-
8578
$isContainerInterfaceType = $isContainerType->yes() || $isPsrContainerType->yes();
8679
if (
8780
$isContainerInterfaceType &&
88-
$this->isAutowireLocator($node, $scope, $service)
81+
$this->isAutowireLocator($node, $scope, $serviceId)
8982
) {
9083
return [];
9184
}
9285

93-
if (!$service->isPublic()) {
86+
$service = $this->serviceMap->getService($serviceId);
87+
if ($service !== null && !$service->isPublic()) {
9488
return [
9589
RuleErrorBuilder::message(sprintf('Service "%s" is private.', $serviceId))
9690
->identifier('symfonyContainer.privateService')
@@ -113,7 +107,7 @@ private function isServiceSubscriber(Type $containerType, Scope $scope): Trinary
113107
return $isContainerServiceSubscriber->or($serviceSubscriberInterfaceType->isSuperTypeOf($containedClassType));
114108
}
115109

116-
private function isAutowireLocator(Node $node, Scope $scope, ServiceDefinition $service): bool
110+
private function isAutowireLocator(Node $node, Scope $scope, string $serviceId): bool
117111
{
118112
if (!class_exists('Symfony\\Component\\DependencyInjection\\Attribute\\AutowireLocator')) {
119113
return false;
@@ -149,41 +143,21 @@ private function isAutowireLocator(Node $node, Scope $scope, ServiceDefinition $
149143
$classPropertyReflection = $containerInterfacePropertyReflection->getNativeReflection();
150144
$autowireLocatorAttributes = $classPropertyReflection->getAttributes(AutowireLocator::class);
151145

152-
return $this->isAutowireLocatorService($autowireLocatorAttributes, $service);
146+
return $this->isAutowireLocatorService($autowireLocatorAttributes, $serviceId);
153147
}
154148

155149
/**
156150
* @param array<int, FakeReflectionAttribute|ReflectionAttribute> $autowireLocatorAttributes
157151
*/
158-
private function isAutowireLocatorService(array $autowireLocatorAttributes, ServiceDefinition $service): bool
152+
private function isAutowireLocatorService(array $autowireLocatorAttributes, string $serviceId): bool
159153
{
160154
foreach ($autowireLocatorAttributes as $autowireLocatorAttribute) {
161-
foreach ($autowireLocatorAttribute->getArgumentsExpressions() as $autowireLocatorServices) {
162-
if (!$autowireLocatorServices instanceof Node\Expr\Array_) {
163-
continue;
164-
}
165-
166-
foreach ($autowireLocatorServices->items as $autowireLocatorServiceNode) {
167-
/** @var Node\Expr\ArrayItem $autowireLocatorServiceNode */
168-
$autowireLocatorServiceExpr = $autowireLocatorServiceNode->value;
169-
170-
switch (get_class($autowireLocatorServiceExpr)) {
171-
case Node\Scalar\String_::class:
172-
$autowireLocatorServiceClass = $autowireLocatorServiceExpr->value;
173-
break;
174-
case Node\Expr\ClassConstFetch::class:
175-
$autowireLocatorServiceClass = $autowireLocatorServiceExpr->class instanceof Node\Name
176-
? $autowireLocatorServiceExpr->class->toString()
177-
: null;
178-
break;
179-
default:
180-
$autowireLocatorServiceClass = null;
181-
}
182-
183-
if ($service->getId() === $autowireLocatorServiceClass) {
184-
return true;
185-
}
186-
}
155+
/** @var AutowireLocator $autowireLocatorInstance */
156+
$autowireLocator = $autowireLocatorAttribute->newInstance();
157+
$autowireLocatorServices = $autowireLocator->value->getValues();
158+
159+
if (array_key_exists($serviceId, $autowireLocatorServices)) {
160+
return true;
187161
}
188162
}
189163

0 commit comments

Comments
 (0)