diff --git a/extension.neon b/extension.neon index 0803248f..c76d573f 100644 --- a/extension.neon +++ b/extension.neon @@ -13,9 +13,6 @@ parameters: - stubs/Psr/Cache/CacheItemInterface.stub - stubs/Psr/Cache/InvalidArgumentException.stub - stubs/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.stub - - stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub - - stubs/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.stub - - stubs/Symfony/Bundle/FrameworkBundle/Test/TestContainer.stub - stubs/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AuthenticatorFactoryInterface.stub - stubs/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FirewallListenerFactoryInterface.stub - stubs/Symfony/Component/Console/Command.stub diff --git a/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php b/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php index 96f1efea..c8ec11a8 100644 --- a/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php +++ b/src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php @@ -43,11 +43,11 @@ public function processNode(Node $node, Scope $scope): array $argType = $scope->getType($node->var); - $isTestContainerType = (new ObjectType('Symfony\Bundle\FrameworkBundle\Test\TestContainer'))->isSuperTypeOf($argType); + $isTestContainer = $this->isTestContainer($argType, $scope); $isOldServiceSubscriber = (new ObjectType('Symfony\Component\DependencyInjection\ServiceSubscriberInterface'))->isSuperTypeOf($argType); $isServiceSubscriber = $this->isServiceSubscriber($argType, $scope); $isServiceLocator = (new ObjectType('Symfony\Component\DependencyInjection\ServiceLocator'))->isSuperTypeOf($argType); - if ($isTestContainerType->yes() || $isOldServiceSubscriber->yes() || $isServiceSubscriber->yes() || $isServiceLocator->yes()) { + if ($isTestContainer->yes() || $isOldServiceSubscriber->yes() || $isServiceSubscriber->yes() || $isServiceLocator->yes()) { return []; } @@ -91,4 +91,25 @@ private function isServiceSubscriber(Type $containerType, Scope $scope): Trinary return $isContainerServiceSubscriber->or($serviceSubscriberInterfaceType->isSuperTypeOf($containedClassType)->result); } + private function isTestContainer(Type $containerType, Scope $scope): TrinaryLogic + { + $testContainer = new ObjectType('Symfony\Bundle\FrameworkBundle\Test\TestContainer'); + $isTestContainer = $testContainer->isSuperTypeOf($containerType)->result; + + $classReflection = $scope->getClassReflection(); + if ($classReflection === null) { + return $isTestContainer; + } + + $containerInterface = new ObjectType('Symfony\Component\DependencyInjection\ContainerInterface'); + $kernelTestCase = new ObjectType('Symfony\Bundle\FrameworkBundle\Test\KernelTestCase'); + $containedClassType = new ObjectType($classReflection->getName()); + + return $isTestContainer->or( + $containerInterface->isSuperTypeOf($containerType)->result->and( + $kernelTestCase->isSuperTypeOf($containedClassType)->result, + ), + ); + } + } diff --git a/stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub b/stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub deleted file mode 100644 index ec54f1eb..00000000 --- a/stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub +++ /dev/null @@ -1,13 +0,0 @@ -analyse( + [ + __DIR__ . '/ExampleTest.php', + ], + [], + ); + } + } diff --git a/tests/Rules/Symfony/ExampleTest.php b/tests/Rules/Symfony/ExampleTest.php new file mode 100644 index 00000000..10b06703 --- /dev/null +++ b/tests/Rules/Symfony/ExampleTest.php @@ -0,0 +1,23 @@ +get('private'); + } + + public function foo(KernelBrowser $browser): void + { + $container = $browser->getContainer(); + $container->get('private'); + } + +}