diff --git a/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php b/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php index 5140d865..16160df4 100644 --- a/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php +++ b/src/Definition/Repository/Reflection/ReflectionClassDefinitionRepository.php @@ -32,6 +32,7 @@ use function array_filter; use function array_keys; use function array_map; +use function interface_exists; /** @internal */ final class ReflectionClassDefinitionRepository implements ClassDefinitionRepository @@ -114,7 +115,7 @@ private function typeResolver(ClassType $type, string $targetClass): ReflectionT return $this->typeResolver[$typeKey]; } - while ($type->className() !== $targetClass) { + while ($type->className() !== $targetClass && ! interface_exists($targetClass)) { $type = $type->parent(); } diff --git a/tests/Fixture/Object/AbstractObjectWithInterface.php b/tests/Fixture/Object/AbstractObjectWithInterface.php new file mode 100644 index 00000000..b3a7d6d0 --- /dev/null +++ b/tests/Fixture/Object/AbstractObjectWithInterface.php @@ -0,0 +1,10 @@ +defaultValue()); } + public function test_methods_can_be_retrieved_from_abstract_object_with_interface_and_with_method_referencing_self(): void + { + $type = new NativeClassType(AbstractObjectWithInterface::class); + $methods = $this->repository->for($type)->methods(); + + self::assertTrue($methods->has('of')); + self::assertTrue($methods->has('jsonSerialize')); + } + public function test_private_parent_constructor_is_listed_in_methods(): void { $type = new NativeClassType(ClassWithInheritedPrivateConstructor::class, parent: new NativeClassType(AbstractClassWithPrivateConstructor::class));