Skip to content

Commit

Permalink
Merge pull request #898 from kukulich/stringable
Browse files Browse the repository at this point in the history
We should add `Stringable` interface only when it can be reflected
  • Loading branch information
Ocramius authored Dec 5, 2021
2 parents c6c9b85 + 53d433b commit ff18794
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/Reflection/ReflectionClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -1112,7 +1112,16 @@ private function addStringableInterface(array $interfaces): array

foreach ($this->node->getMethods() as $methodNode) {
if ($methodNode->name->toLowerString() === '__tostring') {
$interfaces[$stringableClassName] = $this->reflectClassForNamedNode(new Node\Name(Stringable::class));
try {
$stringableInterfaceReflection = $this->reflectClassForNamedNode(new Node\Name($stringableClassName));

if ($stringableInterfaceReflection->isInternal()) {
$interfaces[$stringableClassName] = $stringableInterfaceReflection;
}
} catch (IdentifierNotFound) {
// Stringable interface does not exist on target PHP version
}

break;
}
}
Expand Down
44 changes: 44 additions & 0 deletions test/unit/Reflection/ReflectionClassTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2383,6 +2383,50 @@ public function __toString();
self::assertArrayHasKey(Stringable::class, $interfaceNotExtendingStringable->getImmediateInterfaces());
}

public function testNoStringableInterfaceWhenStringableNotFound(): void
{
$php = <<<'PHP'
<?php
class NoStringable
{
public function __toString(): string
{
}
}
PHP;

$reflector = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));

$noStringable = $reflector->reflectClass('NoStringable');

self::assertNotContains(Stringable::class, $noStringable->getInterfaceNames());
}

public function testNoStringableInterfaceWhenStringableIsNotInternal(): void
{
$php = <<<'PHP'
<?php
class Stringable
{
}
class NoStringable
{
public function __toString(): string
{
}
}
PHP;

$reflector = new DefaultReflector(new StringSourceLocator($php, $this->astLocator));

$noStringable = $reflector->reflectClass('NoStringable');

self::assertNotContains(Stringable::class, $noStringable->getInterfaceNames());
}

public function testHasAllInterfacesWithStringable(): void
{
$php = <<<'PHP'
Expand Down

0 comments on commit ff18794

Please sign in to comment.