From 74769abc3063da87a6c5622989be789880b7c06a Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 10 Oct 2026 01:35:02 +0700 Subject: [PATCH] Fix crash on PHPStan\Type\NonexistentParentClassType on AddArrowFunctionReturnTypeRector --- .../return_new_parent_in_trait.php.inc | 31 ++++++++++++ .../return_new_parent_in_trait.php.inc | 31 ++++++++++++ .../NonexistentParentClassTypeMapper.php | 47 +++++++++++++++++++ .../NonexistentParentClassTypeMapperTest.php | 40 ++++++++++++++++ 4 files changed, 149 insertions(+) create mode 100644 rules-tests/TypeDeclaration/Rector/ArrowFunction/AddArrowFunctionReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/Closure/ClosureReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc create mode 100644 src/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapper.php create mode 100644 tests/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapperTest.php diff --git a/rules-tests/TypeDeclaration/Rector/ArrowFunction/AddArrowFunctionReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc b/rules-tests/TypeDeclaration/Rector/ArrowFunction/AddArrowFunctionReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc new file mode 100644 index 00000000000..e8bfa8afe19 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ArrowFunction/AddArrowFunctionReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc @@ -0,0 +1,31 @@ + new parent(...$args), $this); + } +} + +?> +----- + new parent(...$args), $this); + } +} + +?> diff --git a/rules-tests/TypeDeclaration/Rector/Closure/ClosureReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc b/rules-tests/TypeDeclaration/Rector/Closure/ClosureReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc new file mode 100644 index 00000000000..ad44311de02 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/Closure/ClosureReturnTypeRector/Fixture/return_new_parent_in_trait.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/src/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapper.php b/src/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapper.php new file mode 100644 index 00000000000..f2d88a35dd3 --- /dev/null +++ b/src/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapper.php @@ -0,0 +1,47 @@ + + * @see \Rector\Tests\PHPStanStaticTypeMapper\TypeMapper\NonexistentParentClassTypeMapperTest + */ +final class NonexistentParentClassTypeMapper implements TypeMapperInterface +{ + /** + * @return array> + */ + public function getNodeClasses(): array + { + return [NonexistentParentClassType::class]; + } + + /** + * @param NonexistentParentClassType $type + */ + public function mapToPHPStanPhpDocTypeNode(Type $type): TypeNode + { + return $type->toPhpDocNode(); + } + + /** + * @param NonexistentParentClassType $type + */ + public function mapToPhpParserNode(Type $type, string $typeKind): Name + { + return new Name(ObjectReference::PARENT); + } +} diff --git a/tests/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapperTest.php b/tests/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapperTest.php new file mode 100644 index 00000000000..cd5c4100c1e --- /dev/null +++ b/tests/PHPStanStaticTypeMapper/TypeMapper/NonexistentParentClassTypeMapperTest.php @@ -0,0 +1,40 @@ +phpStanStaticTypeMapper = $this->make(PHPStanStaticTypeMapper::class); + } + + public function testMapToPhpParserNode(): void + { + $node = $this->phpStanStaticTypeMapper->mapToPhpParserNode( + new NonexistentParentClassType(), + TypeKind::RETURN + ); + + $this->assertInstanceOf(Name::class, $node); + $this->assertSame('parent', $node->toString()); + } + + public function testMapToPHPStanPhpDocTypeNode(): void + { + $typeNode = $this->phpStanStaticTypeMapper->mapToPHPStanPhpDocTypeNode(new NonexistentParentClassType()); + $this->assertSame('parent', (string) $typeNode); + } +}