55namespace Rector \Utils \Rector ;
66
77use PhpParser \Node ;
8- use PhpParser \Node \Expr \PropertyFetch ;
9- use PhpParser \Node \Stmt \Class_ ;
8+ use PhpParser \Node \Stmt \ClassMethod ;
109use PhpParser \Node \Stmt \If_ ;
11- use PhpParser \Node \Stmt \Property ;
1210use PHPStan \Type \ObjectType ;
1311use Rector \BetterPhpDocParser \PhpDocInfo \PhpDocInfoFactory ;
14- use Rector \NodeManipulator \ClassDependencyManipulator ;
15- use Rector \PhpParser \Node \BetterNodeFinder ;
16- use Rector \PhpParser \Node \Value \ValueResolver ;
17- use Rector \PostRector \ValueObject \PropertyMetadata ;
1812use Rector \Rector \AbstractRector ;
19- use Rector \StaticTypeMapper \StaticTypeMapper ;
13+ use Rector \StaticTypeMapper \ValueObject \ Type \ ShortenedObjectType ;
2014use Symplify \RuleDocGenerator \ValueObject \RuleDefinition ;
2115
2216final class RemoveRefactorDuplicatedNodeInstanceCheckRector extends AbstractRector
2317{
18+ public function __construct (
19+ private readonly PhpDocInfoFactory $ phpDocInfoFactory
20+ ) {
21+ }
22+
2423 public function getRuleDefinition (): RuleDefinition
2524 {
26- return new RuleDefinition ('Remove refactor() method of Rector rule double check of $node instance, if already defined in @param type ' , []);
25+ return new RuleDefinition (
26+ 'Remove refactor() method of Rector rule double check of $node instance, if already defined in @param type ' ,
27+ []
28+ );
2729 }
2830
2931 public function getNodeTypes (): array
3032 {
31- return [Node \ Stmt \ ClassMethod::class];
33+ return [ClassMethod::class];
3234 }
3335
3436 /**
35- * @param Node\Stmt\ ClassMethod $node
37+ * @param ClassMethod $node
3638 */
3739 public function refactor (Node $ node ): ?Node
3840 {
@@ -49,32 +51,48 @@ public function refactor(Node $node): ?Node
4951 return null ;
5052 }
5153
52- // remove already added properties
54+ if (! $ firstStmt ->cond instanceof Node \Expr \BooleanNot) {
55+ return null ;
56+ }
57+
58+ $ booleanNot = $ firstStmt ->cond ;
5359
54- if ($ typesToAdd === [] ) {
60+ if (! $ booleanNot -> expr instanceof Node \ Expr \Instanceof_ ) {
5561 return null ;
5662 }
5763
58- $ hasChanged = false ;
64+ $ instanceIf = $ booleanNot ->expr ;
65+ $ checkedClassType = $ this ->getType ($ instanceIf ->class );
5966
60- foreach ($ typesToAdd as $ propertyNameToAdd => $ propertyTypeToAdd ) {
61- // skip if property already exists
62- if ($ node ->getProperty ($ propertyNameToAdd ) instanceof Property) {
63- continue ;
64- }
67+ if (! $ checkedClassType instanceof ObjectType) {
68+ return null ;
69+ }
6570
66- $ this ->classDependencyManipulator ->addConstructorDependency (
67- $ node ,
68- new PropertyMetadata ($ propertyNameToAdd , new ObjectType ($ propertyTypeToAdd ))
69- );
71+ $ classReflection = $ checkedClassType ->getClassReflection ();
7072
71- $ hasChanged = true ;
73+ if (! $ classReflection ->is (Node::class)) {
74+ return null ;
7275 }
7376
74- if (! $ hasChanged ) {
77+ $ classMethodPhpDocInfo = $ this ->phpDocInfoFactory ->createFromNodeOrEmpty ($ node );
78+
79+ $ paramType = $ classMethodPhpDocInfo ->getParamType ('$node ' );
80+ if (! $ paramType instanceof ObjectType) {
7581 return null ;
7682 }
7783
84+ if ($ paramType instanceof ShortenedObjectType) {
85+ $ className = $ paramType ->getFullyQualifiedName ();
86+ } else {
87+ $ className = $ paramType ->getClassName ();
88+ }
89+
90+ if ($ className !== $ checkedClassType ->getClassName ()) {
91+ return null ;
92+ }
93+
94+ unset($ node ->stmts [0 ]);
95+
7896 return $ node ;
7997 }
8098}
0 commit comments