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: private PsrAutoloaderMapping $mapping;
25: private Locator $astLocator;
26: public function __construct(PsrAutoloaderMapping $mapping, Locator $astLocator)
27: {
28: $this->mapping = $mapping;
29: $this->astLocator = $astLocator;
30: }
31:
32: public function locateIdentifier(Reflector $reflector, Identifier $identifier): ?\PHPStan\BetterReflection\Reflection\Reflection
33: {
34: /** @phpstan-var non-empty-string $file */
35: foreach ($this->mapping->resolvePossibleFilePaths($identifier) as $file) {
36: try {
37: FileChecker::assertReadableFile($file);
38:
39: return $this->astLocator->findReflection(
40: $reflector,
41: new LocatedSource(
42: file_get_contents($file),
43: $identifier->getName(),
44: $file,
45: ),
46: $identifier,
47: );
48: } catch (InvalidFileLocation $exception) {
49: // Ignore
50: } catch (IdentifierNotFound $exception) {
51: // on purpose - autoloading is allowed to fail, and silently-failing autoloaders are normal/endorsed
52: }
53: }
54:
55: return null;
56: }
57:
58: /**
59: * Find all identifiers of a type
60: *
61: * @return list<Reflection>
62: */
63: public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array
64: {
65: return (new DirectoriesSourceLocator(
66: $this->mapping->directories(),
67: $this->astLocator,
68: ))->locateIdentifiersByType($reflector, $identifierType);
69: }
70: }
71: