Skip to content

Commit c7fcb79

Browse files
authored
Merge pull request #409 from mglaman/gh399-node-visitor-fix
Explicit allowed class checks for #lazy_builder
2 parents 05ebd4d + 9c09472 commit c7fcb79

File tree

3 files changed

+19
-17
lines changed

3 files changed

+19
-17
lines changed

src/Rules/Drupal/RenderCallbackRule.php

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace mglaman\PHPStanDrupal\Rules\Drupal;
44

5+
use Drupal\Core\Render\PlaceholderGenerator;
6+
use Drupal\Core\Render\Renderer;
57
use mglaman\PHPStanDrupal\Drupal\ServiceMap;
68
use PhpParser\Node;
79
use PhpParser\Node\Name;
@@ -63,18 +65,22 @@ public function processNode(Node $node, Scope $scope): array
6365

6466
// @todo Move into its own rule.
6567
if ($keyChecked === '#lazy_builder') {
66-
// Check if being used in array_intersect_key.
67-
// NOTE: This only works against existing patterns in Drupal core where the array with boolean values is
68-
// being passed as the argument to array_intersect_key.
69-
$parent = $node->getAttribute('parent');
70-
if ($parent instanceof Node\Expr\Array_) {
71-
$parent = $parent->getAttribute('parent');
72-
if ($parent instanceof Node\Arg) {
73-
$parent = $parent->getAttribute('parent');
74-
if ($parent instanceof Node\Expr\FuncCall
75-
&& $parent->name instanceof Name
76-
&& $parent->name->toString() === 'array_intersect_key'
77-
) {
68+
if ($scope->isInClass()) {
69+
$classReflection = $scope->getClassReflection();
70+
// @todo why doesn't isInClass assert this isn't null?
71+
assert($classReflection !== null);
72+
$classType = new ObjectType($classReflection->getName());
73+
// These classes use #lazy_builder in array_intersect_key. With
74+
// PHPStan 1.6, nodes do not track their parent/next/prev which
75+
// saves a lot of memory. But makes it harder to detect if we're
76+
// in a call to array_intersect_key. This is an easier workaround.
77+
$allowedTypes = [
78+
PlaceholderGenerator::class,
79+
Renderer::class,
80+
'Drupal\Tests\Core\Render\RendererPlaceholdersTest',
81+
];
82+
foreach ($allowedTypes as $allowedType) {
83+
if ($classType->isInstanceOf($allowedType)->yes()) {
7884
return [];
7985
}
8086
}

tests/fixtures/config/phpunit-drupal-phpstan.neon

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,3 @@ includes:
1717
- ../../../extension.neon
1818
- ../../../rules.neon
1919
- ../../../vendor/phpstan/phpstan-deprecation-rules/rules.neon
20-
# @todo remove after https://github.com/mglaman/phpstan-drupal/issues/399.
21-
conditionalTags:
22-
PhpParser\NodeVisitor\NodeConnectingVisitor:
23-
phpstan.parser.richParserNodeVisitor: true

tests/src/Rules/PreRenderCallbackRuleTest.php renamed to tests/src/Rules/RenderCallbackRuleTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use mglaman\PHPStanDrupal\Tests\DrupalRuleTestCase;
88
use mglaman\PHPStanDrupal\Rules\Drupal\RenderCallbackRule;
99

10-
final class PreRenderCallbackRuleTest extends DrupalRuleTestCase {
10+
final class RenderCallbackRuleTest extends DrupalRuleTestCase {
1111

1212
protected function getRule(): \PHPStan\Rules\Rule
1313
{

0 commit comments

Comments
 (0)