2020-03-01 00:25:07 +01:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2020-03-01 00:25:07 +01:00
|
|
|
namespace Rector\CodingStyle\Node;
|
|
|
|
|
2021-10-27 08:50:45 +00:00
|
|
|
use RectorPrefix20211027\Nette\Utils\Strings;
|
2021-01-20 18:41:35 +07:00
|
|
|
use PhpParser\Comment\Doc;
|
2020-03-01 00:25:07 +01:00
|
|
|
use PhpParser\Node;
|
|
|
|
use PHPStan\Type\Type;
|
|
|
|
use PHPStan\Type\UnionType;
|
|
|
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
2021-01-19 22:32:28 +01:00
|
|
|
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
2020-12-24 17:31:24 +01:00
|
|
|
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
|
2021-10-27 08:50:45 +00:00
|
|
|
use RectorPrefix20211027\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
2020-03-01 00:25:07 +01:00
|
|
|
final class DocAliasResolver
|
|
|
|
{
|
2020-09-23 11:16:40 +02:00
|
|
|
/**
|
|
|
|
* @var string
|
2020-10-30 01:04:33 +07:00
|
|
|
* @see https://regex101.com/r/cWpliJ/1
|
2020-09-23 11:16:40 +02:00
|
|
|
*/
|
2021-05-09 20:15:43 +00:00
|
|
|
private const DOC_ALIAS_REGEX = '#\\@(?<possible_alias>\\w+)(\\\\)?#s';
|
2020-03-01 00:25:07 +01:00
|
|
|
/**
|
2021-08-23 00:20:32 +00:00
|
|
|
* @var \Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser
|
2020-03-01 00:25:07 +01:00
|
|
|
*/
|
2021-01-16 22:45:18 +01:00
|
|
|
private $simpleCallableNodeTraverser;
|
2021-01-19 22:32:28 +01:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory
|
2021-01-19 22:32:28 +01:00
|
|
|
*/
|
|
|
|
private $phpDocInfoFactory;
|
2021-10-27 08:50:45 +00:00
|
|
|
public function __construct(\RectorPrefix20211027\Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser $simpleCallableNodeTraverser, \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory $phpDocInfoFactory)
|
2021-05-09 20:15:43 +00:00
|
|
|
{
|
2021-01-16 22:45:18 +01:00
|
|
|
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
2021-01-19 22:32:28 +01:00
|
|
|
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
2020-03-01 00:25:07 +01:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
public function resolve(\PhpParser\Node $node) : array
|
2020-03-01 00:25:07 +01:00
|
|
|
{
|
|
|
|
$possibleDocAliases = [];
|
2021-05-10 22:23:08 +00:00
|
|
|
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($node, function (\PhpParser\Node $node) use(&$possibleDocAliases) : void {
|
2020-11-16 17:50:38 +00:00
|
|
|
$docComment = $node->getDocComment();
|
2021-05-10 22:23:08 +00:00
|
|
|
if (!$docComment instanceof \PhpParser\Comment\Doc) {
|
2020-03-01 00:25:07 +01:00
|
|
|
return;
|
|
|
|
}
|
2021-01-19 22:32:28 +01:00
|
|
|
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
2020-12-21 03:12:42 +01:00
|
|
|
$possibleDocAliases = $this->collectVarType($phpDocInfo, $possibleDocAliases);
|
2020-03-01 00:25:07 +01:00
|
|
|
// e.g. "use Dotrine\ORM\Mapping as ORM" etc.
|
2021-10-27 08:50:45 +00:00
|
|
|
$matches = \RectorPrefix20211027\Nette\Utils\Strings::matchAll($docComment->getText(), self::DOC_ALIAS_REGEX);
|
2020-03-01 00:25:07 +01:00
|
|
|
foreach ($matches as $match) {
|
|
|
|
$possibleDocAliases[] = $match['possible_alias'];
|
|
|
|
}
|
|
|
|
});
|
2021-05-09 20:15:43 +00:00
|
|
|
return \array_unique($possibleDocAliases);
|
2020-03-01 00:25:07 +01:00
|
|
|
}
|
|
|
|
/**
|
2020-04-26 02:57:47 +02:00
|
|
|
* @param string[] $possibleDocAliases
|
2020-03-01 00:25:07 +01:00
|
|
|
* @return string[]
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function collectVarType(\Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo $phpDocInfo, array $possibleDocAliases) : array
|
2020-03-01 00:25:07 +01:00
|
|
|
{
|
2020-04-26 02:57:47 +02:00
|
|
|
$possibleDocAliases = $this->appendPossibleAliases($phpDocInfo->getVarType(), $possibleDocAliases);
|
|
|
|
$possibleDocAliases = $this->appendPossibleAliases($phpDocInfo->getReturnType(), $possibleDocAliases);
|
2020-12-05 00:22:12 +01:00
|
|
|
foreach ($phpDocInfo->getParamTypesByName() as $paramType) {
|
2020-04-26 02:57:47 +02:00
|
|
|
$possibleDocAliases = $this->appendPossibleAliases($paramType, $possibleDocAliases);
|
2020-03-01 00:25:07 +01:00
|
|
|
}
|
|
|
|
return $possibleDocAliases;
|
|
|
|
}
|
2020-03-01 00:45:06 +01:00
|
|
|
/**
|
2020-10-11 16:17:43 +02:00
|
|
|
* @param string[] $possibleDocAliases
|
2020-03-01 00:45:06 +01:00
|
|
|
* @return string[]
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function appendPossibleAliases(\PHPStan\Type\Type $varType, array $possibleDocAliases) : array
|
2020-03-01 00:45:06 +01:00
|
|
|
{
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($varType instanceof \Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType) {
|
2020-04-26 02:57:47 +02:00
|
|
|
$possibleDocAliases[] = $varType->getClassName();
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
if ($varType instanceof \PHPStan\Type\UnionType) {
|
2020-04-26 02:57:47 +02:00
|
|
|
foreach ($varType->getTypes() as $type) {
|
|
|
|
$possibleDocAliases = $this->appendPossibleAliases($type, $possibleDocAliases);
|
|
|
|
}
|
2020-03-01 00:45:06 +01:00
|
|
|
}
|
|
|
|
return $possibleDocAliases;
|
|
|
|
}
|
2020-03-01 00:25:07 +01:00
|
|
|
}
|