Skip to content

Commit e4255f8

Browse files
committed
Added support for self, static, parent
1 parent 143d34b commit e4255f8

7 files changed

+38
-18
lines changed

src/Rules/ContainerInterfacePrivateServiceRule.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function processNode(Node $node, Scope $scope): array
4141
&& isset($node->args[0])
4242
&& $node->args[0] instanceof Arg
4343
) {
44-
$service = $this->serviceMap->getServiceFromNode($node->args[0]->value);
44+
$service = $this->serviceMap->getServiceFromNode($node->args[0]->value, $scope);
4545
if ($service !== \null && !$service['public']) {
4646
return [\sprintf('Service "%s" is private.', $service['id'])];
4747
}

src/Rules/ContainerInterfaceUnknownServiceRule.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ public function processNode(Node $node, Scope $scope): array
4141
&& isset($node->args[0])
4242
&& $node->args[0] instanceof Arg
4343
) {
44-
$service = $this->serviceMap->getServiceFromNode($node->args[0]->value);
44+
$service = $this->serviceMap->getServiceFromNode($node->args[0]->value, $scope);
4545
if ($service === \null) {
46-
$serviceId = ServiceMap::getServiceIdFromNode($node->args[0]->value);
46+
$serviceId = ServiceMap::getServiceIdFromNode($node->args[0]->value, $scope);
4747
if ($serviceId !== null) {
4848
return [\sprintf('Service "%s" is not registered in the container.', $serviceId)];
4949
}

src/ServiceMap.php

+7-9
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
namespace Lookyman\PHPStan\Symfony;
55

66
use Lookyman\PHPStan\Symfony\Exception\XmlContainerNotExistsException;
7+
use PHPStan\Analyser\Scope;
78
use PhpParser\Node;
89
use PhpParser\Node\Expr\BinaryOp\Concat;
910
use PhpParser\Node\Expr\ClassConstFetch;
@@ -55,26 +56,23 @@ public function __construct(string $containerXml)
5556
}
5657
}
5758

58-
public function getServiceFromNode(Node $node): ?array
59+
public function getServiceFromNode(Node $node, Scope $scope): ?array
5960
{
60-
$serviceId = self::getServiceIdFromNode($node);
61+
$serviceId = self::getServiceIdFromNode($node, $scope);
6162
return $serviceId !== \null && \array_key_exists($serviceId, $this->services) ? $this->services[$serviceId] : \null;
6263
}
6364

64-
public static function getServiceIdFromNode(Node $node): ?string
65+
public static function getServiceIdFromNode(Node $node, Scope $scope): ?string
6566
{
6667
if ($node instanceof String_) {
6768
return $node->value;
6869
}
6970
if ($node instanceof ClassConstFetch && $node->class instanceof Name) {
70-
$serviceId = $node->class->toString();
71-
if (!\in_array($serviceId, ['self', 'static', 'parent'], true)) {
72-
return $serviceId;
73-
}
71+
return $scope->resolveName($node->class);
7472
}
7573
if ($node instanceof Concat) {
76-
$left = self::getServiceIdFromNode($node->left);
77-
$right = self::getServiceIdFromNode($node->right);
74+
$left = self::getServiceIdFromNode($node->left, $scope);
75+
$right = self::getServiceIdFromNode($node->right, $scope);
7876
if ($left !== null && $right !== null) {
7977
return \sprintf('%s%s', $left, $right);
8078
}

src/Type/ContainerInterfaceDynamicReturnTypeExtension.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function getTypeFromMethodCall(
4343
if (isset($methodCall->args[0])
4444
&& $methodCall->args[0] instanceof Arg
4545
) {
46-
$service = $this->serviceMap->getServiceFromNode($methodCall->args[0]->value);
46+
$service = $this->serviceMap->getServiceFromNode($methodCall->args[0]->value, $scope);
4747
if ($service !== \null && !$service['synthetic']) {
4848
return new ObjectType($service['class'] ?? $service['id']);
4949
}

src/Type/ControllerDynamicReturnTypeExtension.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function getTypeFromMethodCall(
4343
if (isset($methodCall->args[0])
4444
&& $methodCall->args[0] instanceof Arg
4545
) {
46-
$service = $this->serviceMap->getServiceFromNode($methodCall->args[0]->value);
46+
$service = $this->serviceMap->getServiceFromNode($methodCall->args[0]->value, $scope);
4747
if ($service !== \null && !$service['synthetic']) {
4848
return new ObjectType($service['class'] ?? $service['id']);
4949
}

tests/Rules/ContainerInterfaceUnknownServiceRuleTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ public function testGetUnknownService(): void
3131
'Service "service.Lookyman\PHPStan\Symfony\ServiceMap" is not registered in the container.',
3232
38,
3333
],
34+
[
35+
'Service "Lookyman\PHPStan\Symfony\Rules\data\ExampleController" is not registered in the container.',
36+
44,
37+
],
3438
]);
3539
}
3640

tests/ServiceMapTest.php

+22-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33

44
namespace Lookyman\PHPStan\Symfony;
55

6-
use PHPUnit\Framework\TestCase;
6+
use Lookyman\PHPStan\Symfony\Rules\data\ExampleController;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Analyser\TypeSpecifier;
9+
use PHPStan\Testing\TestCase;
10+
use PhpParser\Node\Expr\BinaryOp\Concat;
711
use PhpParser\Node\Expr\ClassConstFetch;
812
use PhpParser\Node\Name;
913
use PhpParser\Node\Scalar\String_;
14+
use PhpParser\PrettyPrinter\Standard;
1015

1116
/**
1217
* @covers \Lookyman\PHPStan\Symfony\ServiceMap
@@ -19,8 +24,13 @@ final class ServiceMapTest extends TestCase
1924
*/
2025
public function testGetServiceFromNode(array $service): void
2126
{
27+
$printer = new Standard();
28+
2229
$serviceMap = new ServiceMap(__DIR__ . '/container.xml');
23-
self::assertEquals($service, $serviceMap->getServiceFromNode(new String_($service['id'])));
30+
self::assertSame($service, $serviceMap->getServiceFromNode(
31+
new String_($service['id']),
32+
new Scope($this->createBroker(), $printer, new TypeSpecifier($printer), '')
33+
));
2434
}
2535

2636
/**
@@ -46,8 +56,16 @@ public function getServiceFromNodeProvider(): array
4656

4757
public function testGetServiceIdFromNode(): void
4858
{
49-
self::assertEquals('foo', ServiceMap::getServiceIdFromNode(new String_('foo')));
50-
self::assertEquals('bar', ServiceMap::getServiceIdFromNode(new ClassConstFetch(new Name('bar'), '')));
59+
$broker = $this->createBroker();
60+
$printer = new Standard();
61+
$scope = new Scope($broker, $printer, new TypeSpecifier($printer), '');
62+
63+
self::assertSame('foo', ServiceMap::getServiceIdFromNode(new String_('foo'), $scope));
64+
self::assertSame('bar', ServiceMap::getServiceIdFromNode(new ClassConstFetch(new Name('bar'), ''), $scope));
65+
self::assertSame('foobar', ServiceMap::getServiceIdFromNode(new Concat(new String_('foo'), new ClassConstFetch(new Name('bar'), '')), $scope));
66+
67+
$scope = $scope->enterClass($broker->getClass(ExampleController::class));
68+
self::assertEquals(ExampleController::class, ServiceMap::getServiceIdFromNode(new ClassConstFetch(new Name('static'), ExampleController::class), $scope));
5169
}
5270

5371
}

0 commit comments

Comments
 (0)