Skip to content

Commit

Permalink
Merge pull request #409 from mglaman/gh399-node-visitor-fix
Browse files Browse the repository at this point in the history
Explicit allowed class checks for #lazy_builder
  • Loading branch information
mglaman authored May 20, 2022
2 parents 05ebd4d + 9c09472 commit c7fcb79
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 17 deletions.
30 changes: 18 additions & 12 deletions src/Rules/Drupal/RenderCallbackRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace mglaman\PHPStanDrupal\Rules\Drupal;

use Drupal\Core\Render\PlaceholderGenerator;
use Drupal\Core\Render\Renderer;
use mglaman\PHPStanDrupal\Drupal\ServiceMap;
use PhpParser\Node;
use PhpParser\Node\Name;
Expand Down Expand Up @@ -63,18 +65,22 @@ public function processNode(Node $node, Scope $scope): array

// @todo Move into its own rule.
if ($keyChecked === '#lazy_builder') {
// Check if being used in array_intersect_key.
// NOTE: This only works against existing patterns in Drupal core where the array with boolean values is
// being passed as the argument to array_intersect_key.
$parent = $node->getAttribute('parent');
if ($parent instanceof Node\Expr\Array_) {
$parent = $parent->getAttribute('parent');
if ($parent instanceof Node\Arg) {
$parent = $parent->getAttribute('parent');
if ($parent instanceof Node\Expr\FuncCall
&& $parent->name instanceof Name
&& $parent->name->toString() === 'array_intersect_key'
) {
if ($scope->isInClass()) {
$classReflection = $scope->getClassReflection();
// @todo why doesn't isInClass assert this isn't null?
assert($classReflection !== null);
$classType = new ObjectType($classReflection->getName());
// These classes use #lazy_builder in array_intersect_key. With
// PHPStan 1.6, nodes do not track their parent/next/prev which
// saves a lot of memory. But makes it harder to detect if we're
// in a call to array_intersect_key. This is an easier workaround.
$allowedTypes = [
PlaceholderGenerator::class,
Renderer::class,
'Drupal\Tests\Core\Render\RendererPlaceholdersTest',
];
foreach ($allowedTypes as $allowedType) {
if ($classType->isInstanceOf($allowedType)->yes()) {
return [];
}
}
Expand Down
4 changes: 0 additions & 4 deletions tests/fixtures/config/phpunit-drupal-phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,3 @@ includes:
- ../../../extension.neon
- ../../../rules.neon
- ../../../vendor/phpstan/phpstan-deprecation-rules/rules.neon
# @todo remove after https://github.com/mglaman/phpstan-drupal/issues/399.
conditionalTags:
PhpParser\NodeVisitor\NodeConnectingVisitor:
phpstan.parser.richParserNodeVisitor: true
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use mglaman\PHPStanDrupal\Tests\DrupalRuleTestCase;
use mglaman\PHPStanDrupal\Rules\Drupal\RenderCallbackRule;

final class PreRenderCallbackRuleTest extends DrupalRuleTestCase {
final class RenderCallbackRuleTest extends DrupalRuleTestCase {

protected function getRule(): \PHPStan\Rules\Rule
{
Expand Down

0 comments on commit c7fcb79

Please sign in to comment.