Skip to content

Commit bfcbb8f

Browse files
committed
perf: speeds up cache generation
1 parent 88cf5a4 commit bfcbb8f

File tree

1 file changed

+119
-5
lines changed

1 file changed

+119
-5
lines changed

DependencyInjection/GraphQLiteCompilerPass.php

+119-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
use GraphQL\Validator\Rules\QueryComplexity;
1111
use GraphQL\Validator\Rules\QueryDepth;
1212
use Kcs\ClassFinder\Finder\ComposerFinder;
13+
use Kcs\ClassFinder\Finder\FinderInterface;
1314
use ReflectionNamedType;
1415
use Symfony\Component\Cache\Adapter\ApcuAdapter;
1516
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
1617
use Symfony\Component\Cache\Psr16Cache;
18+
use Symfony\Component\Finder\Finder;
1719
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
1820
use TheCodingMachine\GraphQLite\Mappers\StaticClassListTypeMapperFactory;
1921
use Webmozart\Assert\Assert;
@@ -239,16 +241,18 @@ public function process(ContainerBuilder $container): void
239241
}
240242
}
241243

244+
$finder = $this->createFinder($container);
245+
242246
foreach ($controllersNamespaces as $controllersNamespace) {
243247
$schemaFactory->addMethodCall('addControllerNamespace', [ $controllersNamespace ]);
244-
foreach ($this->getClassList($controllersNamespace) as $className => $refClass) {
248+
foreach ($this->getClassList($controllersNamespace, $finder) as $className => $refClass) {
245249
$this->makePublicInjectedServices($refClass, $reader, $container, true);
246250
}
247251
}
248252

249253
foreach ($typesNamespaces as $typeNamespace) {
250254
$schemaFactory->addMethodCall('addTypeNamespace', [ $typeNamespace ]);
251-
foreach ($this->getClassList($typeNamespace) as $className => $refClass) {
255+
foreach ($this->getClassList($typeNamespace, $finder) as $className => $refClass) {
252256
$this->makePublicInjectedServices($refClass, $reader, $container, false);
253257
}
254258
}
@@ -482,13 +486,123 @@ private function getCodeCache(): ClassBoundCacheContractInterface
482486
* @param string $namespace
483487
* @return Generator<class-string, ReflectionClass<object>, void, void>
484488
*/
485-
private function getClassList(string $namespace): Generator
489+
private function getClassList(string $namespace, FinderInterface $finder): Generator
486490
{
487-
$finder = new ComposerFinder();
488491
foreach ($finder->inNamespace($namespace) as $class) {
489492
assert($class instanceof ReflectionClass);
490493
yield $class->getName() => $class;
491494
}
492495
}
493496

494-
}
497+
private function createFinder(ContainerBuilder $container): FinderInterface
498+
{
499+
return new class($container) implements FinderInterface {
500+
/** @var string[] */
501+
private array $namespaces;
502+
503+
private string $projectDir;
504+
505+
/** @var string[] */
506+
private array $namespaceControllers;
507+
508+
/** @var string[] */
509+
private array $namespaceTypes;
510+
511+
public function __construct(ContainerBuilder $container)
512+
{
513+
$this->namespaceTypes = $container->getParameter('graphqlite.namespace.types');
514+
$this->namespaceControllers = $container->getParameter('graphqlite.namespace.controllers');
515+
$this->projectDir = $container->getParameter('kernel.project_dir');
516+
}
517+
518+
public function getIterator(): \Traversable
519+
{
520+
$namespaces = $this->namespaces ?? [...$this->namespaceControllers, ...$this->namespaceTypes];
521+
522+
foreach ($namespaces as $namespace) {
523+
$dir = "{$this->projectDir}/src/".\str_replace(['Qbil\\', '\\'], '/', $namespace);
524+
525+
if (!\is_dir($dir)) {
526+
continue;
527+
}
528+
529+
$finder = new Finder();
530+
531+
$finder->files()->in($dir)->name('*.php');
532+
533+
foreach ($finder as $file) {
534+
$class = 'Qbil'
535+
.\str_replace(
536+
'/',
537+
'\\',
538+
\str_replace(["$this->projectDir/src/", '.php'], '', $file->getPathname()),
539+
);
540+
541+
if (!\class_exists($class)) {
542+
continue;
543+
}
544+
545+
yield $class => new \ReflectionClass($class);
546+
}
547+
}
548+
}
549+
550+
public function implementationOf(array|string $interface): FinderInterface
551+
{
552+
return $this;
553+
}
554+
555+
public function subclassOf(?string $superClass): FinderInterface
556+
{
557+
return $this;
558+
}
559+
560+
public function annotatedBy(?string $annotationClass): FinderInterface
561+
{
562+
return $this;
563+
}
564+
565+
public function withAttribute(?string $attributeClass): FinderInterface
566+
{
567+
return $this;
568+
}
569+
570+
public function in(array|string $dirs): FinderInterface
571+
{
572+
return $this;
573+
}
574+
575+
public function inNamespace(array|string $namespaces): FinderInterface
576+
{
577+
$this->namespaces = (array) $namespaces;
578+
579+
return $this;
580+
}
581+
582+
public function notInNamespace(array|string $namespaces): FinderInterface
583+
{
584+
return $this;
585+
}
586+
587+
public function filter(?callable $callback): FinderInterface
588+
{
589+
return $this;
590+
}
591+
592+
public function path(string $pattern): FinderInterface
593+
{
594+
return $this;
595+
}
596+
597+
public function notPath(string $pattern): FinderInterface
598+
{
599+
return $this;
600+
}
601+
602+
public function pathFilter(?callable $callback): FinderInterface
603+
{
604+
return $this;
605+
}
606+
};
607+
}
608+
}

0 commit comments

Comments
 (0)