Skip to content

Commit 8da2be8

Browse files
authored
Merge pull request #9 from jakzal/issue/3
Fix an issue with traits referencing class constants
2 parents 9af50d9 + 548a019 commit 8da2be8

File tree

2 files changed

+45
-16
lines changed

2 files changed

+45
-16
lines changed

src/Symfony/Compiler/Discovery/ClassFinder.php

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,45 +35,59 @@ private function find(callable $predicate): array
3535
$classes = [];
3636

3737
foreach ($this->findPhpFiles() as $phpFile) {
38-
$classes[] = $this->findClassesInFile($predicate, $phpFile);
38+
$classes[] = $this->findClassInFile($phpFile);
3939
}
4040

41-
$classes = \array_merge([], ...$classes);
41+
$classes = \array_filter($classes, function (?string $class) use ($predicate) {
42+
return !empty($class) && $predicate($class);
43+
});
4244

4345
\sort($classes);
4446

4547
return $classes;
4648
}
4749

48-
private function findClassesInFile(callable $predicate, \SplFileInfo $phpFile): array
50+
private function findClassInFile(\SplFileInfo $phpFile): ?string
4951
{
5052
// @see https://stackoverflow.com/a/27440555/330267
51-
$classes = [];
5253
$tokens = \token_get_all(\file_get_contents($phpFile->getRealPath()));
5354
$namespace = '';
5455

5556
for ($index = 0; isset($tokens[$index]); $index++) {
5657
if (!\is_array($tokens[$index])) {
5758
continue;
5859
}
59-
if (T_NAMESPACE === $tokens[$index][0]) {
60-
$index += 2; // Skip namespace keyword and whitespace
61-
while (isset($tokens[$index]) && \is_array($tokens[$index]) && T_WHITESPACE !== $tokens[$index][0]) {
60+
if ($this->isNamespaceToken($tokens, $index)) {
61+
while ($this->isNotWhitespaceToken($tokens, $index)) {
6262
$namespace .= $tokens[$index++][1];
6363
}
6464
}
65-
if (T_CLASS === $tokens[$index][0]) {
66-
$index += 2; // Skip class keyword and whitespace
67-
$class = $namespace . '\\' . $tokens[$index][1];
68-
if ($predicate($class)) {
69-
$classes[] = $class;
70-
}
71-
72-
break;
65+
if ($this->isClassNameToken($tokens, $index)) {
66+
return $namespace . '\\' . $tokens[$index][1];
7367
}
7468
}
7569

76-
return $classes;
70+
return null;
71+
}
72+
73+
private function isNamespaceToken($tokens, int $index): bool
74+
{
75+
return $this->extractTokens($tokens, $index - 2, 3) === [T_NAMESPACE, T_WHITESPACE, T_STRING];
76+
}
77+
78+
private function isClassNameToken($tokens, int $index): bool
79+
{
80+
return $this->extractTokens($tokens, $index - 2, 3) === [T_CLASS, T_WHITESPACE, T_STRING];
81+
}
82+
83+
private function extractTokens($tokens, int $startIndex, int $count): array
84+
{
85+
return \array_column(\array_slice($tokens, $startIndex, $count), 0);
86+
}
87+
88+
private function isNotWhitespaceToken($tokens, int $index): bool
89+
{
90+
return isset($tokens[$index]) && \is_array($tokens[$index]) && T_WHITESPACE !== $tokens[$index][0];
7791
}
7892

7993
/**
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Zalas\Injector\PHPUnit\Tests\Symfony\Compiler\Fixtures;
5+
6+
trait FooTrait
7+
{
8+
/**
9+
* Reproduces https://github.com/jakzal/phpunit-injector/issues/3
10+
*/
11+
protected function bar(): string
12+
{
13+
return Service1::class;
14+
}
15+
}

0 commit comments

Comments
 (0)