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: /**
27: * @var \Composer\Autoload\ClassLoader
28: */
29: private $classLoader;
30: public function __construct(ClassLoader $classLoader, Locator $astLocator)
31: {
32: $this->classLoader = $classLoader;
33: parent::__construct($astLocator);
34: }
35:
36: /**
37: * {@inheritDoc}
38: *
39: * @throws InvalidArgumentException
40: * @throws InvalidFileLocation
41: */
42: protected function createLocatedSource(Identifier $identifier): ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource
43: {
44: if ($identifier->getType()->getName() !== IdentifierType::IDENTIFIER_CLASS) {
45: return null;
46: }
47:
48: $filename = $this->classLoader->findFile($identifier->getName());
49:
50: if ($filename === false) {
51: return null;
52: }
53:
54: return new LocatedSource(file_get_contents($filename), $identifier->getName(), $filename);
55: }
56: }
57: