Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector\Fixture;

trait ReturnNewParentInTrait
{
public function __construct(...$args)
{
self::createLazyProxy(static fn () => new parent(...$args), $this);
}
}

?>
-----
<?php

declare(strict_types=1);

namespace Rector\Tests\TypeDeclaration\Rector\ArrowFunction\AddArrowFunctionReturnTypeRector\Fixture;

trait ReturnNewParentInTrait
{
public function __construct(...$args)
{
self::createLazyProxy(static fn (): parent => new parent(...$args), $this);
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\ClosureReturnTypeRector\Fixture;

trait ReturnNewParentInTrait
{
public function createParentClosure()
{
return static function () {
return new parent();
};
}
}

?>
-----
<?php

namespace Rector\Tests\TypeDeclaration\Rector\Closure\ClosureReturnTypeRector\Fixture;

trait ReturnNewParentInTrait
{
public function createParentClosure()
{
return static function (): parent {
return new parent();
};
}
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Rector\PHPStanStaticTypeMapper\TypeMapper;

use PhpParser\Node\Name;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\NonexistentParentClassType;
use PHPStan\Type\Type;
use Rector\Enum\ObjectReference;
use Rector\PHPStanStaticTypeMapper\Contract\TypeMapperInterface;

/**
* PHPStan resolves "parent" to this type when the parent class is unknown at analysis time,
* typically inside a trait, where "parent" is only bound once the trait is used by a class.
* PHP accepts "parent" as a native type in traits, so it is kept as-is.
*
* @implements TypeMapperInterface<NonexistentParentClassType>
* @see \Rector\Tests\PHPStanStaticTypeMapper\TypeMapper\NonexistentParentClassTypeMapperTest
*/
final class NonexistentParentClassTypeMapper implements TypeMapperInterface
{
/**
* @return array<class-string<Type>>
*/
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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\PHPStanStaticTypeMapper\TypeMapper;

use PhpParser\Node\Name;
use PHPStan\Type\NonexistentParentClassType;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\PHPStanStaticTypeMapper\PHPStanStaticTypeMapper;
use Rector\Testing\PHPUnit\AbstractLazyTestCase;

final class NonexistentParentClassTypeMapperTest extends AbstractLazyTestCase
{
private PHPStanStaticTypeMapper $phpStanStaticTypeMapper;

protected function setUp(): void
{
parent::setUp();

$this->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);
}
}
Loading