diff --git a/src/Parser/CachedParser.php b/src/Parser/CachedParser.php index 9a789330b1..f78bfc60f1 100644 --- a/src/Parser/CachedParser.php +++ b/src/Parser/CachedParser.php @@ -16,6 +16,9 @@ class CachedParser implements Parser private int $cachedNodesByStringCountMax; + /** @var array */ + private array $parsedByString = []; + public function __construct( Parser $originalParser, int $cachedNodesByStringCountMax @@ -43,9 +46,10 @@ public function parseFile(string $file): array } $sourceCode = FileReader::read($file); - if (!isset($this->cachedNodesByString[$sourceCode])) { + if (!isset($this->cachedNodesByString[$sourceCode]) || isset($this->parsedByString[$sourceCode])) { $this->cachedNodesByString[$sourceCode] = $this->originalParser->parseFile($file); $this->cachedNodesByStringCount++; + unset($this->parsedByString[$sourceCode]); } return $this->cachedNodesByString[$sourceCode]; @@ -71,6 +75,7 @@ public function parseString(string $sourceCode): array if (!isset($this->cachedNodesByString[$sourceCode])) { $this->cachedNodesByString[$sourceCode] = $this->originalParser->parseString($sourceCode); $this->cachedNodesByStringCount++; + $this->parsedByString[$sourceCode] = true; } return $this->cachedNodesByString[$sourceCode]; diff --git a/tests/PHPStan/Parser/CachedParserTest.php b/tests/PHPStan/Parser/CachedParserTest.php index b014507974..a76dd3f97c 100644 --- a/tests/PHPStan/Parser/CachedParserTest.php +++ b/tests/PHPStan/Parser/CachedParserTest.php @@ -2,7 +2,11 @@ namespace PHPStan\Parser; -class CachedParserTest extends \PHPUnit\Framework\TestCase +use PhpParser\Node\Stmt\Namespace_; +use PHPStan\File\FileReader; +use PHPStan\Testing\TestCase; + +class CachedParserTest extends TestCase { /** @@ -75,4 +79,22 @@ private function getPhpParserNodeMock(): \PhpParser\Node return $this->createMock(\PhpParser\Node::class); } + public function testParseTheSameFileWithDifferentMethod(): void + { + $parser = new CachedParser(self::getContainer()->getService('pathRoutingParser'), 500); + $path = __DIR__ . '/data/test.php'; + $contents = FileReader::read($path); + $stmts = $parser->parseString($contents); + $this->assertInstanceOf(Namespace_::class, $stmts[0]); + $this->assertNull($stmts[0]->stmts[0]->getAttribute('parent')); + + $stmts = $parser->parseFile($path); + $this->assertInstanceOf(Namespace_::class, $stmts[0]); + $this->assertInstanceOf(Namespace_::class, $stmts[0]->stmts[0]->getAttribute('parent')); + + $stmts = $parser->parseString($contents); + $this->assertInstanceOf(Namespace_::class, $stmts[0]); + $this->assertInstanceOf(Namespace_::class, $stmts[0]->stmts[0]->getAttribute('parent')); + } + } diff --git a/tests/PHPStan/Parser/data/test.php b/tests/PHPStan/Parser/data/test.php new file mode 100644 index 0000000000..a6bee51214 --- /dev/null +++ b/tests/PHPStan/Parser/data/test.php @@ -0,0 +1,8 @@ +