Skip to content

Commit 0df4a31

Browse files
authored
Merge pull request #1524 from staabm/trait
Support indirect `Stringable` interface via `__toString()` in trait
2 parents 8068fe1 + 9f3bebd commit 0df4a31

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

src/Reflection/ReflectionClass.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,12 @@ private function addStringableInterface(array $interfaces): array
13151315
return $interfaces;
13161316
}
13171317

1318-
foreach (array_keys($this->immediateMethods) as $immediateMethodName) {
1318+
$methods = $this->immediateMethods;
1319+
foreach ($this->getTraits() as $trait) {
1320+
$methods += $trait->immediateMethods;
1321+
}
1322+
1323+
foreach (array_keys($methods) as $immediateMethodName) {
13191324
if (strtolower($immediateMethodName) === '__tostring') {
13201325
try {
13211326
$stringableInterfaceReflection = $this->reflector->reflectClass($stringableClassName);

test/unit/Reflection/ReflectionClassTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2878,6 +2878,30 @@ public function __toString(): string
28782878
self::assertSame(['Iterator', 'Traversable', 'Stringable'], $class->getInterfaceNames());
28792879
}
28802880

2881+
public function testStringableViaTrait(): void
2882+
{
2883+
$php = <<<'PHP'
2884+
<?php
2885+
2886+
trait HasStringableTrait {
2887+
public function __toString(): string { return 'foo'; }
2888+
}
2889+
2890+
class ClassHasStringableTrait {
2891+
use HasStringableTrait;
2892+
}
2893+
PHP;
2894+
2895+
$reflector = new DefaultReflector(new AggregateSourceLocator([
2896+
new StringSourceLocator($php, $this->astLocator),
2897+
BetterReflectionSingleton::instance()->sourceLocator(),
2898+
]));
2899+
2900+
$class = $reflector->reflectClass('ClassHasStringableTrait');
2901+
2902+
self::assertSame(['Stringable'], $class->getInterfaceNames());
2903+
}
2904+
28812905
/** @return list<array{0: string, 1: bool}> */
28822906
public static function deprecatedProvider(): array
28832907
{

0 commit comments

Comments
 (0)