1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\SourceLocator\Type;
6:
7: use Composer\Autoload\ClassLoader;
8: use InvalidArgumentException;
9: use PHPStan\BetterReflection\Identifier\Identifier;
10: use PHPStan\BetterReflection\Identifier\IdentifierType;
11: use PHPStan\BetterReflection\SourceLocator\Ast\Locator;
12: use PHPStan\BetterReflection\SourceLocator\Exception\InvalidFileLocation;
13: use PHPStan\BetterReflection\SourceLocator\Located\LocatedSource;
14:
15: use function file_get_contents;
16:
17: /**
18: * This source locator uses Composer's built-in ClassLoader to locate files.
19: *
20: * Note that we use ClassLoader->findFile directory, rather than
21: * ClassLoader->loadClass because this library has a strict requirement that we
22: * do NOT actually load the classes
23: */
24: class ComposerSourceLocator extends AbstractSourceLocator
25: {
26: private ClassLoader $classLoader;
27: public function __construct(ClassLoader $classLoader, Locator $astLocator)
28: {
29: $this->classLoader = $classLoader;
30: parent::__construct($astLocator);
31: }
32:
33: /**
34: * {@inheritDoc}
35: *
36: * @throws InvalidArgumentException
37: * @throws InvalidFileLocation
38: */
39: protected function createLocatedSource(Identifier $identifier): ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource
40: {
41: if ($identifier->getType()->getName() !== IdentifierType::IDENTIFIER_CLASS) {
42: return null;
43: }
44:
45: $filename = $this->classLoader->findFile($identifier->getName());
46:
47: if ($filename === false) {
48: return null;
49: }
50:
51: return new LocatedSource(
52: file_get_contents($filename),
53: $identifier->getName(),
54: $filename,
55: );
56: }
57: }
58: