1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\SourceLocator\Type;
6:
7: use RecursiveDirectoryIterator;
8: use RecursiveIteratorIterator;
9: use PHPStan\BetterReflection\Identifier\Identifier;
10: use PHPStan\BetterReflection\Identifier\IdentifierType;
11: use PHPStan\BetterReflection\Reflection\Reflection;
12: use PHPStan\BetterReflection\Reflector\Reflector;
13: use PHPStan\BetterReflection\SourceLocator\Ast\Locator;
14: use PHPStan\BetterReflection\SourceLocator\Exception\InvalidDirectory;
15: use PHPStan\BetterReflection\SourceLocator\Exception\InvalidFileInfo;
16:
17: use function array_map;
18: use function is_dir;
19:
20: /**
21: * This source locator recursively loads all php files in an entire directory or multiple directories.
22: */
23: class DirectoriesSourceLocator implements SourceLocator
24: {
25: /**
26: * @var \PHPStan\BetterReflection\SourceLocator\Type\AggregateSourceLocator
27: */
28: private $aggregateSourceLocator;
29:
30: /**
31: * @param list<string> $directories directories to scan
32: *
33: * @throws InvalidDirectory
34: * @throws InvalidFileInfo
35: */
36: public function __construct(array $directories, Locator $astLocator)
37: {
38: $this->aggregateSourceLocator = new AggregateSourceLocator(array_map(static function (string $directory) use ($astLocator): FileIteratorSourceLocator {
39: if (! is_dir($directory)) {
40: throw InvalidDirectory::fromNonDirectory($directory);
41: }
42:
43: return new FileIteratorSourceLocator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS)), $astLocator);
44: }, $directories));
45: }
46:
47: public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\PHPStan\BetterReflection\Reflection\Reflection
48: {
49: return $this->aggregateSourceLocator->locateIdentifier($reflector, $identifier);
50: }
51:
52: /**
53: * {@inheritDoc}
54: */
55: public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array
56: {
57: return $this->aggregateSourceLocator->locateIdentifiersByType($reflector, $identifierType);
58: }
59: }
60: