|
5 | 5 | use Generator; |
6 | 6 | use PhpParser\Node; |
7 | 7 | use PhpParser\Node\Stmt\Namespace_; |
| 8 | +use PHPStan\BetterReflection\Reflection\ExprCacheHelper; |
8 | 9 | use PHPStan\File\FileHelper; |
9 | 10 | use PHPStan\File\FileReader; |
10 | 11 | use PHPStan\Testing\PHPStanTestCase; |
@@ -123,4 +124,51 @@ public function testParseTheSameFileWithDifferentMethod(): void |
123 | 124 | $this->assertSame(2, $stmts[0]->stmts[1]->expr->expr->class->getAttribute(AnonymousClassVisitor::ATTRIBUTE_LINE_INDEX)); |
124 | 125 | } |
125 | 126 |
|
| 127 | + public function testWithExprCacheHelper(): void |
| 128 | + { |
| 129 | + $fileHelper = self::getContainer()->getByType(FileHelper::class); |
| 130 | + $pathRoutingParser = new PathRoutingParser( |
| 131 | + $fileHelper, |
| 132 | + self::getContainer()->getService('currentPhpVersionRichParser'), |
| 133 | + self::getContainer()->getService('currentPhpVersionSimpleDirectParser'), |
| 134 | + self::getContainer()->getService('php8Parser'), |
| 135 | + null, |
| 136 | + ); |
| 137 | + $parser = new CachedParser($pathRoutingParser, 500); |
| 138 | + $path = $fileHelper->normalizePath(__DIR__ . '/data/parser-cache-bug.php'); |
| 139 | + $pathRoutingParser->setAnalysedFiles([$path]); |
| 140 | + $contents = FileReader::read($path); |
| 141 | + $stmts = $parser->parseString($contents); |
| 142 | + |
| 143 | + $this->assertInstanceOf(Namespace_::class, $stmts[0]); |
| 144 | + $ns = $stmts[0]; |
| 145 | + |
| 146 | + $this->assertInstanceOf(Node\Stmt\Class_::class, $ns->stmts[1]); |
| 147 | + $class = $ns->stmts[1]; |
| 148 | + |
| 149 | + $this->assertInstanceOf(Node\Stmt\Property::class, $class->stmts[0]); |
| 150 | + $property = $class->stmts[0]; |
| 151 | + $group = $property->attrGroups[0]; |
| 152 | + $attribute = $group->attrs[0]; |
| 153 | + |
| 154 | + $expr = $attribute->args[0]->value; |
| 155 | + $this->assertSame(['startLine' => 8, 'startTokenPos' => 21, 'startFilePos' => 88, 'endLine' => 8, 'endTokenPos' => 21, 'endFilePos' => 94, 'kind' => 1, 'rawValue' => "'hello'"], $expr->getAttributes()); |
| 156 | + $exported = ExprCacheHelper::export($expr); |
| 157 | + $reImported = ExprCacheHelper::import($exported); |
| 158 | + $this->assertSame(['startLine' => 8, 'startTokenPos' => 21, 'startFilePos' => 88, 'endLine' => 8, 'endTokenPos' => 21, 'endFilePos' => 94, 'kind' => 1, 'rawValue' => "'hello'"], $reImported->getAttributes()); |
| 159 | + |
| 160 | + $this->assertInstanceOf(Node\Stmt\Property::class, $class->stmts[1]); |
| 161 | + $property = $class->stmts[1]; |
| 162 | + $group = $property->attrGroups[0]; |
| 163 | + $attribute = $group->attrs[0]; |
| 164 | + |
| 165 | + $expr = $attribute->args[0]->value; |
| 166 | + $this->assertSame(['startLine' => 10, 'startTokenPos' => 35, 'startFilePos' => 137, 'endLine' => 10, 'endTokenPos' => 35, 'endFilePos' => 143, 'kind' => 1, 'rawValue' => "'hello'"], $expr->getAttributes()); |
| 167 | + $exported = ExprCacheHelper::export($expr); |
| 168 | + unset($exported['attributes']['startLine']); // modify attributes |
| 169 | + $reImported = ExprCacheHelper::import($exported); |
| 170 | + // assert that we get back the default start-line instead of a stale cached startLine of previous same value expression |
| 171 | + $this->assertSame(['startLine' => 1, 'startTokenPos' => 35, 'startFilePos' => 137, 'endLine' => 10, 'endTokenPos' => 35, 'endFilePos' => 143, 'kind' => 1, 'rawValue' => "'hello'"], $reImported->getAttributes()); |
| 172 | + } |
| 173 | + |
126 | 174 | } |
0 commit comments