Skip to content

Commit

Permalink
fix: crash when trying to resolve methods from abstract class with in…
Browse files Browse the repository at this point in the history
…terface and with method referencing self

I have encountered the issue when working with brick/math, namely `BigNumber::of()`.
  • Loading branch information
simPod committed Aug 17, 2023
1 parent 1964d41 commit e2d8b60
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
}

Expand Down
10 changes: 10 additions & 0 deletions tests/Fixture/Object/AbstractObjectWithInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace CuyZ\Valinor\Tests\Fixture\Object;

abstract class AbstractObjectWithInterface implements \JsonSerializable
{
public static function of(AbstractObjectWithInterface $value): void {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use CuyZ\Valinor\Tests\Fake\Definition\Repository\FakeAttributesRepository;
use CuyZ\Valinor\Tests\Fake\Type\FakeType;
use CuyZ\Valinor\Tests\Fake\Type\Parser\Factory\FakeTypeParserFactory;
use CuyZ\Valinor\Tests\Fixture\Object\AbstractObjectWithInterface;
use CuyZ\Valinor\Type\StringType;
use CuyZ\Valinor\Type\Types\NativeClassType;
use CuyZ\Valinor\Type\Types\MixedType;
Expand Down Expand Up @@ -145,6 +146,15 @@ public function publicMethodWithNativeAndDocBlockReturnTypes(): string
self::assertSame('Optional parameter value', $optionalParameter->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));
Expand Down

0 comments on commit e2d8b60

Please sign in to comment.