Skip to content

Commit 86e3a3e

Browse files
author
Philipp Fritsche
committed
Use iterable of ClassLoaders for ClassFinder
1 parent bab889d commit 86e3a3e

File tree

4 files changed

+52
-67
lines changed

4 files changed

+52
-67
lines changed

src/Util/ClassFinder.php

+31-24
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,23 @@ class ClassFinder
1515
'+' => '(?-i:([A-Z][a-z0-9]+|[A-Z]+)_?)',
1616
];
1717

18-
private ClassLoader $classLoader;
18+
/** @var ClassLoader[] */
19+
private iterable $classLoaders;
20+
1921
private ?ConfigCache $configCache;
2022
private ?ClassMapGenerator $classMapGenerator;
2123

2224
private ?array $classList;
23-
25+
26+
/**
27+
* @param ClassLoader[] $classLoaders
28+
*/
2429
public function __construct(
25-
ClassLoader $classLoader,
30+
iterable $classLoaders = [],
2631
ConfigCache $configCache = null,
2732
ClassMapGenerator $classMapGenerator = null
2833
) {
29-
$this->classLoader = $classLoader;
34+
$this->classLoaders = $classLoaders;
3035
$this->configCache = $configCache;
3136
$this->classMapGenerator = $classMapGenerator;
3237
}
@@ -39,32 +44,34 @@ public function getClassList()
3944
return $this->classList;
4045
}
4146

42-
$classes[] = $this->classLoader->getClassMap();
43-
44-
if ($this->classLoader->isClassMapAuthoritative() === false) {
45-
$this->classMapGenerator ??= new ClassMapGenerator();
47+
foreach ($this->classLoaders as $loader) {
48+
$classes[] = $loader->getClassMap();
49+
50+
if ($loader->isClassMapAuthoritative() === false) {
51+
$this->classMapGenerator ??= new ClassMapGenerator();
4652

47-
foreach ($this->classLoader->getPrefixesPsr4() as $namespace => $dirs) {
48-
foreach ($dirs as $dir) {
49-
$classes[] = $this->classMapGenerator->createMap($dir, null, null, $namespace, 'psr-4');
53+
foreach ($loader->getPrefixesPsr4() as $namespace => $dirs) {
54+
foreach ($dirs as $dir) {
55+
$classes[] = $this->classMapGenerator->createMap($dir, null, null, $namespace, 'psr-4');
56+
}
5057
}
51-
}
5258

53-
$dirs = $this->classLoader->getFallbackDirsPsr4();
54-
foreach ($dirs as $dir) {
55-
$classes[] = $this->classMapGenerator->createMap($dir, null, null, null, 'psr-4');
56-
}
57-
58-
$dirs = $this->classLoader->getPrefixes();
59-
foreach ($this->classLoader->getPrefixes() as $namespace => $dirs) {
59+
$dirs = $loader->getFallbackDirsPsr4();
6060
foreach ($dirs as $dir) {
61-
$classes[] = $this->classMapGenerator->createMap($dir, null, null, $namespace, 'psr-0');
61+
$classes[] = $this->classMapGenerator->createMap($dir, null, null, null, 'psr-4');
62+
}
63+
64+
$dirs = $loader->getPrefixes();
65+
foreach ($loader->getPrefixes() as $namespace => $dirs) {
66+
foreach ($dirs as $dir) {
67+
$classes[] = $this->classMapGenerator->createMap($dir, null, null, $namespace, 'psr-0');
68+
}
6269
}
63-
}
6470

65-
$dirs = $this->classLoader->getFallbackDirs();
66-
foreach ($dirs as $dir) {
67-
$classes[] = $this->classMapGenerator->createMap($dir, null, null, null, 'psr-0');
71+
$dirs = $loader->getFallbackDirs();
72+
foreach ($dirs as $dir) {
73+
$classes[] = $this->classMapGenerator->createMap($dir, null, null, null, 'psr-0');
74+
}
6875
}
6976
}
7077

src/Util/ClassFinderFactory.php

+14-22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<?php
22
namespace nextdev\AdrBundle\Util;
33

4-
use LogicException;
54
use Composer\Autoload\ClassLoader;
65
use Symfony\Component\Config\ConfigCache;
76
use Symfony\Component\HttpKernel\KernelInterface;
@@ -25,40 +24,33 @@ public function __construct(
2524
public function __invoke()
2625
{
2726
return new ClassFinder(
28-
$this->getClassLoaderFromAutoload(),
27+
$this->getClassLoadersFromAutoload(),
2928
$this->getCacheFromKernel()
3029
);
3130
}
3231

33-
protected function getClassLoaderFromAutoload(): ClassLoader
32+
/**
33+
* @return ClassLoader[]
34+
*/
35+
protected function getClassLoadersFromAutoload(): array
3436
{
37+
$loaders = [];
38+
3539
$autoloadStack = ($this->autoloadStack)();
3640

3741
if (\is_array($autoloadStack)) {
38-
$classLoader = \reset($autoloadStack);
39-
if (\is_callable($classLoader) && \is_array($classLoader)) {
40-
$classLoader = $classLoader[0];
41-
}
42+
foreach ($autoloadStack as $callback) {
43+
if (\is_array($callback) && $callback[0] instanceof DebugClassLoader) {
44+
$callback = $callback[0]->getClassLoader();
45+
}
4246

43-
if ($classLoader instanceof DebugClassLoader) {
44-
$classLoader = $classLoader->getClassLoader();
45-
if (\is_array($classLoader)) {
46-
$classLoader = $classLoader[0];
47+
if (\is_array($callback) && $callback[0] instanceof ClassLoader) {
48+
$loaders[] = $callback[0];
4749
}
4850
}
49-
} else {
50-
$classLoader = 'spl_autoload';
51-
}
52-
53-
if (!$classLoader instanceof ClassLoader) {
54-
throw new LogicException(\sprintf(
55-
'Autoloader %s is not supported for discovering classes. %s required.',
56-
\is_object($classLoader) ? \get_class($classLoader) : (string) $classLoader,
57-
ClassLoader::class
58-
));
5951
}
6052

61-
return $classLoader;
53+
return $loaders;
6254
}
6355

6456
protected function getCacheFromKernel(): ConfigCache

test/Util/ClassFinderFactoryTest.php

+2-14
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ function () use ($wrapLoader) {
2929

3030
$this->assertInstanceOf(ClassFinder::class, $finder);
3131

32-
$loaderProp = new ReflectionProperty(ClassFinder::class, 'classLoader');
32+
$loaderProp = new ReflectionProperty(ClassFinder::class, 'classLoaders');
3333
$loaderProp->setAccessible(true);
34-
$this->assertEquals($loader, $loaderProp->getValue($finder));
34+
$this->assertEquals([$loader], $loaderProp->getValue($finder));
3535

3636
$cacheProp = new ReflectionProperty(ClassFinder::class, 'configCache');
3737
$cacheProp->setAccessible(true);
@@ -41,18 +41,6 @@ function () use ($wrapLoader) {
4141
$this->assertEquals($cacheFile, $cache->getPath());
4242
}
4343

44-
public function testExceptionOnInvalidAutoloader()
45-
{
46-
$factory = new ClassFinderFactory(
47-
$this->getKernel('foo'),
48-
fn() => false
49-
);
50-
51-
$this->expectException(LogicException::class);
52-
53-
$factory();
54-
}
55-
5644
protected function getKernel(
5745
string $classesCacheFile,
5846
bool $debug = true

test/Util/ClassFinderTest.php

+5-7
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function testFindClasses(
7575
$search,
7676
$expected
7777
): void {
78-
$finder = new ClassFinder($this->createMock(ClassLoader::class));
78+
$finder = new ClassFinder();
7979
$classList = new ReflectionProperty(ClassFinder::class, 'classList');
8080
$classList->setAccessible(true);
8181
$classList->setValue($finder, $this->classListFixture);
@@ -108,7 +108,7 @@ public function testFindBestMatch(
108108
$search,
109109
$expected
110110
): void {
111-
$finder = new ClassFinder($this->createMock(ClassLoader::class));
111+
$finder = new ClassFinder();
112112
$classList = new ReflectionProperty(ClassFinder::class, 'classList');
113113
$classList->setAccessible(true);
114114
$classList->setValue($finder, $this->classListFixture);
@@ -177,7 +177,7 @@ public static function createMap($path, $blacklist = null, $io = null, $namespac
177177
};
178178
$mapGenerator::$call = 0;
179179

180-
$finder = new ClassFinder($loader, null, $mapGenerator);
180+
$finder = new ClassFinder([$loader], null, $mapGenerator);
181181

182182
$this->assertEquals(\array_keys(\array_merge(...$map)), $finder->getClassList());
183183
}
@@ -187,9 +187,8 @@ public function testCacheClassList()
187187
$classes = ['foo', 'bar', 'baz'];
188188

189189
$vfs = vfsStream::setup();
190-
$classLoader = $this->createMock(ClassLoader::class);
191190
$cache = new ConfigCache($vfs->url() . '/test.php', true);
192-
$finder = new ClassFinder($classLoader, $cache);
191+
$finder = new ClassFinder([], $cache);
193192

194193
$dumpMethod = new ReflectionMethod(ClassFinder::class, 'dumpClassList');
195194
$dumpMethod->setAccessible(true);
@@ -206,9 +205,8 @@ public function testCacheClassList()
206205
public function testExceptionOnCompromisedDumpfile()
207206
{
208207
$vfs = vfsStream::setup();
209-
$classLoader = $this->createMock(ClassLoader::class);
210208
$cache = new ConfigCache($vfs->url() . '/test.php', true);
211-
$finder = new ClassFinder($classLoader, $cache);
209+
$finder = new ClassFinder([], $cache);
212210

213211
$loadMethod = new ReflectionMethod(ClassFinder::class, 'loadClassList');
214212
$loadMethod->setAccessible(true);

0 commit comments

Comments
 (0)