Skip to content

Commit 423fd9b

Browse files
committed
AutoloadSourceLocator - use FileNodesFetcher
1 parent 97617f2 commit 423fd9b

File tree

5 files changed

+63
-32
lines changed

5 files changed

+63
-32
lines changed

conf/config.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,9 @@ services:
465465
arguments:
466466
phpParser: @phpParserDecorator
467467

468+
-
469+
class: PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocator
470+
468471
-
469472
class: PHPStan\Reflection\BetterReflection\SourceLocator\ComposerJsonAndInstalledJsonSourceLocatorMaker
470473

src/Reflection/BetterReflection/BetterReflectionSourceLocatorFactory.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class BetterReflectionSourceLocatorFactory
3939
/** @var ComposerJsonAndInstalledJsonSourceLocatorMaker */
4040
private $composerJsonAndInstalledJsonSourceLocatorMaker;
4141

42+
/** @var AutoloadSourceLocator */
43+
private $autoloadSourceLocator;
44+
4245
/** @var \PHPStan\DependencyInjection\Container */
4346
private $container;
4447

@@ -71,6 +74,7 @@ public function __construct(
7174
OptimizedSingleFileSourceLocatorRepository $optimizedSingleFileSourceLocatorRepository,
7275
OptimizedDirectorySourceLocatorRepository $optimizedDirectorySourceLocatorRepository,
7376
ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker,
77+
AutoloadSourceLocator $autoloadSourceLocator,
7478
Container $container,
7579
array $autoloadDirectories,
7680
array $autoloadFiles,
@@ -85,6 +89,7 @@ public function __construct(
8589
$this->optimizedSingleFileSourceLocatorRepository = $optimizedSingleFileSourceLocatorRepository;
8690
$this->optimizedDirectorySourceLocatorRepository = $optimizedDirectorySourceLocatorRepository;
8791
$this->composerJsonAndInstalledJsonSourceLocatorMaker = $composerJsonAndInstalledJsonSourceLocatorMaker;
92+
$this->autoloadSourceLocator = $autoloadSourceLocator;
8893
$this->container = $container;
8994
$this->autoloadDirectories = $autoloadDirectories;
9095
$this->autoloadFiles = $autoloadFiles;
@@ -135,7 +140,7 @@ public function create(): SourceLocator
135140
return $this->container->getService('betterReflectionFunctionReflector');
136141
});
137142
$locators[] = new PhpInternalSourceLocator($astLocator, $this->phpstormStubsSourceStubber);
138-
$locators[] = new AutoloadSourceLocator($astLocator);
143+
$locators[] = $this->autoloadSourceLocator;
139144
$locators[] = new PhpInternalSourceLocator($astLocator, $this->reflectionSourceStubber);
140145
$locators[] = new EvaledCodeSourceLocator($astLocator, $this->reflectionSourceStubber);
141146

src/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocator.php

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,16 @@
88
use PhpParser\Node\Expr\FuncCall;
99
use PhpParser\Node\Name;
1010
use PhpParser\Node\Scalar\String_;
11-
use PHPStan\File\FileReader;
1211
use ReflectionClass;
1312
use ReflectionException;
1413
use ReflectionFunction;
1514
use Roave\BetterReflection\Identifier\Identifier;
1615
use Roave\BetterReflection\Identifier\IdentifierType;
1716
use Roave\BetterReflection\Reflection\Reflection;
1817
use Roave\BetterReflection\Reflection\ReflectionConstant;
19-
use Roave\BetterReflection\Reflector\Exception\IdentifierNotFound;
2018
use Roave\BetterReflection\Reflector\Reflector;
2119
use Roave\BetterReflection\SourceLocator\Ast\Exception\ParseToAstFailure;
22-
use Roave\BetterReflection\SourceLocator\Ast\Locator as AstLocator;
20+
use Roave\BetterReflection\SourceLocator\Ast\Strategy\NodeToReflection;
2321
use Roave\BetterReflection\SourceLocator\Located\LocatedSource;
2422
use Roave\BetterReflection\SourceLocator\Type\SourceLocator;
2523
use function file_exists;
@@ -36,24 +34,24 @@
3634
class AutoloadSourceLocator implements SourceLocator
3735
{
3836

39-
private AstLocator $astLocator;
37+
private FileNodesFetcher $fileNodesFetcher;
4038

4139
private static ?string $autoloadLocatedFile = null;
4240

43-
private static ?AstLocator $currentAstLocator = null;
41+
private static ?FileNodesFetcher $currentFileNodesFetcher = null;
4442

4543
/**
4644
* Note: the constructor has been made a 0-argument constructor because `\stream_wrapper_register`
4745
* is a piece of trash, and doesn't accept instances, just class names.
4846
*/
49-
public function __construct(?AstLocator $astLocator = null)
47+
public function __construct(?FileNodesFetcher $fileNodesFetcher = null)
5048
{
51-
$validLocator = $astLocator ?? self::$currentAstLocator;
52-
if ($validLocator === null) {
49+
$validFetcher = $fileNodesFetcher ?? self::$currentFileNodesFetcher;
50+
if ($validFetcher === null) {
5351
throw new \PHPStan\ShouldNotHappenException();
5452
}
5553

56-
$this->astLocator = $validLocator;
54+
$this->fileNodesFetcher = $validFetcher;
5755
}
5856

5957
/**
@@ -115,22 +113,40 @@ public function locateIdentifier(Reflector $reflector, Identifier $identifier):
115113

116114
private function findReflection(Reflector $reflector, string $file, Identifier $identifier): ?Reflection
117115
{
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+
}
122132
}
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+
}
133147
}
148+
149+
return null;
134150
}
135151

136152
public function locateIdentifiersByType(Reflector $reflector, IdentifierType $identifierType): array
@@ -172,7 +188,7 @@ private function locateClassByName(string $className): ?array
172188
}
173189

174190
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`
176192
set_error_handler(static function (int $errno, string $errstr): bool {
177193
throw new \PHPStan\Reflection\BetterReflection\SourceLocator\AutoloadSourceLocatorException();
178194
});

src/Testing/TestCaseSourceLocatorFactory.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class TestCaseSourceLocatorFactory
2323

2424
private ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker;
2525

26+
private AutoloadSourceLocator $autoloadSourceLocator;
27+
2628
private \PhpParser\Parser $phpParser;
2729

2830
private PhpStormStubsSourceStubber $phpstormStubsSourceStubber;
@@ -32,13 +34,15 @@ class TestCaseSourceLocatorFactory
3234
public function __construct(
3335
Container $container,
3436
ComposerJsonAndInstalledJsonSourceLocatorMaker $composerJsonAndInstalledJsonSourceLocatorMaker,
37+
AutoloadSourceLocator $autoloadSourceLocator,
3538
\PhpParser\Parser $phpParser,
3639
PhpStormStubsSourceStubber $phpstormStubsSourceStubber,
3740
ReflectionSourceStubber $reflectionSourceStubber
3841
)
3942
{
4043
$this->container = $container;
4144
$this->composerJsonAndInstalledJsonSourceLocatorMaker = $composerJsonAndInstalledJsonSourceLocatorMaker;
45+
$this->autoloadSourceLocator = $autoloadSourceLocator;
4246
$this->phpParser = $phpParser;
4347
$this->phpstormStubsSourceStubber = $phpstormStubsSourceStubber;
4448
$this->reflectionSourceStubber = $reflectionSourceStubber;
@@ -69,7 +73,7 @@ public function create(): SourceLocator
6973
});
7074

7175
$locators[] = new PhpInternalSourceLocator($astLocator, $this->phpstormStubsSourceStubber);
72-
$locators[] = new AutoloadSourceLocator($astLocator);
76+
$locators[] = $this->autoloadSourceLocator;
7377
$locators[] = new PhpInternalSourceLocator($astLocator, $this->reflectionSourceStubber);
7478
$locators[] = new EvaledCodeSourceLocator($astLocator, $this->reflectionSourceStubber);
7579

tests/PHPStan/Reflection/BetterReflection/SourceLocator/AutoloadSourceLocatorTest.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,31 @@
22

33
namespace PHPStan\Reflection\BetterReflection\SourceLocator;
44

5-
use PHPStan\Parser\PhpParserDecorator;
65
use PHPStan\Testing\TestCase;
76
use Roave\BetterReflection\Reflector\ClassReflector;
87
use Roave\BetterReflection\Reflector\FunctionReflector;
9-
use Roave\BetterReflection\SourceLocator\Ast\Locator;
108
use TestSingleFileSourceLocator\AFoo;
119

10+
function testFunctionForLocator()
11+
{
12+
13+
}
14+
1215
class AutoloadSourceLocatorTest extends TestCase
1316
{
1417

1518
public function testAutoloadEverythingInFile(): void
1619
{
1720
/** @var FunctionReflector $functionReflector */
1821
$functionReflector = null;
19-
$astLocator = new Locator(new PhpParserDecorator($this->getParser()), function () use (&$functionReflector): FunctionReflector {
20-
return $functionReflector;
21-
});
22-
$locator = new AutoloadSourceLocator($astLocator);
22+
$locator = new AutoloadSourceLocator(self::getContainer()->getByType(FileNodesFetcher::class));
2323
$classReflector = new ClassReflector($locator);
2424
$functionReflector = new FunctionReflector($locator, $classReflector);
2525
$aFoo = $classReflector->reflect(AFoo::class);
2626
$this->assertSame('a.php', basename($aFoo->getFileName()));
27+
28+
$testFunctionReflection = $functionReflector->reflect('PHPStan\\Reflection\\BetterReflection\\SourceLocator\testFunctionForLocator');
29+
$this->assertSame(__FILE__, $testFunctionReflection->getFileName());
2730
}
2831

2932
}

0 commit comments

Comments
 (0)