rector/rules/CodingStyle/Node/DocAliasResolver.php
Tomas Votruba 6fa9c12855 Updated Rector to commit 4f26e3643d638a69edaf1064cf59c13f373d557d
4f26e3643d [Scoped] Early downgrade src/functions (#185)
2021-06-09 02:43:00 +00:00

86 lines
3.5 KiB
PHP

<?php
declare (strict_types=1);
namespace Rector\CodingStyle\Node;
use RectorPrefix20210609\Nette\Utils\Strings;
use PhpParser\Comment\Doc;
use PhpParser\Node;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
use RectorPrefix20210609\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
final class DocAliasResolver
{
/**
* @var string
* @see https://regex101.com/r/cWpliJ/1
*/
private const DOC_ALIAS_REGEX = '#\\@(?<possible_alias>\\w+)(\\\\)?#s';
/**
* @var \Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser
*/
private $simpleCallableNodeTraverser;
/**
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
*/
private $phpDocInfoFactory;
public function __construct(\RectorPrefix20210609\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser $simpleCallableNodeTraverser, \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory $phpDocInfoFactory)
{
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
$this->phpDocInfoFactory = $phpDocInfoFactory;
}
/**
* @return string[]
*/
public function resolve(\PhpParser\Node $node) : array
{
$possibleDocAliases = [];
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($node, function (\PhpParser\Node $node) use(&$possibleDocAliases) : void {
$docComment = $node->getDocComment();
if (!$docComment instanceof \PhpParser\Comment\Doc) {
return;
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
$possibleDocAliases = $this->collectVarType($phpDocInfo, $possibleDocAliases);
// e.g. "use Dotrine\ORM\Mapping as ORM" etc.
$matches = \RectorPrefix20210609\Nette\Utils\Strings::matchAll($docComment->getText(), self::DOC_ALIAS_REGEX);
foreach ($matches as $match) {
$possibleDocAliases[] = $match['possible_alias'];
}
});
return \array_unique($possibleDocAliases);
}
/**
* @param string[] $possibleDocAliases
* @return string[]
*/
private function collectVarType(\Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo $phpDocInfo, array $possibleDocAliases) : array
{
$possibleDocAliases = $this->appendPossibleAliases($phpDocInfo->getVarType(), $possibleDocAliases);
$possibleDocAliases = $this->appendPossibleAliases($phpDocInfo->getReturnType(), $possibleDocAliases);
foreach ($phpDocInfo->getParamTypesByName() as $paramType) {
$possibleDocAliases = $this->appendPossibleAliases($paramType, $possibleDocAliases);
}
return $possibleDocAliases;
}
/**
* @param string[] $possibleDocAliases
* @return string[]
*/
private function appendPossibleAliases(\PHPStan\Type\Type $varType, array $possibleDocAliases) : array
{
if ($varType instanceof \Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType) {
$possibleDocAliases[] = $varType->getClassName();
}
if ($varType instanceof \PHPStan\Type\UnionType) {
foreach ($varType->getTypes() as $type) {
$possibleDocAliases = $this->appendPossibleAliases($type, $possibleDocAliases);
}
}
return $possibleDocAliases;
}
}