Skip to content

Commit 46d19a9

Browse files
Add solution for test container
1 parent cf8c9c6 commit 46d19a9

11 files changed

+146
-41
lines changed

extension.neon

+6-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ parameters:
1313
- stubs/Psr/Cache/CacheItemInterface.stub
1414
- stubs/Psr/Cache/InvalidArgumentException.stub
1515
- stubs/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.stub
16-
- stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub
17-
- stubs/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.stub
18-
- stubs/Symfony/Bundle/FrameworkBundle/Test/TestContainer.stub
1916
- stubs/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/AuthenticatorFactoryInterface.stub
2017
- stubs/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/FirewallListenerFactoryInterface.stub
2118
- stubs/Symfony/Component/Console/Command.stub
@@ -364,3 +361,9 @@ services:
364361
class: PHPStan\Symfony\SymfonyContainerResultCacheMetaExtension
365362
tags:
366363
- phpstan.resultCacheMetaExtension
364+
-
365+
class: PHPStan\Type\Symfony\Container\KernelBrowserGetContainerDynamicReturnTypeExtension
366+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
367+
-
368+
class: PHPStan\Type\Symfony\Container\KernelTestCaseGetContainerDynamicReturnTypeExtension
369+
tags: [phpstan.broker.dynamicStaticMethodReturnTypeExtension]

src/Rules/Symfony/ContainerInterfacePrivateServiceRule.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\Symfony\ServiceMap;
1111
use PHPStan\TrinaryLogic;
1212
use PHPStan\Type\ObjectType;
13+
use PHPStan\Type\Symfony\Container\TestContainerType;
1314
use PHPStan\Type\Type;
1415
use function sprintf;
1516

@@ -43,11 +44,17 @@ public function processNode(Node $node, Scope $scope): array
4344

4445
$argType = $scope->getType($node->var);
4546

46-
$isTestContainerType = (new ObjectType('Symfony\Bundle\FrameworkBundle\Test\TestContainer'))->isSuperTypeOf($argType);
47+
if (
48+
$argType instanceof TestContainerType
49+
|| (new ObjectType('Symfony\Bundle\FrameworkBundle\Test\TestContainer'))->isSuperTypeOf($argType)->yes()
50+
) {
51+
return [];
52+
}
53+
4754
$isOldServiceSubscriber = (new ObjectType('Symfony\Component\DependencyInjection\ServiceSubscriberInterface'))->isSuperTypeOf($argType);
4855
$isServiceSubscriber = $this->isServiceSubscriber($argType, $scope);
4956
$isServiceLocator = (new ObjectType('Symfony\Component\DependencyInjection\ServiceLocator'))->isSuperTypeOf($argType);
50-
if ($isTestContainerType->yes() || $isOldServiceSubscriber->yes() || $isServiceSubscriber->yes() || $isServiceLocator->yes()) {
57+
if ($isOldServiceSubscriber->yes() || $isServiceSubscriber->yes() || $isServiceLocator->yes()) {
5158
return [];
5259
}
5360

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPStan\Type\Symfony\Container;
6+
7+
use PhpParser\Node\Expr\MethodCall;
8+
use PHPStan\Analyser\Scope;
9+
use PHPStan\Reflection\MethodReflection;
10+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
11+
use PHPStan\Type\Type;
12+
13+
final class KernelBrowserGetContainerDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
14+
{
15+
16+
public function getClass(): string
17+
{
18+
return 'Symfony\Bundle\FrameworkBundle\KernelBrowser';
19+
}
20+
21+
public function isMethodSupported(MethodReflection $methodReflection): bool
22+
{
23+
return $methodReflection->getName() === 'getContainer';
24+
}
25+
26+
public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): ?Type
27+
{
28+
return new TestContainerType();
29+
}
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPStan\Type\Symfony\Container;
6+
7+
use PhpParser\Node\Expr\StaticCall;
8+
use PHPStan\Analyser\Scope;
9+
use PHPStan\Reflection\MethodReflection;
10+
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
11+
use PHPStan\Type\Type;
12+
13+
final class KernelTestCaseGetContainerDynamicReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension
14+
{
15+
16+
public function getClass(): string
17+
{
18+
return 'Symfony\Bundle\FrameworkBundle\Test\KernelTestCase';
19+
}
20+
21+
public function isStaticMethodSupported(MethodReflection $methodReflection): bool
22+
{
23+
return $methodReflection->getName() === 'getContainer';
24+
}
25+
26+
public function getTypeFromStaticMethodCall(MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope): ?Type
27+
{
28+
return new TestContainerType();
29+
}
30+
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPStan\Type\Symfony\Container;
6+
7+
use PHPStan\Reflection\ClassReflection;
8+
use PHPStan\Type\ObjectType;
9+
use PHPStan\Type\Type;
10+
11+
class TestContainerType extends ObjectType
12+
{
13+
public function __construct(
14+
string $class = 'Symfony\Component\DependencyInjection\ContainerInterface',
15+
?Type $subtractedType = null,
16+
?ClassReflection $classReflection = null
17+
) {
18+
parent::__construct($class, $subtractedType, $classReflection);
19+
}
20+
}

stubs/Symfony/Bundle/FrameworkBundle/KernelBrowser.stub

-13
This file was deleted.

stubs/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.stub

-16
This file was deleted.

stubs/Symfony/Bundle/FrameworkBundle/Test/TestContainer.stub

-7
This file was deleted.

tests/Rules/Symfony/ContainerInterfacePrivateServiceRuleTest.php

+17
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,21 @@ public function testGetPrivateServiceInServiceSubscriber(): void
7777
);
7878
}
7979

80+
public function testGetPrivateServiceInTest(): void
81+
{
82+
$this->analyse(
83+
[
84+
__DIR__ . '/ExampleTest.php',
85+
],
86+
[],
87+
);
88+
}
89+
90+
public static function getAdditionalConfigFiles(): array
91+
{
92+
return [
93+
__DIR__ . '/container-extensions.neon',
94+
];
95+
}
96+
8097
}

tests/Rules/Symfony/ExampleTest.php

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPStan\Rules\Symfony;
6+
7+
use Symfony\Bundle\FrameworkBundle\KernelBrowser;
8+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
9+
10+
class ExampleTest extends KernelTestCase
11+
{
12+
13+
public function test(): void
14+
{
15+
$container = self::getContainer();
16+
$container->get('private');
17+
}
18+
19+
public function foo(KernelBrowser $browser): void
20+
{
21+
$container = $browser->getContainer();
22+
$container->get('private');
23+
}
24+
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
-
3+
class: PHPStan\Type\Symfony\Container\KernelBrowserGetContainerDynamicReturnTypeExtension
4+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
5+
-
6+
class: PHPStan\Type\Symfony\Container\KernelTestCaseGetContainerDynamicReturnTypeExtension
7+
tags: [phpstan.broker.dynamicStaticMethodReturnTypeExtension]

0 commit comments

Comments
 (0)