From 1081bca18bfd0c07ff89854f80f91ef9fc83f756 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 18 Sep 2024 20:33:47 +0700 Subject: [PATCH 1/3] [Php81] Handle crash on ArrowFunction attribute on FirstClassCallableRector --- .../Fixture/skip_in_attribute.php.inc | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 rules-tests/Php81/Rector/Array_/FirstClassCallableRector/Fixture/skip_in_attribute.php.inc diff --git a/rules-tests/Php81/Rector/Array_/FirstClassCallableRector/Fixture/skip_in_attribute.php.inc b/rules-tests/Php81/Rector/Array_/FirstClassCallableRector/Fixture/skip_in_attribute.php.inc new file mode 100644 index 0000000000..0795d3cf3e --- /dev/null +++ b/rules-tests/Php81/Rector/Array_/FirstClassCallableRector/Fixture/skip_in_attribute.php.inc @@ -0,0 +1,12 @@ + null, +); \ No newline at end of file From 206bb4157f97a7845609a78ad81ce0b9a5f3dec2 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 18 Sep 2024 20:37:47 +0700 Subject: [PATCH 2/3] Fixed :tada: --- .../Scope/PHPStanNodeScopeResolver.php | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php index 93aab58590..c4a3e8212b 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php +++ b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php @@ -9,12 +9,14 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\Array_; use PhpParser\Node\Expr\ArrayItem; +use PhpParser\Node\Expr\ArrowFunction; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\AssignOp; use PhpParser\Node\Expr\BinaryOp; use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\Cast; use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\Match_; @@ -30,14 +32,19 @@ use PhpParser\Node\IntersectionType; use PhpParser\Node\Name; use PhpParser\Node\NullableType; +use PhpParser\Node\Param; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Catch_; use PhpParser\Node\Stmt\Class_; +use PhpParser\Node\Stmt\ClassConst; +use PhpParser\Node\Stmt\ClassLike; +use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Enum_; use PhpParser\Node\Stmt\EnumCase; use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Finally_; use PhpParser\Node\Stmt\Foreach_; +use PhpParser\Node\Stmt\Function_; use PhpParser\Node\Stmt\Interface_; use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\Return_; @@ -129,11 +136,15 @@ public function processNodes( /** @var MutatingScope $mutatingScope */ $mutatingScope = $this->resolveClassOrInterfaceScope($node, $mutatingScope); $node->setAttribute(AttributeKey::SCOPE, $mutatingScope); + $this->decorateNodeAttrGroups($node, $mutatingScope, $nodeCallback); + return; } if ($node instanceof Trait_) { $this->processTrait($node, $mutatingScope, $nodeCallback); + $this->decorateNodeAttrGroups($node, $mutatingScope, $nodeCallback); + return; } @@ -153,6 +164,8 @@ public function processNodes( $node->setAttribute(AttributeKey::SCOPE, $mutatingScope); } + $this->decorateNodeAttrGroups($node, $mutatingScope, $nodeCallback); + if ($node instanceof FileWithoutNamespace) { $this->nodeScopeResolverProcessNodes($node->stmts, $mutatingScope, $nodeCallback); return; @@ -360,12 +373,33 @@ private function processArrayItem(ArrayItem $arrayItem, MutatingScope $mutatingS $arrayItem->value->setAttribute(AttributeKey::SCOPE, $mutatingScope); } - private function decorateTraitAttrGroups(Trait_ $trait, MutatingScope $mutatingScope): void + private function decorateNodeAttrGroups(Node $node, MutatingScope $mutatingScope, callable $nodeCallback): void { - foreach ($trait->attrGroups as $attrGroup) { + // better to have AttrGroupsAwareInterface for all Node definition with attrGroups property + // but because may conflict with StmtsAwareInterface patch, this needs to be here + if ( + ! $node instanceof Param && + ! $node instanceof ArrowFunction && + ! $node instanceof Closure && + ! $node instanceof ClassConst && + ! $node instanceof ClassLike && + ! $node instanceof ClassMethod && + ! $node instanceof EnumCase && + ! $node instanceof Function_ && + ! $node instanceof Property + ) { + return; + } + + foreach ($node->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { foreach ($attr->args as $arg) { $arg->value->setAttribute(AttributeKey::SCOPE, $mutatingScope); + $this->nodeScopeResolverProcessNodes( + [new Expression($arg->value)], + $mutatingScope, + $nodeCallback + ); } } } @@ -501,7 +535,6 @@ private function processTrait(Trait_ $trait, MutatingScope $mutatingScope, calla if (! $this->reflectionProvider->hasClass($traitName)) { $trait->setAttribute(AttributeKey::SCOPE, $mutatingScope); $this->nodeScopeResolverProcessNodes($trait->stmts, $mutatingScope, $nodeCallback); - $this->decorateTraitAttrGroups($trait, $mutatingScope); return; } @@ -521,6 +554,5 @@ private function processTrait(Trait_ $trait, MutatingScope $mutatingScope, calla $trait->setAttribute(AttributeKey::SCOPE, $traitScope); $this->nodeScopeResolverProcessNodes($trait->stmts, $traitScope, $nodeCallback); - $this->decorateTraitAttrGroups($trait, $traitScope); } } From c785c65d45b3f63e7cfe869c8a06ad6bce63031b Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 18 Sep 2024 20:42:50 +0700 Subject: [PATCH 3/3] Fix phpstan --- .../PHPStan/Scope/PHPStanNodeScopeResolver.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php index c4a3e8212b..e384e2f1ad 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php +++ b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php @@ -373,6 +373,9 @@ private function processArrayItem(ArrayItem $arrayItem, MutatingScope $mutatingS $arrayItem->value->setAttribute(AttributeKey::SCOPE, $mutatingScope); } + /** + * @param callable(Node $trait, MutatingScope $scope): void $nodeCallback + */ private function decorateNodeAttrGroups(Node $node, MutatingScope $mutatingScope, callable $nodeCallback): void { // better to have AttrGroupsAwareInterface for all Node definition with attrGroups property