168 lines
5.0 KiB
PHP
Raw Normal View History

2019-10-13 07:59:52 +02:00
<?php
declare(strict_types=1);
2019-02-28 22:50:53 +01:00
namespace Rector\BetterPhpDocParser\PhpDocInfo;
use PhpParser\Node;
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwarePhpDocNode;
2020-02-19 00:54:28 +01:00
use Rector\BetterPhpDocParser\Attributes\Ast\AttributeAwareNodeFactory;
2019-02-28 22:50:53 +01:00
use Rector\BetterPhpDocParser\Attributes\Attribute\Attribute;
use Rector\BetterPhpDocParser\Contract\PhpDocNode\AttributeAwareNodeInterface;
use Rector\BetterPhpDocParser\Contract\PhpDocNodeFactoryInterface;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocRemover;
2020-07-27 11:26:41 +02:00
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
2020-10-11 12:40:45 +02:00
use Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser;
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;
2019-02-28 22:50:53 +01:00
final class PhpDocInfoFactory
{
/**
* @var PhpDocParser
*/
2020-10-11 12:40:45 +02:00
private $betterPhpDocParser;
2019-02-28 22:50:53 +01:00
/**
* @var Lexer
*/
private $lexer;
/**
* @var CurrentNodeProvider
*/
private $currentNodeProvider;
/**
* @var StaticTypeMapper
*/
private $staticTypeMapper;
2020-02-19 00:54:28 +01:00
/**
* @var AttributeAwareNodeFactory
*/
private $attributeAwareNodeFactory;
/**
2020-07-27 11:26:41 +02:00
* @var PhpDocTypeChanger
*/
2020-07-27 11:26:41 +02:00
private $phpDocTypeChanger;
/**
* @var PhpDocRemover
*/
private $phpDocRemover;
2019-02-28 22:50:53 +01:00
public function __construct(
2020-07-26 09:49:22 +02:00
AttributeAwareNodeFactory $attributeAwareNodeFactory,
CurrentNodeProvider $currentNodeProvider,
2020-07-26 09:49:22 +02:00
Lexer $lexer,
2020-10-11 12:40:45 +02:00
BetterPhpDocParser $betterPhpDocParser,
PhpDocRemover $phpDocRemover,
PhpDocTypeChanger $phpDocTypeChanger,
StaticTypeMapper $staticTypeMapper
2019-02-28 22:50:53 +01:00
) {
2020-10-11 12:40:45 +02:00
$this->betterPhpDocParser = $betterPhpDocParser;
2019-02-28 22:50:53 +01:00
$this->lexer = $lexer;
$this->currentNodeProvider = $currentNodeProvider;
$this->staticTypeMapper = $staticTypeMapper;
2020-02-19 00:54:28 +01:00
$this->attributeAwareNodeFactory = $attributeAwareNodeFactory;
2020-07-27 11:26:41 +02:00
$this->phpDocTypeChanger = $phpDocTypeChanger;
$this->phpDocRemover = $phpDocRemover;
2020-02-02 19:15:36 +01:00
}
2020-02-16 22:29:32 +01:00
public function createFromNode(Node $node): ?PhpDocInfo
2019-02-28 22:50:53 +01:00
{
2020-01-30 22:11:29 +01:00
/** needed for @see PhpDocNodeFactoryInterface */
$this->currentNodeProvider->setNode($node);
if ($node->getDocComment() === null) {
2020-02-02 19:15:36 +01:00
if ($node->getComments() !== []) {
2020-02-16 22:29:32 +01:00
return null;
2020-02-02 19:15:36 +01:00
}
2020-02-16 22:29:32 +01:00
// create empty node
$content = '';
$tokens = [];
$phpDocNode = new AttributeAwarePhpDocNode([]);
2020-01-30 22:11:29 +01:00
} else {
$content = $node->getDocComment()
->getText();
2020-01-30 22:11:29 +01:00
$tokens = $this->lexer->tokenize($content);
2020-02-02 19:15:36 +01:00
$phpDocNode = $this->parseTokensToPhpDocNode($tokens);
$this->setPositionOfLastToken($phpDocNode);
2019-09-18 12:22:12 +02:00
}
2020-05-04 22:06:33 +02:00
return $this->createFromPhpDocNode($phpDocNode, $content, $tokens, $node);
}
2020-02-19 00:54:28 +01:00
2020-05-04 22:06:33 +02:00
public function createEmpty(Node $node): PhpDocInfo
{
/** needed for @see PhpDocNodeFactoryInterface */
$this->currentNodeProvider->setNode($node);
2019-09-18 12:22:12 +02:00
2020-07-19 23:36:10 +02:00
$attributeAwarePhpDocNode = new AttributeAwarePhpDocNode([]);
2020-05-04 22:06:33 +02:00
2020-07-19 23:36:10 +02:00
return $this->createFromPhpDocNode($attributeAwarePhpDocNode, '', [], $node);
2019-02-28 22:50:53 +01:00
}
private function parseTokensToPhpDocNode(array $tokens): AttributeAwarePhpDocNode
{
$tokenIterator = new TokenIterator($tokens);
2020-10-11 12:40:45 +02:00
return $this->betterPhpDocParser->parse($tokenIterator);
}
2019-02-28 22:50:53 +01:00
/**
* Needed for printing
*/
2020-02-02 19:15:36 +01:00
private function setPositionOfLastToken(AttributeAwarePhpDocNode $attributeAwarePhpDocNode): void
{
2019-02-28 22:50:53 +01:00
if ($attributeAwarePhpDocNode->children === []) {
2020-02-02 19:15:36 +01:00
return;
2019-02-28 22:50:53 +01:00
}
$phpDocChildNodes = $attributeAwarePhpDocNode->children;
2019-07-04 12:26:39 +03:00
/** @var AttributeAwareNodeInterface $lastChildNode */
2019-02-28 22:50:53 +01:00
$lastChildNode = array_pop($phpDocChildNodes);
/** @var StartAndEnd $startAndEnd */
$startAndEnd = $lastChildNode->getAttribute(Attribute::START_END);
if ($startAndEnd !== null) {
$attributeAwarePhpDocNode->setAttribute(Attribute::LAST_TOKEN_POSITION, $startAndEnd->getEnd());
2019-02-28 22:50:53 +01:00
}
2020-02-02 19:15:36 +01:00
}
2020-05-04 22:06:33 +02:00
private function createFromPhpDocNode(
AttributeAwarePhpDocNode $attributeAwarePhpDocNode,
string $content,
array $tokens,
Node $node
): PhpDocInfo {
/** @var AttributeAwarePhpDocNode $attributeAwarePhpDocNode */
$attributeAwarePhpDocNode = $this->attributeAwareNodeFactory->createFromNode(
$attributeAwarePhpDocNode,
$content
);
$phpDocInfo = new PhpDocInfo(
$attributeAwarePhpDocNode,
$tokens,
$content,
$this->staticTypeMapper,
$node,
$this->phpDocTypeChanger,
$this->phpDocRemover
2020-05-04 22:06:33 +02:00
);
$node->setAttribute(AttributeKey::PHP_DOC_INFO, $phpDocInfo);
return $phpDocInfo;
}
2019-02-28 22:50:53 +01:00
}