55namespace Rector \Renaming \Rector \Name ;
66
77use PhpParser \Node ;
8- use PhpParser \Node \Expr \ClassConstFetch ;
98use PhpParser \Node \FunctionLike ;
10- use PhpParser \Node \Identifier ;
119use PhpParser \Node \Name ;
1210use PhpParser \Node \Name \FullyQualified ;
1311use PhpParser \Node \Stmt \ClassLike ;
1412use PhpParser \Node \Stmt \Expression ;
1513use PhpParser \Node \Stmt \If_ ;
1614use PhpParser \Node \Stmt \Property ;
17- use PhpParser \NodeVisitor ;
1815use PHPStan \Reflection \ReflectionProvider ;
1916use Rector \Configuration \RenamedClassesDataCollector ;
2017use Rector \Contract \Rector \ConfigurableRectorInterface ;
@@ -80,7 +77,6 @@ function someFunction(SomeNewClass $someOldClass): SomeNewClass
8077 public function getNodeTypes (): array
8178 {
8279 return [
83- ClassConstFetch::class,
8480 // place FullyQualified before Name on purpose executed early before the Name as parent
8581 FullyQualified::class,
8682 // Name as parent of FullyQualified executed later for fallback annotation to attribute rename to Name
@@ -94,19 +90,21 @@ public function getNodeTypes(): array
9490 }
9591
9692 /**
97- * @param ClassConstFetch|FunctionLike|FullyQualified|Name|ClassLike|Expression|Property|If_ $node
98- * @return null|NodeVisitor::DONT_TRAVERSE_CHILDREN|Node
93+ * @param FunctionLike|FullyQualified|Name|ClassLike|Expression|Property|If_ $node
9994 */
100- public function refactor (Node $ node ): int | null | Node
95+ public function refactor (Node $ node ): ? Node
10196 {
10297 $ oldToNewClasses = $ this ->renamedClassesDataCollector ->getOldToNewClasses ();
10398
10499 if ($ oldToNewClasses === []) {
105100 return null ;
106101 }
107102
108- if ($ node instanceof ClassConstFetch) {
109- return $ this ->processClassConstFetch ($ node , $ oldToNewClasses );
103+ if ($ node instanceof FullyQualified && $ this ->shouldSkipClassConstFetchForMissingConstantName (
104+ $ node ,
105+ $ oldToNewClasses
106+ )) {
107+ return null ;
110108 }
111109
112110 $ scope = $ node ->getAttribute (AttributeKey::SCOPE );
@@ -126,18 +124,29 @@ public function configure(array $configuration): void
126124
127125 /**
128126 * @param array<string, string> $oldToNewClasses
129- * @return null|NodeVisitor::DONT_TRAVERSE_CHILDREN
130127 */
131- private function processClassConstFetch (ClassConstFetch $ classConstFetch , array $ oldToNewClasses ): int |null
132- {
133- if (! $ classConstFetch ->class instanceof FullyQualified
134- || ! $ classConstFetch ->name instanceof Identifier
135- || ! $ this ->reflectionProvider ->hasClass ($ classConstFetch ->class ->toString ())) {
136- return null ;
128+ private function shouldSkipClassConstFetchForMissingConstantName (
129+ FullyQualified $ fullyQualified ,
130+ array $ oldToNewClasses
131+ ): bool {
132+ if (! $ this ->reflectionProvider ->hasClass ($ fullyQualified ->toString ())) {
133+ return false ;
134+ }
135+
136+ // not part of class const fetch (e.g. SomeClass::SOME_VALUE)
137+ $ constFetchName = $ fullyQualified ->getAttribute (AttributeKey::CLASS_CONST_FETCH_NAME );
138+ if (! is_string ($ constFetchName )) {
139+ return false ;
137140 }
138141
142+ // if (! $classConstFetch->class instanceof FullyQualified
143+ // || ! $classConstFetch->name instanceof Identifier
144+ // || ! $this->reflectionProvider->hasClass($classConstFetch->class->toString())) {
145+ // return null;
146+ // }
147+
139148 foreach ($ oldToNewClasses as $ oldClass => $ newClass ) {
140- if (! $ this ->isName ($ classConstFetch -> class , $ oldClass )) {
149+ if (! $ this ->isName ($ fullyQualified , $ oldClass )) {
141150 continue ;
142151 }
143152
@@ -146,20 +155,20 @@ private function processClassConstFetch(ClassConstFetch $classConstFetch, array
146155 }
147156
148157 $ classReflection = $ this ->reflectionProvider ->getClass ($ newClass );
149- if (! $ classReflection ->isInterface ()) {
150- continue ;
151- }
158+ // if (! $classReflection->isInterface()) {
159+ // continue;
160+ // }
152161
153162 $ oldClassReflection = $ this ->reflectionProvider ->getClass ($ oldClass );
154163
155- if ($ oldClassReflection ->hasConstant ($ classConstFetch ->name ->toString ())
156- && ! $ classReflection ->hasConstant ($ classConstFetch ->name ->toString ())) {
157- // no constant found on new interface? skip node below ClassConstFetch on this rule
158- return NodeVisitor::DONT_TRAVERSE_CHILDREN ;
164+ if ($ oldClassReflection ->hasConstant ($ constFetchName ) && ! $ classReflection ->hasConstant ($ constFetchName )) {
165+ // should be skipped
166+ return true ;
159167 }
160168 }
161169
162- // continue to next Name usage
163- return null ;
170+ return false ;
171+
172+ // return $this->classRenamer->renameNode($fullyQualified, $oldToNewClasses, $scope);
164173 }
165174}
0 commit comments