|
8 | 8 | use PHPStan\Analyser\Scope;
|
9 | 9 | use PHPStan\Rules\Rule;
|
10 | 10 | use PHPStan\Rules\RuleErrorBuilder;
|
| 11 | +use PHPStan\Symfony\AutowireLoaderServiceMapFactory; |
| 12 | +use PHPStan\Symfony\DefaultServiceMap; |
11 | 13 | use PHPStan\Symfony\ServiceMap;
|
12 | 14 | use PHPStan\Type\ObjectType;
|
13 | 15 | use PHPStan\Type\Symfony\Helper;
|
@@ -66,19 +68,52 @@ public function processNode(Node $node, Scope $scope): array
|
66 | 68 | }
|
67 | 69 |
|
68 | 70 | $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)) { |
| 71 | + if ($serviceId === null) { |
| 72 | + return []; |
| 73 | + } |
| 74 | + |
| 75 | + $isContainerInterfaceType = $isContainerType->yes() || $isPsrContainerType->yes(); |
| 76 | + if ($isContainerInterfaceType) { |
| 77 | + $autowireLoaderResult = $this->getAutowireLoaderResult($node, $scope, $serviceId); |
| 78 | + |
| 79 | + if (is_array($autowireLoaderResult)) { |
| 80 | + return $autowireLoaderResult; |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + $service = $this->serviceMap->getService($serviceId); |
| 85 | + $serviceIdType = $scope->getType($node->getArgs()[0]->value); |
| 86 | + if ($service === null && !$scope->getType(Helper::createMarkerNode($node->var, $serviceIdType, $this->printer))->equals($serviceIdType)) { |
| 87 | + return [ |
| 88 | + RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId)) |
| 89 | + ->identifier('symfonyContainer.serviceNotFound') |
| 90 | + ->build(), |
| 91 | + ]; |
| 92 | + } |
| 93 | + |
| 94 | + return []; |
| 95 | + } |
| 96 | + |
| 97 | + private function getAutowireLoaderResult(Node $node, Scope $scope, string $serviceId): ?array { |
| 98 | + $autowireLocatorServiceMapFactory = new AutowireLoaderServiceMapFactory($node, $scope); |
| 99 | + $autowireLocatorServiceMap = $autowireLocatorServiceMapFactory->create(); |
| 100 | + |
| 101 | + // Our container has a valid AutowireLoader attribute, else we would get a FakeServiceMap. |
| 102 | + if ($autowireLocatorServiceMap instanceof DefaultServiceMap) { |
| 103 | + $autowireLocatorService = $autowireLocatorServiceMap->getService($serviceId); |
| 104 | + |
| 105 | + if ($autowireLocatorService === null) { |
73 | 106 | return [
|
74 |
| - RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the container.', $serviceId)) |
75 |
| - ->identifier('symfonyContainer.serviceNotFound') |
| 107 | + RuleErrorBuilder::message(sprintf('Service "%s" is not registered in the AutowireLocator.', $serviceId)) |
| 108 | + ->identifier('symfonyContainer.undefinedService') |
76 | 109 | ->build(),
|
77 | 110 | ];
|
78 | 111 | }
|
| 112 | + |
| 113 | + return []; |
79 | 114 | }
|
80 | 115 |
|
81 |
| - return []; |
| 116 | + return null; |
82 | 117 | }
|
83 | 118 |
|
84 | 119 | }
|
0 commit comments