Skip to content

Commit 314a9cc

Browse files
committed
Hierarchy distances - collect all traits
1 parent f73c118 commit 314a9cc

File tree

4 files changed

+56
-16
lines changed

4 files changed

+56
-16
lines changed

src/Reflection/ClassReflection.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ public function getClassHierarchyDistances(): array
259259
$this->getName() => $distance,
260260
];
261261
$currentClassReflection = $this->getNativeReflection();
262-
foreach ($this->getNativeReflection()->getTraits() as $trait) {
262+
foreach ($this->collectTraits($this->getNativeReflection()) as $trait) {
263263
$distance++;
264264
if (array_key_exists($trait->getName(), $distances)) {
265265
continue;
@@ -275,7 +275,7 @@ public function getClassHierarchyDistances(): array
275275
$distances[$parentClassName] = $distance;
276276
}
277277
$currentClassReflection = $currentClassReflection->getParentClass();
278-
foreach ($currentClassReflection->getTraits() as $trait) {
278+
foreach ($this->collectTraits($currentClassReflection) as $trait) {
279279
$distance++;
280280
if (array_key_exists($trait->getName(), $distances)) {
281281
continue;
@@ -299,6 +299,33 @@ public function getClassHierarchyDistances(): array
299299
return $this->classHierarchyDistances;
300300
}
301301

302+
/**
303+
* @param \ReflectionClass $class
304+
* @return \ReflectionClass[]
305+
*/
306+
private function collectTraits(\ReflectionClass $class): array
307+
{
308+
$traits = [];
309+
$traitsLeftToAnalyze = $class->getTraits();
310+
311+
while (count($traitsLeftToAnalyze) !== 0) {
312+
$trait = reset($traitsLeftToAnalyze);
313+
$traits[] = $trait;
314+
315+
foreach ($trait->getTraits() as $subTrait) {
316+
if (in_array($subTrait, $traits, true)) {
317+
continue;
318+
}
319+
320+
$traitsLeftToAnalyze[] = $subTrait;
321+
}
322+
323+
array_shift($traitsLeftToAnalyze);
324+
}
325+
326+
return $traits;
327+
}
328+
302329
public function hasProperty(string $propertyName): bool
303330
{
304331
foreach ($this->propertiesClassReflectionExtensions as $extension) {

tests/PHPStan/Reflection/ClassReflectionTest.php

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ public function dataClassHierarchyDistances(): array
3838
[
3939
\HierarchyDistances\Lorem::class => 0,
4040
\HierarchyDistances\TraitTwo::class => 1,
41-
\HierarchyDistances\FirstLoremInterface::class => 2,
42-
\HierarchyDistances\SecondLoremInterface::class => 3,
41+
\HierarchyDistances\TraitThree::class => 2,
42+
\HierarchyDistances\FirstLoremInterface::class => 3,
43+
\HierarchyDistances\SecondLoremInterface::class => 4,
4344
],
4445
],
4546
[
@@ -50,25 +51,27 @@ public function dataClassHierarchyDistances(): array
5051
\HierarchyDistances\TraitOne::class => 1,
5152
\HierarchyDistances\Lorem::class => 2,
5253
\HierarchyDistances\TraitTwo::class => 3,
53-
\HierarchyDistances\SecondLoremInterface::class => 4,
54-
\HierarchyDistances\FirstLoremInterface::class => 5,
55-
\HierarchyDistances\FirstIpsumInterface::class => 6,
56-
\HierarchyDistances\ExtendedIpsumInterface::class => 7,
57-
\HierarchyDistances\SecondIpsumInterface::class => 8,
58-
\HierarchyDistances\ThirdIpsumInterface::class => 9,
54+
\HierarchyDistances\TraitThree::class => 4,
55+
\HierarchyDistances\SecondLoremInterface::class => 5,
56+
\HierarchyDistances\FirstLoremInterface::class => 6,
57+
\HierarchyDistances\FirstIpsumInterface::class => 7,
58+
\HierarchyDistances\ExtendedIpsumInterface::class => 8,
59+
\HierarchyDistances\SecondIpsumInterface::class => 9,
60+
\HierarchyDistances\ThirdIpsumInterface::class => 10,
5961
]
6062
:
6163
[
6264
\HierarchyDistances\Ipsum::class => 0,
6365
\HierarchyDistances\TraitOne::class => 1,
6466
\HierarchyDistances\Lorem::class => 2,
6567
\HierarchyDistances\TraitTwo::class => 3,
66-
\HierarchyDistances\FirstLoremInterface::class => 4,
67-
\HierarchyDistances\SecondLoremInterface::class => 5,
68-
\HierarchyDistances\FirstIpsumInterface::class => 6,
69-
\HierarchyDistances\SecondIpsumInterface::class => 7,
70-
\HierarchyDistances\ThirdIpsumInterface::class => 8,
71-
\HierarchyDistances\ExtendedIpsumInterface::class => 9,
68+
\HierarchyDistances\TraitThree::class => 4,
69+
\HierarchyDistances\FirstLoremInterface::class => 5,
70+
\HierarchyDistances\SecondLoremInterface::class => 6,
71+
\HierarchyDistances\FirstIpsumInterface::class => 7,
72+
\HierarchyDistances\SecondIpsumInterface::class => 8,
73+
\HierarchyDistances\ThirdIpsumInterface::class => 9,
74+
\HierarchyDistances\ExtendedIpsumInterface::class => 10,
7275
],
7376
],
7477
];
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace HierarchyDistances;
4+
5+
trait TraitThree
6+
{
7+
8+
}

tests/PHPStan/Reflection/data/distances/TraitTwo.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
trait TraitTwo
66
{
77

8+
use TraitThree;
9+
810
}

0 commit comments

Comments
 (0)