|
2 | 2 |
|
3 | 3 | namespace PHPStan\Reflection; |
4 | 4 |
|
| 5 | +use ArrayObject; |
5 | 6 | use Attribute; |
6 | 7 | use Attributes\IsAttribute; |
7 | 8 | use Attributes\IsAttribute2; |
|
31 | 32 | use PHPStan\Testing\PHPStanTestCase; |
32 | 33 | use PHPStan\Testing\RuleTestCase; |
33 | 34 | use PHPStan\Type\IntegerType; |
| 35 | +use PHPStan\Type\StringType; |
34 | 36 | use PHPUnit\Framework\Attributes\DataProvider; |
35 | 37 | use PHPUnit\Framework\Attributes\RequiresPhp; |
36 | 38 | use PHPUnit\Framework\TestCase; |
37 | 39 | use ReflectionClass; |
| 40 | +use WeakReference; |
38 | 41 | use WrongClassConstantFile\SecuredRouter; |
| 42 | +use function array_key_first; |
39 | 43 | use function array_map; |
40 | 44 | use function array_values; |
| 45 | +use function gc_disable; |
| 46 | +use function gc_enable; |
| 47 | +use function gc_enabled; |
41 | 48 |
|
42 | 49 | class ClassReflectionTest extends PHPStanTestCase |
43 | 50 | { |
@@ -375,4 +382,29 @@ public function testDeprecatedAttribute(string $className, bool $expected): void |
375 | 382 | $this->assertSame($expected, $classReflection->isDeprecated()); |
376 | 383 | } |
377 | 384 |
|
| 385 | + public function testAncestorsDoNotKeepClassReflectionAlive(): void |
| 386 | + { |
| 387 | + $reflectionProvider = self::createReflectionProvider(); |
| 388 | + $classReflection = $reflectionProvider->getClass(ArrayObject::class)->withTypes([new IntegerType(), new StringType()]); |
| 389 | + |
| 390 | + $ancestors = $classReflection->getAncestors(); |
| 391 | + $this->assertSame(ArrayObject::class, array_key_first($ancestors)); |
| 392 | + $this->assertSame($classReflection, $ancestors[ArrayObject::class]); |
| 393 | + $this->assertSame($ancestors, $classReflection->getAncestors()); |
| 394 | + unset($ancestors); |
| 395 | + |
| 396 | + // PHPStan runs with gc_disable(), so a reference cycle would keep it alive |
| 397 | + $gcEnabled = gc_enabled(); |
| 398 | + gc_disable(); |
| 399 | + try { |
| 400 | + $weakReference = WeakReference::create($classReflection); |
| 401 | + unset($classReflection); |
| 402 | + $this->assertNull($weakReference->get()); |
| 403 | + } finally { |
| 404 | + if ($gcEnabled) { |
| 405 | + gc_enable(); |
| 406 | + } |
| 407 | + } |
| 408 | + } |
| 409 | + |
378 | 410 | } |
0 commit comments