|
8 | 8 | use PhpParser\Node\Expr\FuncCall; |
9 | 9 | use PhpParser\Node\Name; |
10 | 10 | use PhpParser\Node\Scalar\String_; |
11 | | -use PHPStan\File\FileReader; |
12 | 11 | use ReflectionClass; |
13 | 12 | use ReflectionException; |
14 | 13 | use ReflectionFunction; |
15 | 14 | use Roave\BetterReflection\Identifier\Identifier; |
16 | 15 | use Roave\BetterReflection\Identifier\IdentifierType; |
17 | 16 | use Roave\BetterReflection\Reflection\Reflection; |
18 | 17 | use Roave\BetterReflection\Reflection\ReflectionConstant; |
19 | | -use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound; |
20 | 18 | use Roave\BetterReflection\Reflector\Reflector; |
21 | 19 | use Roave\BetterReflection\SourceLocator\Ast\Exception\ParseToAstFailure; |
22 | | -use Roave\BetterReflection\SourceLocator\Ast\Locator as AstLocator; |
| 20 | +use Roave\BetterReflection\SourceLocator\Ast\Strategy\NodeToReflection; |
23 | 21 | use Roave\BetterReflection\SourceLocator\Located\LocatedSource; |
24 | 22 | use Roave\BetterReflection\SourceLocator\Type\SourceLocator; |
25 | 23 | use function file_exists; |
|
36 | 34 | class AutoloadSourceLocator implements SourceLocator |
37 | 35 | { |
38 | 36 |
|
39 | | - private AstLocator $astLocator; |
| 37 | + private FileNodesFetcher $fileNodesFetcher; |
40 | 38 |
|
41 | 39 | private static ?string $autoloadLocatedFile = null; |
42 | 40 |
|
43 | | - private static ?AstLocator $currentAstLocator = null; |
| 41 | + private static ?FileNodesFetcher $currentFileNodesFetcher = null; |
44 | 42 |
|
45 | 43 | /** |
46 | 44 | * Note: the constructor has been made a 0-argument constructor because `\stream_wrapper_register` |
47 | 45 | * is a piece of trash, and doesn't accept instances, just class names. |
48 | 46 | */ |
49 | | - public function __construct(?AstLocator $astLocator = null) |
| 47 | + public function __construct(?FileNodesFetcher $fileNodesFetcher = null) |
50 | 48 | { |
51 | | - $validLocator = $astLocator ?? self::$currentAstLocator; |
52 | | - if ($validLocator === null) { |
| 49 | + $validFetcher = $fileNodesFetcher ?? self::$currentFileNodesFetcher; |
| 50 | + if ($validFetcher === null) { |
53 | 51 | throw new \PHPStan\ShouldNotHappenException(); |
54 | 52 | } |
55 | 53 |
|
56 | | - $this->astLocator = $validLocator; |
| 54 | + $this->fileNodesFetcher = $validFetcher; |
57 | 55 | } |
58 | 56 |
|
59 | 57 | /** |
@@ -115,22 +113,40 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier): |
115 | 113 |
|
116 | 114 | private function findReflection(Reflector $reflector, string $file, Identifier $identifier): ?Reflection |
117 | 115 | { |
118 | | - try { |
119 | | - $fileContents = FileReader::read($file); |
120 | | - } catch (\PHPStan\File\CouldNotReadFileException $e) { |
121 | | - return null; |
| 116 | + $result = $this->fileNodesFetcher->fetchNodes($file); |
| 117 | + $nodeToReflection = new NodeToReflection(); |
| 118 | + if ($identifier->isClass()) { |
| 119 | + foreach ($result->getClassNodes() as $fetchedFunctionNode) { |
| 120 | + $reflection = $nodeToReflection->__invoke( |
| 121 | + $reflector, |
| 122 | + $fetchedFunctionNode->getNode(), |
| 123 | + $result->getLocatedSource(), |
| 124 | + $fetchedFunctionNode->getNamespace() |
| 125 | + ); |
| 126 | + if ($reflection === null) { |
| 127 | + continue; |
| 128 | + } |
| 129 | + |
| 130 | + return $reflection; |
| 131 | + } |
122 | 132 | } |
123 | | - |
124 | | - $locatedSource = new LocatedSource( |
125 | | - $fileContents, |
126 | | - $file |
127 | | - ); |
128 | | - |
129 | | - try { |
130 | | - return $this->astLocator->findReflection($reflector, $locatedSource, $identifier); |
131 | | - } catch (IdentifierNotFound $exception) { |
132 | | - return null; |
| 133 | + if ($identifier->isFunction()) { |
| 134 | + foreach ($result->getFunctionNodes() as $fetchedFunctionNode) { |
| 135 | + $reflection = $nodeToReflection->__invoke( |
| 136 | + $reflector, |
| 137 | + $fetchedFunctionNode->getNode(), |
| 138 | + $result->getLocatedSource(), |
| 139 | + $fetchedFunctionNode->getNamespace() |
| 140 | + ); |
| 141 | + if ($reflection === null) { |
| 142 | + continue; |
| 143 | + } |
| 144 | + |
| 145 | + return $reflection; |
| 146 | + } |
133 | 147 | } |
| 148 | + |
| 149 | + return null; |
134 | 150 | } |
135 | 151 |
|
136 | 152 | public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array |
@@ -172,7 +188,7 @@ private function locateClassByName(string $className): ?array |
172 | 188 | } |
173 | 189 |
|
174 | 190 | self::$autoloadLocatedFile = null; |
175 | | - self::$currentAstLocator = $this->astLocator; // passing the locator on to the implicitly instantiated `self` |
| 191 | + self::$currentFileNodesFetcher = $this->fileNodesFetcher; // passing the locator on to the implicitly instantiated `self` |
176 | 192 | set_error_handler(static function (int $errno, string $errstr): bool { |
177 | 193 | throw new \PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocatorException(); |
178 | 194 | }); |
|
0 commit comments