26
26
use Rector \Core \Exclusion \ExclusionManager ;
27
27
use Rector \Core \Logging \CurrentRectorProvider ;
28
28
use Rector \Core \NodeAnalyzer \ChangedNodeAnalyzer ;
29
+ use Rector \Core \NodeDecorator \CreatedByRuleDecorator ;
29
30
use Rector \Core \Php \PhpVersionProvider ;
30
31
use Rector \Core \PhpParser \Comparing \NodeComparator ;
31
32
use Rector \Core \PhpParser \Node \BetterNodeFinder ;
@@ -170,10 +171,14 @@ abstract class AbstractRector extends \PhpParser\NodeVisitorAbstract implements
170
171
* @var \Rector\Core\ProcessAnalyzer\RectifiedAnalyzer
171
172
*/
172
173
private $ rectifiedAnalyzer ;
174
+ /**
175
+ * @var \Rector\Core\NodeDecorator\CreatedByRuleDecorator
176
+ */
177
+ private $ createdByRuleDecorator ;
173
178
/**
174
179
* @required
175
180
*/
176
- public function autowire (\Rector \PostRector \Collector \NodesToRemoveCollector $ nodesToRemoveCollector , \Rector \PostRector \Collector \NodesToAddCollector $ nodesToAddCollector , \Rector \NodeRemoval \NodeRemover $ nodeRemover , \Rector \Core \Application \FileSystem \RemovedAndAddedFilesCollector $ removedAndAddedFilesCollector , \Rector \Core \PhpParser \Printer \BetterStandardPrinter $ betterStandardPrinter , \Rector \NodeNameResolver \NodeNameResolver $ nodeNameResolver , \Rector \NodeTypeResolver \NodeTypeResolver $ nodeTypeResolver , \RectorPrefix20211231 \Symplify \Astral \NodeTraverser \SimpleCallableNodeTraverser $ simpleCallableNodeTraverser , \Rector \Core \PhpParser \Node \NodeFactory $ nodeFactory , \Rector \BetterPhpDocParser \PhpDocInfo \PhpDocInfoFactory $ phpDocInfoFactory , \RectorPrefix20211231 \Symfony \Component \Console \Style \SymfonyStyle $ symfonyStyle , \Rector \Core \Php \PhpVersionProvider $ phpVersionProvider , \Rector \Core \Exclusion \ExclusionManager $ exclusionManager , \Rector \StaticTypeMapper \StaticTypeMapper $ staticTypeMapper , \RectorPrefix20211231 \Symplify \PackageBuilder \Parameter \ParameterProvider $ parameterProvider , \Rector \Core \Logging \CurrentRectorProvider $ currentRectorProvider , \Rector \Core \Configuration \CurrentNodeProvider $ currentNodeProvider , \RectorPrefix20211231 \Symplify \Skipper \Skipper \Skipper $ skipper , \Rector \Core \PhpParser \Node \Value \ValueResolver $ valueResolver , \Rector \Core \PhpParser \Node \BetterNodeFinder $ betterNodeFinder , \Rector \Core \PhpParser \Comparing \NodeComparator $ nodeComparator , \Rector \Core \Provider \CurrentFileProvider $ currentFileProvider , \Rector \Core \NodeAnalyzer \ChangedNodeAnalyzer $ changedNodeAnalyzer , \Rector \Core \Validation \InfiniteLoopValidator $ infiniteLoopValidator , \Rector \Core \ProcessAnalyzer \RectifiedAnalyzer $ rectifiedAnalyzer ) : void
181
+ public function autowire (\Rector \PostRector \Collector \NodesToRemoveCollector $ nodesToRemoveCollector , \Rector \PostRector \Collector \NodesToAddCollector $ nodesToAddCollector , \Rector \NodeRemoval \NodeRemover $ nodeRemover , \Rector \Core \Application \FileSystem \RemovedAndAddedFilesCollector $ removedAndAddedFilesCollector , \Rector \Core \PhpParser \Printer \BetterStandardPrinter $ betterStandardPrinter , \Rector \NodeNameResolver \NodeNameResolver $ nodeNameResolver , \Rector \NodeTypeResolver \NodeTypeResolver $ nodeTypeResolver , \RectorPrefix20211231 \Symplify \Astral \NodeTraverser \SimpleCallableNodeTraverser $ simpleCallableNodeTraverser , \Rector \Core \PhpParser \Node \NodeFactory $ nodeFactory , \Rector \BetterPhpDocParser \PhpDocInfo \PhpDocInfoFactory $ phpDocInfoFactory , \RectorPrefix20211231 \Symfony \Component \Console \Style \SymfonyStyle $ symfonyStyle , \Rector \Core \Php \PhpVersionProvider $ phpVersionProvider , \Rector \Core \Exclusion \ExclusionManager $ exclusionManager , \Rector \StaticTypeMapper \StaticTypeMapper $ staticTypeMapper , \RectorPrefix20211231 \Symplify \PackageBuilder \Parameter \ParameterProvider $ parameterProvider , \Rector \Core \Logging \CurrentRectorProvider $ currentRectorProvider , \Rector \Core \Configuration \CurrentNodeProvider $ currentNodeProvider , \RectorPrefix20211231 \Symplify \Skipper \Skipper \Skipper $ skipper , \Rector \Core \PhpParser \Node \Value \ValueResolver $ valueResolver , \Rector \Core \PhpParser \Node \BetterNodeFinder $ betterNodeFinder , \Rector \Core \PhpParser \Comparing \NodeComparator $ nodeComparator , \Rector \Core \Provider \CurrentFileProvider $ currentFileProvider , \Rector \Core \NodeAnalyzer \ChangedNodeAnalyzer $ changedNodeAnalyzer , \Rector \Core \Validation \InfiniteLoopValidator $ infiniteLoopValidator , \Rector \Core \ProcessAnalyzer \RectifiedAnalyzer $ rectifiedAnalyzer , \Rector \Core \NodeDecorator \CreatedByRuleDecorator $ createdByRuleDecorator ) : void
177
182
{
178
183
$ this ->nodesToRemoveCollector = $ nodesToRemoveCollector ;
179
184
$ this ->nodesToAddCollector = $ nodesToAddCollector ;
@@ -200,6 +205,7 @@ public function autowire(\Rector\PostRector\Collector\NodesToRemoveCollector $no
200
205
$ this ->changedNodeAnalyzer = $ changedNodeAnalyzer ;
201
206
$ this ->infiniteLoopValidator = $ infiniteLoopValidator ;
202
207
$ this ->rectifiedAnalyzer = $ rectifiedAnalyzer ;
208
+ $ this ->createdByRuleDecorator = $ createdByRuleDecorator ;
203
209
}
204
210
/**
205
211
* @return Node[]|null
@@ -235,7 +241,12 @@ public final function enterNode(\PhpParser\Node $node)
235
241
$ originalAttributes = $ node ->getAttributes ();
236
242
$ originalNode = $ node ->getAttribute (\Rector \NodeTypeResolver \Node \AttributeKey::ORIGINAL_NODE ) ?? clone $ node ;
237
243
$ node = $ this ->refactor ($ node );
244
+ // nothing to change → continue
245
+ if ($ node === null ) {
246
+ return null ;
247
+ }
238
248
if (\is_array ($ node )) {
249
+ $ this ->createdByRuleDecorator ->decorate ($ originalNode , static ::class);
239
250
$ originalNodeHash = \spl_object_hash ($ originalNode );
240
251
$ this ->nodesToReturn [$ originalNodeHash ] = $ node ;
241
252
if ($ node !== []) {
@@ -246,29 +257,28 @@ public final function enterNode(\PhpParser\Node $node)
246
257
// will be replaced in leaveNode() the original node must be passed
247
258
return $ originalNode ;
248
259
}
249
- // nothing to change → continue
250
- if (!$ node instanceof \ PhpParser \Node ) {
251
- return null ;
260
+ // not changed, return node early
261
+ if (!$ this -> changedNodeAnalyzer -> hasNodeChanged ( $ originalNode , $ node ) ) {
262
+ return $ node ;
252
263
}
253
- // changed!
254
- if ($ this ->changedNodeAnalyzer ->hasNodeChanged ($ originalNode , $ node )) {
255
- $ rectorWithLineChange = new \Rector \ChangesReporting \ValueObject \RectorWithLineChange (\get_class ($ this ), $ originalNode ->getLine ());
256
- $ this ->file ->addRectorClassWithLine ($ rectorWithLineChange );
257
- // update parents relations - must run before connectParentNodes()
258
- $ this ->mirrorAttributes ($ originalAttributes , $ node );
259
- $ this ->connectParentNodes ($ node );
260
- // is different node type? do not traverse children to avoid looping
261
- if (\get_class ($ originalNode ) !== \get_class ($ node )) {
262
- $ this ->infiniteLoopValidator ->process ($ node , $ originalNode , static ::class);
263
- // search "infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
264
- $ originalNodeHash = \spl_object_hash ($ originalNode );
265
- if ($ originalNode instanceof \PhpParser \Node \Stmt && $ node instanceof \PhpParser \Node \Expr) {
266
- $ node = new \PhpParser \Node \Stmt \Expression ($ node );
267
- }
268
- $ this ->nodesToReturn [$ originalNodeHash ] = $ node ;
269
- return $ node ;
270
- }
264
+ $ this ->createdByRuleDecorator ->decorate ($ node , static ::class);
265
+ $ rectorWithLineChange = new \Rector \ChangesReporting \ValueObject \RectorWithLineChange (\get_class ($ this ), $ originalNode ->getLine ());
266
+ $ this ->file ->addRectorClassWithLine ($ rectorWithLineChange );
267
+ // update parents relations - must run before connectParentNodes()
268
+ $ this ->mirrorAttributes ($ originalAttributes , $ node );
269
+ $ this ->connectParentNodes ($ node );
270
+ // is equals node type? return node early
271
+ if (\get_class ($ originalNode ) === \get_class ($ node )) {
272
+ return $ node ;
273
+ }
274
+ // is different node type? do not traverse children to avoid looping
275
+ $ this ->infiniteLoopValidator ->process ($ node , $ originalNode , static ::class);
276
+ // search "infinite recursion" in https://github.com/nikic/PHP-Parser/blob/master/doc/component/Walking_the_AST.markdown
277
+ $ originalNodeHash = \spl_object_hash ($ originalNode );
278
+ if ($ originalNode instanceof \PhpParser \Node \Stmt && $ node instanceof \PhpParser \Node \Expr) {
279
+ $ node = new \PhpParser \Node \Stmt \Expression ($ node );
271
280
}
281
+ $ this ->nodesToReturn [$ originalNodeHash ] = $ node ;
272
282
return $ node ;
273
283
}
274
284
/**
0 commit comments