Skip to content

Commit d8ae186

Browse files
committed
Merge branch 'main' into typed-entity-storage-does-not-succeed-to-infer-query-type
# Conflicts: # src/Type/EntityStorage/EntityStorageDynamicReturnTypeExtension.php
2 parents abfcb51 + a8ec61b commit d8ae186

File tree

3 files changed

+64
-30
lines changed

3 files changed

+64
-30
lines changed

extension.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,9 @@ services:
297297
-
298298
class: mglaman\PHPStanDrupal\Type\EntityStorage\EntityStorageDynamicReturnTypeExtension
299299
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
300+
-
301+
class: mglaman\PHPStanDrupal\Type\EntityStorage\GetQueryReturnTypeExtension
302+
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]
300303
-
301304
class: mglaman\PHPStanDrupal\Type\ContainerDynamicReturnTypeExtension
302305
tags: [phpstan.broker.dynamicMethodReturnTypeExtension]

src/Type/EntityStorage/EntityStorageDynamicReturnTypeExtension.php

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,17 @@
22

33
namespace mglaman\PHPStanDrupal\Type\EntityStorage;
44

5-
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
6-
use Drupal\Core\Entity\ContentEntityStorageInterface;
75
use Drupal\Core\Entity\EntityStorageInterface;
86
use mglaman\PHPStanDrupal\Drupal\EntityDataRepository;
9-
use mglaman\PHPStanDrupal\Type\EntityQuery\ConfigEntityQueryType;
10-
use mglaman\PHPStanDrupal\Type\EntityQuery\ContentEntityQueryType;
117
use PhpParser\Node\Expr\MethodCall;
128
use PHPStan\Analyser\Scope;
139
use PHPStan\Reflection\MethodReflection;
1410
use PHPStan\Reflection\ParametersAcceptorSelector;
15-
use PHPStan\ShouldNotHappenException;
1611
use PHPStan\Type\ArrayType;
1712
use PHPStan\Type\DynamicMethodReturnTypeExtension;
1813
use PHPStan\Type\IntegerType;
1914
use PHPStan\Type\ObjectType;
2015
use PHPStan\Type\StringType;
21-
use PHPStan\Type\Type;
2216
use PHPStan\Type\TypeCombinator;
2317

2418
class EntityStorageDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
@@ -49,7 +43,6 @@ public function isMethodSupported(MethodReflection $methodReflection): bool
4943
'loadMultiple',
5044
'loadByProperties',
5145
'loadUnchanged',
52-
'getQuery',
5346
],
5447
true
5548
);
@@ -65,29 +58,6 @@ public function getTypeFromMethodCall(
6558
return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
6659
}
6760

68-
if ($methodReflection->getName() === 'getQuery') {
69-
$returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
70-
if (!$returnType instanceof ObjectType) {
71-
return $returnType;
72-
}
73-
74-
if ((new ObjectType(ContentEntityStorageInterface::class))->isSuperTypeOf($callerType)->yes()) {
75-
return new ContentEntityQueryType(
76-
$returnType->getClassName(),
77-
$returnType->getSubtractedType(),
78-
$returnType->getClassReflection()
79-
);
80-
}
81-
if ((new ObjectType(ConfigEntityStorageInterface::class))->isSuperTypeOf($callerType)->yes()) {
82-
return new ConfigEntityQueryType(
83-
$returnType->getClassName(),
84-
$returnType->getSubtractedType(),
85-
$returnType->getClassReflection()
86-
);
87-
}
88-
return $returnType;
89-
}
90-
9161
if (!$callerType instanceof EntityStorageType) {
9262
$resolvedEntityType = $this->entityDataRepository->resolveFromStorage($callerType);
9363
if ($resolvedEntityType === null) {
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace mglaman\PHPStanDrupal\Type\EntityStorage;
4+
5+
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
6+
use Drupal\Core\Entity\ContentEntityStorageInterface;
7+
use Drupal\Core\Entity\EntityStorageInterface;
8+
use mglaman\PHPStanDrupal\Type\EntityQuery\ConfigEntityQueryType;
9+
use mglaman\PHPStanDrupal\Type\EntityQuery\ContentEntityQueryType;
10+
use PhpParser\Node\Expr\MethodCall;
11+
use PHPStan\Analyser\Scope;
12+
use PHPStan\Reflection\MethodReflection;
13+
use PHPStan\Reflection\ParametersAcceptorSelector;
14+
use PHPStan\Type\DynamicMethodReturnTypeExtension;
15+
use PHPStan\Type\ObjectType;
16+
17+
final class GetQueryReturnTypeExtension implements DynamicMethodReturnTypeExtension
18+
{
19+
20+
public function getClass(): string
21+
{
22+
return EntityStorageInterface::class;
23+
}
24+
25+
public function isMethodSupported(MethodReflection $methodReflection): bool
26+
{
27+
return $methodReflection->getName() === 'getQuery';
28+
}
29+
30+
public function getTypeFromMethodCall(
31+
MethodReflection $methodReflection,
32+
MethodCall $methodCall,
33+
Scope $scope
34+
): \PHPStan\Type\Type {
35+
$returnType = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType();
36+
if (!$returnType instanceof ObjectType) {
37+
return $returnType;
38+
}
39+
40+
$callerType = $scope->getType($methodCall->var);
41+
if (!$callerType instanceof ObjectType) {
42+
return $returnType;
43+
}
44+
45+
if ((new ObjectType(ContentEntityStorageInterface::class))->isSuperTypeOf($callerType)->yes()) {
46+
return new ContentEntityQueryType(
47+
$returnType->getClassName(),
48+
$returnType->getSubtractedType(),
49+
$returnType->getClassReflection()
50+
);
51+
}
52+
if ((new ObjectType(ConfigEntityStorageInterface::class))->isSuperTypeOf($callerType)->yes()) {
53+
return new ConfigEntityQueryType(
54+
$returnType->getClassName(),
55+
$returnType->getSubtractedType(),
56+
$returnType->getClassReflection()
57+
);
58+
}
59+
return $returnType;
60+
}
61+
}

0 commit comments

Comments
 (0)