Skip to content

Commit fe2a56d

Browse files
committed
Add AutowireLoader support for ContainerInterfaceUnknownServiceRule
1 parent 7480e9d commit fe2a56d

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

Diff for: src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php

+47-7
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
use PhpParser\Node\Expr\MethodCall;
77
use PhpParser\PrettyPrinter\Standard;
88
use PHPStan\Analyser\Scope;
9+
use PHPStan\Rules\IdentifierRuleError;
910
use PHPStan\Rules\Rule;
1011
use PHPStan\Rules\RuleErrorBuilder;
12+
use PHPStan\Symfony\AutowireLoaderServiceMapFactory;
13+
use PHPStan\Symfony\DefaultServiceMap;
1114
use PHPStan\Symfony\ServiceMap;
1215
use PHPStan\Type\ObjectType;
1316
use PHPStan\Type\Symfony\Helper;
@@ -66,19 +69,56 @@ public function processNode(Node $node, Scope $scope): array
6669
}
6770

6871
$serviceId = $this->serviceMap::getServiceIdFromNode($node->getArgs()[0]->value, $scope);
69-
if ($serviceId !== null) {
70-
$service = $this->serviceMap->getService($serviceId);
71-
$serviceIdType = $scope->getType($node->getArgs()[0]->value);
72-
if ($service === null && !$scope->getType(Helper::createMarkerNode($node->var, $serviceIdType, $this->printer))->equals($serviceIdType)) {
72+
if ($serviceId === null) {
73+
return [];
74+
}
75+
76+
$isContainerInterfaceType = $isContainerType->yes() || $isPsrContainerType->yes();
77+
if ($isContainerInterfaceType) {
78+
$autowireLoaderResult = $this->getAutowireLoaderResult($node, $scope, $serviceId);
79+
80+
if ($autowireLoaderResult !== null) {
81+
return $autowireLoaderResult;
82+
}
83+
}
84+
85+
$service = $this->serviceMap->getService($serviceId);
86+
$serviceIdType = $scope->getType($node->getArgs()[0]->value);
87+
if ($service === null && !$scope->getType(Helper::createMarkerNode($node->var, $serviceIdType, $this->printer))->equals($serviceIdType)) {
88+
return [
89+
RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId))
90+
->identifier('symfonyContainer.serviceNotFound')
91+
->build(),
92+
];
93+
}
94+
95+
return [];
96+
}
97+
98+
/**
99+
* @return list<IdentifierRuleError>|null
100+
*/
101+
private function getAutowireLoaderResult(Node $node, Scope $scope, string $serviceId): ?array
102+
{
103+
$autowireLocatorServiceMapFactory = new AutowireLoaderServiceMapFactory($node, $scope);
104+
$autowireLocatorServiceMap = $autowireLocatorServiceMapFactory->create();
105+
106+
// Our container has a valid AutowireLoader attribute, else we would get a FakeServiceMap.
107+
if ($autowireLocatorServiceMap instanceof DefaultServiceMap) {
108+
$autowireLocatorService = $autowireLocatorServiceMap->getService($serviceId);
109+
110+
if ($autowireLocatorService === null) {
73111
return [
74-
RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId))
75-
->identifier('symfonyContainer.serviceNotFound')
112+
RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the AutowireLocator.', $serviceId))
113+
->identifier('symfonyContainer.undefinedService')
76114
->build(),
77115
];
78116
}
117+
118+
return [];
79119
}
80120

81-
return [];
121+
return null;
82122
}
83123

84124
}

0 commit comments

Comments
 (0)