Skip to content

Commit 20b043c

Browse files
authored
Merge pull request #233 from mglaman/gh232
Use isSuperTypeOf to detect if module handler
2 parents 1f803a2 + 1fcebad commit 20b043c

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

src/Rules/Drupal/LoadIncludes.php

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

55
use Drupal\Core\Extension\ModuleHandlerInterface;
66
use DrupalFinder\DrupalFinder;
7+
use mglaman\PHPStanDrupal\Drupal\ExtensionDiscovery;
78
use PhpParser\Node;
89
use PHPStan\Analyser\Scope;
9-
use mglaman\PHPStanDrupal\Drupal\ExtensionDiscovery;
1010
use PHPStan\Rules\Rule;
11+
use PHPStan\Rules\RuleErrorBuilder;
1112
use PHPStan\ShouldNotHappenException;
1213
use PHPStan\Type\ObjectType;
1314

@@ -53,17 +54,13 @@ public function processNode(Node $node, Scope $scope): array
5354
if (!is_string($var_name)) {
5455
throw new ShouldNotHappenException(sprintf('Expected string for variable in %s, please open an issue on GitHub https://github.com/mglaman/phpstan-drupal/issues', get_called_class()));
5556
}
56-
$type = $scope->getVariableType($var_name);
57-
assert($type instanceof ObjectType);
58-
if (!class_exists($type->getClassName()) && !interface_exists($type->getClassName())) {
59-
throw new ShouldNotHappenException(sprintf('Could not find class for %s from reflection.', get_called_class()));
57+
$moduleHandlerInterfaceType = new ObjectType(ModuleHandlerInterface::class);
58+
$variableType = $scope->getVariableType($var_name);
59+
if (!$variableType->isSuperTypeOf($moduleHandlerInterfaceType)->yes()) {
60+
return [];
6061
}
6162

6263
try {
63-
$reflected = new \ReflectionClass($type->getClassName());
64-
if (!$reflected->implementsInterface(ModuleHandlerInterface::class)) {
65-
return [];
66-
}
6764
// Try to invoke it similarily as the module handler itself.
6865
$finder = new DrupalFinder();
6966
$finder->locateRoot($this->projectRoot);
@@ -97,9 +94,24 @@ public function processNode(Node $node, Scope $scope): array
9794
require_once $file;
9895
return [];
9996
}
100-
return [sprintf('File %s could not be loaded from %s::loadInclude', $file, $type->getClassName())];
97+
return [
98+
RuleErrorBuilder::message(sprintf(
99+
'File %s could not be loaded from %s::loadInclude',
100+
$file,
101+
ModuleHandlerInterface::class
102+
))
103+
->line($node->getLine())
104+
->build()
105+
];
101106
} catch (\Throwable $e) {
102-
return [sprintf('A file could not be loaded from %s::loadInclude', $type->getClassName())];
107+
return [
108+
RuleErrorBuilder::message(sprintf(
109+
'A file could not be loaded from %s::loadInclude',
110+
ModuleHandlerInterface::class
111+
))
112+
->line($node->getLine())
113+
->build()
114+
];
103115
}
104116
}
105117
}

tests/src/Rules/LoadIncludesRuleTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,13 @@ public function testRule(): void
2626
]);
2727
}
2828

29+
public function testFormStateLoadInclude(): void
30+
{
31+
$this->analyse([
32+
__DIR__ . '/../../fixtures/drupal/core/tests/Drupal/Tests/Core/Form/FormStateTest.php'
33+
],
34+
[
35+
]);
36+
}
37+
2938
}

0 commit comments

Comments
 (0)