From 07c1fba85c5fa2e1827634489d82b625c68d8314 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 10 Sep 2024 09:35:49 +0700 Subject: [PATCH 1/3] [Performance] No need traverse WrappedNodeRestoringNodeVisitor when no AlwaysRememberedExpr in PHPStan processNodes() --- .../Scope/PHPStanNodeScopeResolver.php | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php index 93aab58590..0e4f7db9dc 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php +++ b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php @@ -49,6 +49,7 @@ use PHPStan\Analyser\MutatingScope; use PHPStan\Analyser\NodeScopeResolver; use PHPStan\Analyser\ScopeContext; +use PHPStan\Node\Expr\AlwaysRememberedExpr; use PHPStan\Node\UnreachableStatementNode; use PHPStan\Node\VirtualNode; use PHPStan\Reflection\ReflectionProvider; @@ -118,11 +119,18 @@ public function processNodes( $scope = $formerMutatingScope ?? $this->scopeFactory->createFromFile($filePath); $hasUnreachableStatementNode = false; + $hasRememberedExpr = false; + $nodeCallback = function (Node $node, MutatingScope $mutatingScope) use ( &$nodeCallback, $filePath, - &$hasUnreachableStatementNode + &$hasUnreachableStatementNode, + &$hasRememberedExpr ): void { + if ($node instanceof AlwaysRememberedExpr) { + $hasRememberedExpr = true; + } + // the class reflection is resolved AFTER entering to class node // so we need to get it from the first after this one if ($node instanceof Class_ || $node instanceof Interface_ || $node instanceof Enum_) { @@ -280,8 +288,17 @@ public function processNodes( $this->nodeScopeResolverProcessNodes($stmts, $scope, $nodeCallback); + // no AlwaysRememberedExpr instance and no unreachable statement + // return early stmts, no need another traverse + if (! $hasRememberedExpr && ! $hasUnreachableStatementNode) { + return $stmts; + } + $nodeTraverser = new NodeTraverser(); - $nodeTraverser->addVisitor(new WrappedNodeRestoringNodeVisitor()); + + if ($hasRememberedExpr) { + $nodeTraverser->addVisitor(new WrappedNodeRestoringNodeVisitor()); + } if ($hasUnreachableStatementNode) { $nodeTraverser->addVisitor(new UnreachableStatementNodeVisitor($this, $filePath, $scope)); From a6b3c3291b05c36e54d20faae43b487125a7cc2a Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 10 Sep 2024 09:39:35 +0700 Subject: [PATCH 2/3] check on Match_ --- .../PHPStan/Scope/PHPStanNodeScopeResolver.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php index 0e4f7db9dc..47783068f3 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php +++ b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php @@ -127,10 +127,6 @@ public function processNodes( &$hasUnreachableStatementNode, &$hasRememberedExpr ): void { - if ($node instanceof AlwaysRememberedExpr) { - $hasRememberedExpr = true; - } - // the class reflection is resolved AFTER entering to class node // so we need to get it from the first after this one if ($node instanceof Class_ || $node instanceof Interface_ || $node instanceof Enum_) { @@ -282,6 +278,7 @@ public function processNodes( if ($node instanceof Match_) { $this->processMatch($node, $mutatingScope); + $hasRememberedExpr = true; return; } }; From 2cc430ad3d27de54c3a8bffb0cf02aaab53c4938 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Tue, 10 Sep 2024 09:40:45 +0700 Subject: [PATCH 3/3] check on Match_ --- .../PHPStan/Scope/PHPStanNodeScopeResolver.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php index 47783068f3..ac9b8f8510 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php +++ b/src/NodeTypeResolver/PHPStan/Scope/PHPStanNodeScopeResolver.php @@ -49,7 +49,6 @@ use PHPStan\Analyser\MutatingScope; use PHPStan\Analyser\NodeScopeResolver; use PHPStan\Analyser\ScopeContext; -use PHPStan\Node\Expr\AlwaysRememberedExpr; use PHPStan\Node\UnreachableStatementNode; use PHPStan\Node\VirtualNode; use PHPStan\Reflection\ReflectionProvider; @@ -119,13 +118,13 @@ public function processNodes( $scope = $formerMutatingScope ?? $this->scopeFactory->createFromFile($filePath); $hasUnreachableStatementNode = false; - $hasRememberedExpr = false; + $hasMatch = false; $nodeCallback = function (Node $node, MutatingScope $mutatingScope) use ( &$nodeCallback, $filePath, &$hasUnreachableStatementNode, - &$hasRememberedExpr + &$hasMatch ): void { // the class reflection is resolved AFTER entering to class node // so we need to get it from the first after this one @@ -278,22 +277,22 @@ public function processNodes( if ($node instanceof Match_) { $this->processMatch($node, $mutatingScope); - $hasRememberedExpr = true; + $hasMatch = true; return; } }; $this->nodeScopeResolverProcessNodes($stmts, $scope, $nodeCallback); - // no AlwaysRememberedExpr instance and no unreachable statement + // no Match_ instance and no unreachable statement // return early stmts, no need another traverse - if (! $hasRememberedExpr && ! $hasUnreachableStatementNode) { + if (! $hasMatch && ! $hasUnreachableStatementNode) { return $stmts; } $nodeTraverser = new NodeTraverser(); - if ($hasRememberedExpr) { + if ($hasMatch) { $nodeTraverser->addVisitor(new WrappedNodeRestoringNodeVisitor()); }