Skip to content

Commit dae5a6c

Browse files
committed
Introduce DeepNodeCloner
1 parent 427ac6b commit dae5a6c

File tree

7 files changed

+42
-7
lines changed

7 files changed

+42
-7
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
use PhpParser\Node\Stmt\While_;
5757
use PhpParser\NodeFinder;
5858
use PhpParser\NodeTraverser;
59-
use PhpParser\NodeVisitor\CloningVisitor;
6059
use PhpParser\NodeVisitorAbstract;
6160
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass;
6261
use PHPStan\BetterReflection\Reflection\ReflectionEnum;
@@ -81,6 +80,7 @@
8180
use PHPStan\Node\ClassPropertyNode;
8281
use PHPStan\Node\ClassStatementsGatherer;
8382
use PHPStan\Node\ClosureReturnStatementsNode;
83+
use PHPStan\Node\DeepNodeCloner;
8484
use PHPStan\Node\DoWhileLoopConditionNode;
8585
use PHPStan\Node\ExecutionEndNode;
8686
use PHPStan\Node\Expr\AlwaysRememberedExpr;
@@ -270,6 +270,7 @@ public function __construct(
270270
private readonly ParameterClosureThisExtensionProvider $parameterClosureThisExtensionProvider,
271271
private readonly ParameterClosureTypeExtensionProvider $parameterClosureTypeExtensionProvider,
272272
private readonly ScopeFactory $scopeFactory,
273+
private readonly DeepNodeCloner $deepNodeCloner,
273274
#[AutowiredParameter]
274275
private readonly bool $polluteScopeWithLoopInitialAssignments,
275276
#[AutowiredParameter]
@@ -2059,12 +2060,7 @@ public function __invoke(Node $node, Scope $scope): void
20592060
$throwPoints = array_merge($throwPoints, $exprResult->getThrowPoints());
20602061
$impurePoints = array_merge($impurePoints, $exprResult->getImpurePoints());
20612062
if ($var instanceof ArrayDimFetch && $var->dim !== null) {
2062-
$cloningTraverser = new NodeTraverser();
2063-
$cloningTraverser->addVisitor(new CloningVisitor());
2064-
2065-
/** @var Expr $clonedVar */
2066-
[$clonedVar] = $cloningTraverser->traverse([$var->var]);
2067-
2063+
$clonedVar = $this->deepNodeCloner->cloneNode($var->var);
20682064
$traverser = new NodeTraverser();
20692065
$traverser->addVisitor(new class () extends NodeVisitorAbstract {
20702066

src/Node/DeepNodeCloner.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Node;
4+
5+
use PhpParser\Node;
6+
use PhpParser\NodeTraverser;
7+
use PhpParser\NodeVisitor\CloningVisitor;
8+
use PHPStan\DependencyInjection\AutowiredService;
9+
10+
#[AutowiredService]
11+
final class DeepNodeCloner
12+
{
13+
14+
/**
15+
* @template T of Node
16+
* @param T $node
17+
* @return T
18+
*/
19+
public function cloneNode(Node $node): Node
20+
{
21+
$traverser = new NodeTraverser(new CloningVisitor());
22+
23+
[$clonedNode] = $traverser->traverse([$node]);
24+
25+
/** @var T */
26+
return $clonedNode;
27+
}
28+
29+
}

src/Testing/RuleTestCase.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use PHPStan\File\FileHelper;
2828
use PHPStan\File\FileReader;
2929
use PHPStan\Fixable\Patcher;
30+
use PHPStan\Node\DeepNodeCloner;
3031
use PHPStan\Node\Printer\ExprPrinter;
3132
use PHPStan\Php\PhpVersion;
3233
use PHPStan\PhpDoc\PhpDocInheritanceResolver;
@@ -121,6 +122,7 @@ protected function createNodeScopeResolver(): NodeScopeResolver|GeneratorNodeSco
121122
self::getContainer()->getByType(ParameterClosureThisExtensionProvider::class),
122123
self::getContainer()->getByType(ParameterClosureTypeExtensionProvider::class),
123124
self::createScopeFactory($reflectionProvider, $typeSpecifier),
125+
self::getContainer()->getByType(DeepNodeCloner::class),
124126
$this->shouldPolluteScopeWithLoopInitialAssignments(),
125127
$this->shouldPolluteScopeWithAlwaysIterableForeach(),
126128
self::getContainer()->getParameter('polluteScopeWithBlock'),

src/Testing/TypeInferenceTestCase.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use PHPStan\DependencyInjection\Type\ParameterOutTypeExtensionProvider;
2020
use PHPStan\File\FileHelper;
2121
use PHPStan\File\SystemAgnosticSimpleRelativePathHelper;
22+
use PHPStan\Node\DeepNodeCloner;
2223
use PHPStan\Node\InClassNode;
2324
use PHPStan\Node\Printer\ExprPrinter;
2425
use PHPStan\Php\PhpVersion;
@@ -95,6 +96,7 @@ protected static function createNodeScopeResolver(): NodeScopeResolver|Generator
9596
$container->getByType(ParameterClosureThisExtensionProvider::class),
9697
$container->getByType(ParameterClosureTypeExtensionProvider::class),
9798
self::createScopeFactory($reflectionProvider, $typeSpecifier),
99+
self::getContainer()->getByType(DeepNodeCloner::class),
98100
$container->getParameter('polluteScopeWithLoopInitialAssignments'),
99101
$container->getParameter('polluteScopeWithAlwaysIterableForeach'),
100102
$container->getParameter('polluteScopeWithBlock'),

tests/PHPStan/Analyser/AnalyserTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use PHPStan\DependencyInjection\Type\ParameterClosureThisExtensionProvider;
1818
use PHPStan\DependencyInjection\Type\ParameterClosureTypeExtensionProvider;
1919
use PHPStan\DependencyInjection\Type\ParameterOutTypeExtensionProvider;
20+
use PHPStan\Node\DeepNodeCloner;
2021
use PHPStan\Node\Printer\ExprPrinter;
2122
use PHPStan\Node\Printer\Printer;
2223
use PHPStan\Parser\RichParser;
@@ -822,6 +823,7 @@ private function createAnalyser(): Analyser
822823
$container->getByType(ParameterClosureThisExtensionProvider::class),
823824
$container->getByType(ParameterClosureTypeExtensionProvider::class),
824825
self::createScopeFactory($reflectionProvider, $typeSpecifier),
826+
$container->getByType(DeepNodeCloner::class),
825827
false,
826828
true,
827829
true,

tests/PHPStan/Analyser/Fiber/FiberNodeScopeResolverRuleTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\DependencyInjection\Type\ParameterClosureTypeExtensionProvider;
1111
use PHPStan\DependencyInjection\Type\ParameterOutTypeExtensionProvider;
1212
use PHPStan\File\FileHelper;
13+
use PHPStan\Node\DeepNodeCloner;
1314
use PHPStan\Php\PhpVersion;
1415
use PHPStan\PhpDoc\PhpDocInheritanceResolver;
1516
use PHPStan\Reflection\ClassReflectionFactory;
@@ -130,6 +131,7 @@ protected function createNodeScopeResolver(): NodeScopeResolver
130131
self::getContainer()->getByType(ParameterClosureThisExtensionProvider::class),
131132
self::getContainer()->getByType(ParameterClosureTypeExtensionProvider::class),
132133
self::createScopeFactory($reflectionProvider, $typeSpecifier),
134+
self::getContainer()->getByType(DeepNodeCloner::class),
133135
$this->shouldPolluteScopeWithLoopInitialAssignments(),
134136
$this->shouldPolluteScopeWithAlwaysIterableForeach(),
135137
self::getContainer()->getParameter('polluteScopeWithBlock'),

tests/PHPStan/Analyser/Fiber/FiberNodeScopeResolverTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PHPStan\DependencyInjection\Type\ParameterClosureTypeExtensionProvider;
99
use PHPStan\DependencyInjection\Type\ParameterOutTypeExtensionProvider;
1010
use PHPStan\File\FileHelper;
11+
use PHPStan\Node\DeepNodeCloner;
1112
use PHPStan\Php\PhpVersion;
1213
use PHPStan\PhpDoc\PhpDocInheritanceResolver;
1314
use PHPStan\Reflection\ClassReflectionFactory;
@@ -63,6 +64,7 @@ protected static function createNodeScopeResolver(): NodeScopeResolver
6364
$container->getByType(ParameterClosureThisExtensionProvider::class),
6465
$container->getByType(ParameterClosureTypeExtensionProvider::class),
6566
self::createScopeFactory($reflectionProvider, $typeSpecifier),
67+
$container->getByType(DeepNodeCloner::class),
6668
$container->getParameter('polluteScopeWithLoopInitialAssignments'),
6769
$container->getParameter('polluteScopeWithAlwaysIterableForeach'),
6870
$container->getParameter('polluteScopeWithBlock'),

0 commit comments

Comments
 (0)