1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\SourceLocator\Type\Composer;
6:
7: use PHPStan\BetterReflection\Identifier\Identifier;
8: use PHPStan\BetterReflection\Identifier\IdentifierType;
9: use PHPStan\BetterReflection\Reflection\Reflection;
10: use PHPStan\BetterReflection\Reflector\Exception\IdentifierNotFound;
11: use PHPStan\BetterReflection\Reflector\Reflector;
12: use PHPStan\BetterReflection\SourceLocator\Ast\Locator;
13: use PHPStan\BetterReflection\SourceLocator\Exception\InvalidFileLocation;
14: use PHPStan\BetterReflection\SourceLocator\FileChecker;
15: use PHPStan\BetterReflection\SourceLocator\Located\LocatedSource;
16: use PHPStan\BetterReflection\SourceLocator\Type\Composer\Psr\PsrAutoloaderMapping;
17: use PHPStan\BetterReflection\SourceLocator\Type\DirectoriesSourceLocator;
18: use PHPStan\BetterReflection\SourceLocator\Type\SourceLocator;
19:
20: use function file_get_contents;
21:
22: final class PsrAutoloaderLocator implements SourceLocator
23: {
24: /**
25: * @var \PHPStan\BetterReflection\SourceLocator\Type\Composer\Psr\PsrAutoloaderMapping
26: */
27: private $mapping;
28: /**
29: * @var \PHPStan\BetterReflection\SourceLocator\Ast\Locator
30: */
31: private $astLocator;
32: public function __construct(PsrAutoloaderMapping $mapping, Locator $astLocator)
33: {
34: $this->mapping = $mapping;
35: $this->astLocator = $astLocator;
36: }
37:
38: public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\PHPStan\BetterReflection\Reflection\Reflection
39: {
40: foreach ($this->mapping->resolvePossibleFilePaths($identifier) as $file) {
41: try {
42: FileChecker::assertReadableFile($file);
43:
44: return $this->astLocator->findReflection($reflector, new LocatedSource(file_get_contents($file), $identifier->getName(), $file), $identifier);
45: } catch (InvalidFileLocation $exception) {
46: // Ignore
47: } catch (IdentifierNotFound $exception) {
48: // on purpose - autoloading is allowed to fail, and silently-failing autoloaders are normal/endorsed
49: }
50: }
51:
52: return null;
53: }
54:
55: /**
56: * Find all identifiers of a type
57: *
58: * @return list<Reflection>
59: */
60: public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array
61: {
62: return (new DirectoriesSourceLocator($this->mapping->directories(), $this->astLocator))->locateIdentifiersByType($reflector, $identifierType);
63: }
64: }
65: