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: /** @phpstan-var non-empty-string $file */
41: foreach ($this->mapping->resolvePossibleFilePaths($identifier) as $file) {
42: try {
43: FileChecker::assertReadableFile($file);
44:
45: return $this->astLocator->findReflection($reflector, new LocatedSource(file_get_contents($file), $identifier->getName(), $file), $identifier);
46: } catch (InvalidFileLocation $exception) {
47: // Ignore
48: } catch (IdentifierNotFound $exception) {
49: // on purpose - autoloading is allowed to fail, and silently-failing autoloaders are normal/endorsed
50: }
51: }
52:
53: return null;
54: }
55:
56: /**
57: * Find all identifiers of a type
58: *
59: * @return list<Reflection>
60: */
61: public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array
62: {
63: return (new DirectoriesSourceLocator($this->mapping->directories(), $this->astLocator))->locateIdentifiersByType($reflector, $identifierType);
64: }
65: }
66: