Skip to content

Commit 4de76b2

Browse files
authored
Merge pull request #434 from laytan/support-class-string-service-ids
add support for class string service ids
2 parents 8acaa1e + ebb658d commit 4de76b2

File tree

6 files changed

+48
-9
lines changed

6 files changed

+48
-9
lines changed

src/Type/ContainerDynamicReturnTypeExtension.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
use mglaman\PHPStanDrupal\Drupal\DrupalServiceDefinition;
66
use mglaman\PHPStanDrupal\Drupal\ServiceMap;
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\ClassConstFetch;
79
use PhpParser\Node\Expr\MethodCall;
10+
use PhpParser\Node\Name\FullyQualified;
811
use PhpParser\Node\Scalar\String_;
912
use PhpParser\Node\VariadicPlaceholder;
1013
use PHPStan\Analyser\Scope;
@@ -52,13 +55,12 @@ public function getTypeFromMethodCall(
5255
throw new ShouldNotHappenException();
5356
}
5457
$arg1 = $arg1->value;
55-
if (!$arg1 instanceof String_) {
56-
// @todo determine what these types are.
58+
59+
$serviceId = $this->getServiceId($arg1);
60+
if ($serviceId === null) {
5761
return $returnType;
5862
}
5963

60-
$serviceId = $arg1->value;
61-
6264
if ($methodReflection->getName() === 'get') {
6365
$service = $this->serviceMap->getService($serviceId);
6466
if ($service instanceof DrupalServiceDefinition) {
@@ -73,4 +75,18 @@ public function getTypeFromMethodCall(
7375

7476
throw new ShouldNotHappenException();
7577
}
78+
79+
protected function getServiceId(Node $arg1): ?string
80+
{
81+
if ($arg1 instanceof String_) {
82+
// @todo determine what these types are.
83+
return $arg1->value;
84+
}
85+
86+
if ($arg1 instanceof ClassConstFetch && $arg1->class instanceof FullyQualified) {
87+
return (string) $arg1->class;
88+
}
89+
90+
return null;
91+
}
7692
}

src/Type/DrupalServiceDynamicReturnTypeExtension.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
use Drupal;
66
use mglaman\PHPStanDrupal\Drupal\DrupalServiceDefinition;
77
use mglaman\PHPStanDrupal\Drupal\ServiceMap;
8+
use PhpParser\Node\Expr\ClassConstFetch;
89
use PhpParser\Node\Expr\StaticCall;
10+
use PhpParser\Node\Name\FullyQualified;
911
use PhpParser\Node\Scalar\String_;
1012
use PhpParser\Node\VariadicPlaceholder;
1113
use PHPStan\Analyser\Scope;
@@ -51,17 +53,29 @@ public function getTypeFromStaticMethodCall(
5153
if ($arg1 instanceof VariadicPlaceholder) {
5254
throw new ShouldNotHappenException();
5355
}
56+
5457
$arg1 = $arg1->value;
55-
if (!$arg1 instanceof String_) {
56-
// @todo determine what these types are.
57-
return $returnType;
58+
59+
if ($arg1 instanceof String_) {
60+
$serviceId = $arg1->value;
61+
return $this->getServiceType($serviceId) ?? $returnType;
5862
}
5963

60-
$serviceId = $arg1->value;
64+
if ($arg1 instanceof ClassConstFetch && $arg1->class instanceof FullyQualified) {
65+
$serviceId = (string) $arg1->class;
66+
return $this->getServiceType($serviceId) ?? $returnType;
67+
}
68+
69+
return $returnType;
70+
}
71+
72+
protected function getServiceType(string $serviceId): ?Type
73+
{
6174
$service = $this->serviceMap->getService($serviceId);
6275
if ($service instanceof DrupalServiceDefinition) {
6376
return $service->getType();
6477
}
65-
return $returnType;
78+
79+
return null;
6680
}
6781
}

tests/fixtures/drupal/modules/service_map/service_map.services.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
services:
22
service_map.my_service:
33
class: Drupal\service_map\MyService
4+
Drupal\service_map\MyService:
5+
class: Drupal\service_map\MyService
46
GuzzleHttp\Client: '@http_client'
57
Drupal\Core\Config\ConfigFactoryInterface: '@config.factory'
68
Drupal\Core\Messenger\MessengerInterface: '@messenger'

tests/src/Type/data/container.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ function test(): void {
1818
assertType(MyService::class, $container->get('service_map.concrete_service_with_a_parent_which_has_a_parent'));
1919
assertType(Override::class, $container->get('service_map.concrete_service_overriding_definition_of_its_parent'));
2020
assertType(Concrete::class, $container->get('service_map.concrete_overriding_its_parent_which_has_a_parent'));
21+
assertType(MyService::class, $container->get(MyService::class));
2122
}

tests/src/Type/data/drupal-class-resolver.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ function test(): void {
1717
assertType(MyService::class, \Drupal::service('class_resolver')->getInstanceFromDefinition('service_map.my_service'));
1818
assertType(MyService::class, \Drupal::classResolver()->getInstanceFromDefinition('service_map.my_service'));
1919
assertType(MyService::class, \Drupal::classResolver('service_map.my_service'));
20+
21+
assertType(MyService::class, (new ClassResolver())->getInstanceFromDefinition(MyService::class));
22+
assertType(MyService::class, \Drupal::service('class_resolver')->getInstanceFromDefinition(MyService::class));
23+
assertType(MyService::class, \Drupal::classResolver()->getInstanceFromDefinition(MyService::class));
24+
assertType(MyService::class, \Drupal::classResolver(MyService::class));
2025
}

tests/src/Type/data/drupal-service-static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@
77

88
function test(): void {
99
assertType(MyService::class, \Drupal::service('service_map.my_service'));
10+
assertType(MyService::class, \Drupal::service(MyService::class));
1011
}

0 commit comments

Comments
 (0)