1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\SourceLocator\Type;
6:
7: use InvalidArgumentException;
8: use PHPStan\BetterReflection\Identifier\Identifier;
9: use PHPStan\BetterReflection\SourceLocator\Ast\Locator;
10: use PHPStan\BetterReflection\SourceLocator\Exception\InvalidFileLocation;
11: use PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource;
12: use PHPStan\BetterReflection\SourceLocator\Located\LocatedSource;
13: use PHPStan\BetterReflection\SourceLocator\SourceStubber\SourceStubber;
14: use PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData;
15:
16: final class PhpInternalSourceLocator extends AbstractSourceLocator
17: {
18: /**
19: * @var \PHPStan\BetterReflection\SourceLocator\SourceStubber\SourceStubber
20: */
21: private $stubber;
22: public function __construct(Locator $astLocator, SourceStubber $stubber)
23: {
24: $this->stubber = $stubber;
25: parent::__construct($astLocator);
26: }
27:
28: /**
29: * {@inheritDoc}
30: *
31: * @throws InvalidArgumentException
32: * @throws InvalidFileLocation
33: */
34: protected function createLocatedSource(Identifier $identifier): ?\PHPStan\BetterReflection\SourceLocator\Located\LocatedSource
35: {
36: return $this->getClassSource($identifier)
37: ?? $this->getFunctionSource($identifier)
38: ?? $this->getConstantSource($identifier);
39: }
40:
41: private function getClassSource(Identifier $identifier): ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource
42: {
43: if (! $identifier->isClass()) {
44: return null;
45: }
46:
47: /** @psalm-var class-string|trait-string $className */
48: $className = $identifier->getName();
49:
50: return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateClassStub($className));
51: }
52:
53: private function getFunctionSource(Identifier $identifier): ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource
54: {
55: if (! $identifier->isFunction()) {
56: return null;
57: }
58:
59: return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateFunctionStub($identifier->getName()));
60: }
61:
62: private function getConstantSource(Identifier $identifier): ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource
63: {
64: if (! $identifier->isConstant()) {
65: return null;
66: }
67:
68: return $this->createLocatedSourceFromStubData($identifier, $this->stubber->generateConstantStub($identifier->getName()));
69: }
70:
71: private function createLocatedSourceFromStubData(Identifier $identifier, ?\PHPStan\BetterReflection\SourceLocator\SourceStubber\StubData $stubData): ?\PHPStan\BetterReflection\SourceLocator\Located\InternalLocatedSource
72: {
73: if ($stubData === null) {
74: return null;
75: }
76:
77: $extensionName = $stubData->getExtensionName();
78:
79: if ($extensionName === null) {
80: // Not internal
81: return null;
82: }
83:
84: return new InternalLocatedSource($stubData->getStub(), $identifier->getName(), $extensionName, $stubData->getFileName());
85: }
86: }
87: