Skip to content

Commit c195b34

Browse files
committed
Add AutowireLoader support for ContainerInterfaceUnknownServiceRule
1 parent 5226976 commit c195b34

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

src/Rules/Symfony/ContainerInterfaceUnknownServiceRule.php

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
use PHPStan\Analyser\Scope;
99
use PHPStan\Rules\Rule;
1010
use PHPStan\Rules\RuleErrorBuilder;
11+
use PHPStan\ShouldNotHappenException;
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,55 @@ 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<PHPStan\Rules\IdentifierRuleError>|null
100+
*/
101+
private function getAutowireLoaderResult(Node $node, Scope $scope, string $serviceId): ?array {
102+
$autowireLocatorServiceMapFactory = new AutowireLoaderServiceMapFactory($node, $scope);
103+
$autowireLocatorServiceMap = $autowireLocatorServiceMapFactory->create();
104+
105+
// Our container has a valid AutowireLoader attribute, else we would get a FakeServiceMap.
106+
if ($autowireLocatorServiceMap instanceof DefaultServiceMap) {
107+
$autowireLocatorService = $autowireLocatorServiceMap->getService($serviceId);
108+
109+
if ($autowireLocatorService === null) {
73110
return [
74-
RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId))
75-
->identifier('symfonyContainer.serviceNotFound')
111+
RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the AutowireLocator.', $serviceId))
112+
->identifier('symfonyContainer.undefinedService')
76113
->build(),
77114
];
78115
}
116+
117+
return [];
79118
}
80119

81-
return [];
120+
return null;
82121
}
83122

84123
}

0 commit comments

Comments
 (0)