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