19
19
use PHPStan \Reflection \ClassConstantReflection ;
20
20
use PHPStan \Reflection \ClassMemberAccessAnswerer ;
21
21
use PHPStan \Reflection \ClassReflection ;
22
+ use PHPStan \Reflection \Dummy \DummyPropertyReflection ;
22
23
use PHPStan \Reflection \ExtendedMethodReflection ;
23
24
use PHPStan \Reflection \ExtendedPropertyReflection ;
24
25
use PHPStan \Reflection \Php \UniversalObjectCratesClassReflectionExtension ;
25
26
use PHPStan \Reflection \PropertyReflection ;
26
27
use PHPStan \Reflection \ReflectionProviderStaticAccessor ;
27
28
use PHPStan \Reflection \TrivialParametersAcceptor ;
29
+ use PHPStan \Reflection \Type \CallbackUnresolvedPropertyPrototypeReflection ;
28
30
use PHPStan \Reflection \Type \CalledOnTypeUnresolvedMethodPrototypeReflection ;
29
31
use PHPStan \Reflection \Type \CalledOnTypeUnresolvedPropertyPrototypeReflection ;
30
32
use PHPStan \Reflection \Type \UnionTypeUnresolvedPropertyPrototypeReflection ;
@@ -158,7 +160,8 @@ public function hasProperty(string $propertyName): TrinaryLogic
158
160
return TrinaryLogic::createMaybe ();
159
161
}
160
162
161
- if ($ classReflection ->hasProperty ($ propertyName )) {
163
+ $ classHasProperty = RecursionGuard::run ($ this , static fn (): bool => $ classReflection ->hasProperty ($ propertyName ));
164
+ if ($ classHasProperty === true || $ classHasProperty instanceof ErrorType) {
162
165
return TrinaryLogic::createYes ();
163
166
}
164
167
@@ -224,7 +227,17 @@ public function getUnresolvedPropertyPrototype(string $propertyName, ClassMember
224
227
throw new ClassNotFoundException ($ this ->className );
225
228
}
226
229
227
- $ property = $ nakedClassReflection ->getProperty ($ propertyName , $ scope );
230
+ $ property = RecursionGuard::run ($ this , static fn () => $ nakedClassReflection ->getProperty ($ propertyName , $ scope ));
231
+ if ($ property instanceof ErrorType) {
232
+ $ property = new DummyPropertyReflection ();
233
+
234
+ return new CallbackUnresolvedPropertyPrototypeReflection (
235
+ $ property ,
236
+ $ property ->getDeclaringClass (),
237
+ false ,
238
+ static fn (Type $ type ): Type => $ type ,
239
+ );
240
+ }
228
241
229
242
$ ancestor = $ this ->getAncestorWithClassName ($ property ->getDeclaringClass ()->getName ());
230
243
$ resolvedClassReflection = null ;
@@ -246,6 +259,9 @@ public function getUnresolvedPropertyPrototype(string $propertyName, ClassMember
246
259
);
247
260
}
248
261
262
+ /**
263
+ * @deprecated Not in use anymore.
264
+ */
249
265
public function getPropertyWithoutTransformingStatic (string $ propertyName , ClassMemberAccessAnswerer $ scope ): PropertyReflection
250
266
{
251
267
$ classReflection = $ this ->getNakedClassReflection ();
0 commit comments