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