mirror of https://github.com/rectorphp/rector.git
75 lines
2.5 KiB
PHP
75 lines
2.5 KiB
PHP
<?php
|
|
|
|
declare (strict_types=1);
|
|
namespace Rector\StaticTypeMapper\PhpDoc;
|
|
|
|
use PhpParser\Node;
|
|
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasImportTagValueNode;
|
|
use PHPStan\PhpDocParser\Ast\PhpDoc\TypeAliasTagValueNode;
|
|
use PHPStan\Type\Type;
|
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
|
use Rector\StaticTypeMapper\ValueObject\Type\NonExistingObjectType;
|
|
final class CustomPHPStanDetector
|
|
{
|
|
/**
|
|
* @readonly
|
|
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
|
|
*/
|
|
private $phpDocInfoFactory;
|
|
public function __construct(PhpDocInfoFactory $phpDocInfoFactory)
|
|
{
|
|
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
|
}
|
|
/**
|
|
* @api
|
|
*/
|
|
public function isCustomType(Type $definedType, Node $node) : bool
|
|
{
|
|
if (!$definedType instanceof NonExistingObjectType) {
|
|
return \false;
|
|
}
|
|
// start from current Node to lookup parent
|
|
$parentNode = $node;
|
|
$className = $definedType->getClassName();
|
|
while ($parentNode instanceof Node) {
|
|
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($parentNode);
|
|
if ($this->isUsePHPStanImportType($phpDocInfo, $className)) {
|
|
return \true;
|
|
}
|
|
if ($this->isUsePHPStanType($phpDocInfo, $className)) {
|
|
return \true;
|
|
}
|
|
$parentNode = $parentNode->getAttribute(AttributeKey::PARENT_NODE);
|
|
}
|
|
return \false;
|
|
}
|
|
private function isUsePHPStanImportType(PhpDocInfo $phpDocInfo, string $className) : bool
|
|
{
|
|
$tagsByName = $phpDocInfo->getTagsByName('phpstan-import-type');
|
|
foreach ($tagsByName as $tags) {
|
|
if (!$tags->value instanceof TypeAliasImportTagValueNode) {
|
|
continue;
|
|
}
|
|
if ($tags->value->importedAlias === $className) {
|
|
return \true;
|
|
}
|
|
}
|
|
return \false;
|
|
}
|
|
private function isUsePHPStanType(PhpDocInfo $phpDocInfo, string $className) : bool
|
|
{
|
|
$tagsByName = $phpDocInfo->getTagsByName('phpstan-type');
|
|
foreach ($tagsByName as $tags) {
|
|
if (!$tags->value instanceof TypeAliasTagValueNode) {
|
|
continue;
|
|
}
|
|
if ($tags->value->alias === $className) {
|
|
return \true;
|
|
}
|
|
}
|
|
return \false;
|
|
}
|
|
}
|