|
4 | 4 |
|
5 | 5 | use mglaman\PHPStanDrupal\Drupal\ServiceMap;
|
6 | 6 | use PhpParser\Node;
|
| 7 | +use PhpParser\Node\Name; |
7 | 8 | use PHPStan\Analyser\Scope;
|
8 | 9 | use PHPStan\Reflection\ReflectionProvider;
|
9 | 10 | use PHPStan\Rules\Rule;
|
|
18 | 19 | use PHPStan\Type\ObjectType;
|
19 | 20 | use PHPStan\Type\ThisType;
|
20 | 21 | use PHPStan\Type\Type;
|
| 22 | +use PHPStan\Type\TypeCombinator; |
21 | 23 | use PHPStan\Type\UnionType;
|
22 | 24 | use PHPStan\Type\VerbosityLevel;
|
| 25 | +use Drupal\Core\Render\PlaceholderGeneratorInterface; |
| 26 | +use Drupal\Core\Render\RendererInterface; |
23 | 27 |
|
24 | 28 | final class RenderCallbackRule implements Rule
|
25 | 29 | {
|
@@ -62,6 +66,23 @@ public function processNode(Node $node, Scope $scope): array
|
62 | 66 |
|
63 | 67 | // @todo Move into its own rule.
|
64 | 68 | if ($keyChecked === '#lazy_builder') {
|
| 69 | + // Check if being used in array_intersect_key. |
| 70 | + // NOTE: This only works against existing patterns in Drupal core where the array with boolean values is |
| 71 | + // being passed as the argument to array_intersect_key. |
| 72 | + $parent = $node->getAttribute('parent'); |
| 73 | + if ($parent instanceof Node\Expr\Array_) { |
| 74 | + $parent = $parent->getAttribute('parent'); |
| 75 | + if ($parent instanceof Node\Arg) { |
| 76 | + $parent = $parent->getAttribute('parent'); |
| 77 | + if ($parent instanceof Node\Expr\FuncCall |
| 78 | + && $parent->name instanceof Name |
| 79 | + && $parent->name->toString() === 'array_intersect_key' |
| 80 | + ) { |
| 81 | + return []; |
| 82 | + } |
| 83 | + } |
| 84 | + } |
| 85 | + |
65 | 86 | if (!$value instanceof Node\Expr\Array_) {
|
66 | 87 | return [
|
67 | 88 | RuleErrorBuilder::message(sprintf('The "%s" expects a callable array with arguments.', $keyChecked))
|
@@ -118,7 +139,7 @@ private function doProcessNode(Node\Expr $node, Scope $scope, string $keyChecked
|
118 | 139 | }
|
119 | 140 | // We can determine if the callback is callable through the type system. However, we cannot determine
|
120 | 141 | // if it is just a function or a static class call (MyClass::staticFunc).
|
121 |
| - if ($this->reflectionProvider->hasFunction(new Node\Name($type->getValue()), null)) { |
| 142 | + if ($this->reflectionProvider->hasFunction(new Name($type->getValue()), null)) { |
122 | 143 | return RuleErrorBuilder::message(
|
123 | 144 | sprintf("%s callback %s at key '%s' is not trusted.", $keyChecked, $type->describe(VerbosityLevel::value()), $pos)
|
124 | 145 | )->line($errorLine)
|
|
0 commit comments