2019-10-13 07:59:52 +02:00
|
|
|
<?php
|
|
|
|
|
2021-05-09 20:15:43 +00:00
|
|
|
declare (strict_types=1);
|
2019-02-28 22:50:53 +01:00
|
|
|
namespace Rector\BetterPhpDocParser\PhpDocInfo;
|
|
|
|
|
2021-01-20 18:41:35 +07:00
|
|
|
use PhpParser\Comment\Doc;
|
2019-02-28 22:50:53 +01:00
|
|
|
use PhpParser\Node;
|
2021-03-20 16:27:18 +01:00
|
|
|
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
|
2019-02-28 22:50:53 +01:00
|
|
|
use PHPStan\PhpDocParser\Lexer\Lexer;
|
2021-01-19 16:03:26 +01:00
|
|
|
use Rector\BetterPhpDocParser\Annotation\AnnotationNaming;
|
2021-07-01 14:10:40 +00:00
|
|
|
use Rector\BetterPhpDocParser\PhpDocNodeFinder\PhpDocNodeByTypeFinder;
|
2021-03-20 16:27:18 +01:00
|
|
|
use Rector\BetterPhpDocParser\PhpDocNodeMapper;
|
2020-10-11 12:40:45 +02:00
|
|
|
use Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser;
|
2021-04-04 11:01:11 +02:00
|
|
|
use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator;
|
2021-04-06 19:33:09 +02:00
|
|
|
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
|
2020-09-01 19:56:30 +02:00
|
|
|
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
|
2021-01-19 20:45:30 +01:00
|
|
|
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
2020-02-06 22:48:18 +01:00
|
|
|
use Rector\Core\Configuration\CurrentNodeProvider;
|
2020-01-29 14:36:09 +01:00
|
|
|
use Rector\NodeTypeResolver\Node\AttributeKey;
|
2020-02-10 10:17:05 +01:00
|
|
|
use Rector\StaticTypeMapper\StaticTypeMapper;
|
2019-02-28 22:50:53 +01:00
|
|
|
final class PhpDocInfoFactory
|
|
|
|
{
|
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var array<string, PhpDocInfo>
|
2019-02-28 22:50:53 +01:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $phpDocInfosByObjectHash = [];
|
2019-02-28 22:50:53 +01:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\BetterPhpDocParser\PhpDocNodeMapper
|
2019-02-28 22:50:53 +01:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $phpDocNodeMapper;
|
2019-08-26 11:37:02 +02:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\Core\Configuration\CurrentNodeProvider
|
2019-08-26 11:37:02 +02:00
|
|
|
*/
|
|
|
|
private $currentNodeProvider;
|
2019-09-06 12:30:58 +02:00
|
|
|
/**
|
2021-08-22 23:17:31 +00:00
|
|
|
* @var \RectorPrefix20210822\PHPStan\PhpDocParser\Lexer\Lexer
|
2019-09-06 12:30:58 +02:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $lexer;
|
2020-02-19 00:54:28 +01:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser
|
2020-02-19 00:54:28 +01:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $betterPhpDocParser;
|
2020-07-29 01:41:20 +02:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\StaticTypeMapper\StaticTypeMapper
|
2020-07-29 01:41:20 +02:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $staticTypeMapper;
|
2021-01-19 16:03:26 +01:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\BetterPhpDocParser\Annotation\AnnotationNaming
|
2021-01-19 16:03:26 +01:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $annotationNaming;
|
2021-02-20 23:48:31 +01:00
|
|
|
/**
|
2021-05-10 23:39:21 +00:00
|
|
|
* @var \Rector\ChangesReporting\Collector\RectorChangeCollector
|
2021-02-20 23:48:31 +01:00
|
|
|
*/
|
2021-05-10 23:39:21 +00:00
|
|
|
private $rectorChangeCollector;
|
2021-07-01 14:10:40 +00:00
|
|
|
/**
|
|
|
|
* @var \Rector\BetterPhpDocParser\PhpDocNodeFinder\PhpDocNodeByTypeFinder
|
|
|
|
*/
|
|
|
|
private $phpDocNodeByTypeFinder;
|
2021-07-01 14:46:27 +00:00
|
|
|
public function __construct(\Rector\BetterPhpDocParser\PhpDocNodeMapper $phpDocNodeMapper, \Rector\Core\Configuration\CurrentNodeProvider $currentNodeProvider, \PHPStan\PhpDocParser\Lexer\Lexer $lexer, \Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser $betterPhpDocParser, \Rector\StaticTypeMapper\StaticTypeMapper $staticTypeMapper, \Rector\BetterPhpDocParser\Annotation\AnnotationNaming $annotationNaming, \Rector\ChangesReporting\Collector\RectorChangeCollector $rectorChangeCollector, \Rector\BetterPhpDocParser\PhpDocNodeFinder\PhpDocNodeByTypeFinder $phpDocNodeByTypeFinder)
|
2021-05-09 20:15:43 +00:00
|
|
|
{
|
2021-05-10 23:39:21 +00:00
|
|
|
$this->phpDocNodeMapper = $phpDocNodeMapper;
|
2019-08-26 11:37:02 +02:00
|
|
|
$this->currentNodeProvider = $currentNodeProvider;
|
2021-05-10 23:39:21 +00:00
|
|
|
$this->lexer = $lexer;
|
|
|
|
$this->betterPhpDocParser = $betterPhpDocParser;
|
2019-09-06 12:30:58 +02:00
|
|
|
$this->staticTypeMapper = $staticTypeMapper;
|
2021-01-19 16:03:26 +01:00
|
|
|
$this->annotationNaming = $annotationNaming;
|
2021-01-19 20:45:30 +01:00
|
|
|
$this->rectorChangeCollector = $rectorChangeCollector;
|
2021-07-01 14:10:40 +00:00
|
|
|
$this->phpDocNodeByTypeFinder = $phpDocNodeByTypeFinder;
|
2020-02-02 19:15:36 +01:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
public function createFromNodeOrEmpty(\PhpParser\Node $node) : \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo
|
2020-12-20 22:05:48 +01:00
|
|
|
{
|
2021-01-18 21:06:02 +01:00
|
|
|
// already added
|
2021-05-10 22:23:08 +00:00
|
|
|
$phpDocInfo = $node->getAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PHP_DOC_INFO);
|
2021-05-09 20:15:43 +00:00
|
|
|
if ($phpDocInfo instanceof \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo) {
|
2021-01-18 21:06:02 +01:00
|
|
|
return $phpDocInfo;
|
|
|
|
}
|
2020-12-20 22:05:48 +01:00
|
|
|
$phpDocInfo = $this->createFromNode($node);
|
2021-05-09 20:15:43 +00:00
|
|
|
if ($phpDocInfo instanceof \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo) {
|
2020-12-20 22:05:48 +01:00
|
|
|
return $phpDocInfo;
|
|
|
|
}
|
|
|
|
return $this->createEmpty($node);
|
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
public function createFromNode(\PhpParser\Node $node) : ?\Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo
|
2019-02-28 22:50:53 +01:00
|
|
|
{
|
2021-05-09 20:15:43 +00:00
|
|
|
$objectHash = \spl_object_hash($node);
|
2021-02-20 23:48:31 +01:00
|
|
|
if (isset($this->phpDocInfosByObjectHash[$objectHash])) {
|
|
|
|
return $this->phpDocInfosByObjectHash[$objectHash];
|
|
|
|
}
|
2021-07-01 13:06:29 +00:00
|
|
|
/** @see \Rector\BetterPhpDocParser\PhpDocParser\DoctrineAnnotationDecorator::decorate() */
|
2020-01-30 22:11:29 +01:00
|
|
|
$this->currentNodeProvider->setNode($node);
|
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-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
|
2021-05-10 22:23:08 +00:00
|
|
|
$tokenIterator = new \Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator([]);
|
|
|
|
$phpDocNode = new \PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode([]);
|
2020-01-30 22:11:29 +01:00
|
|
|
} else {
|
2021-07-08 15:36:45 +00:00
|
|
|
$text = $docComment->getText();
|
|
|
|
$tokens = $this->lexer->tokenize($text);
|
2021-05-10 22:23:08 +00:00
|
|
|
$tokenIterator = new \Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator($tokens);
|
2021-04-06 20:36:50 +02:00
|
|
|
$phpDocNode = $this->betterPhpDocParser->parse($tokenIterator);
|
2020-02-02 19:15:36 +01:00
|
|
|
$this->setPositionOfLastToken($phpDocNode);
|
2019-09-18 12:22:12 +02:00
|
|
|
}
|
2021-04-06 20:36:50 +02:00
|
|
|
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, $tokenIterator, $node);
|
2021-02-20 23:48:31 +01:00
|
|
|
$this->phpDocInfosByObjectHash[$objectHash] = $phpDocInfo;
|
|
|
|
return $phpDocInfo;
|
2020-05-04 22:06:33 +02:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
public function createEmpty(\PhpParser\Node $node) : \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo
|
2020-05-04 22:06:33 +02:00
|
|
|
{
|
2021-07-01 13:06:29 +00:00
|
|
|
/** @see \Rector\BetterPhpDocParser\PhpDocParser\DoctrineAnnotationDecorator::decorate() */
|
2020-05-04 22:06:33 +02:00
|
|
|
$this->currentNodeProvider->setNode($node);
|
2021-05-10 22:23:08 +00:00
|
|
|
$phpDocNode = new \PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode([]);
|
|
|
|
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, new \Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator([]), $node);
|
2021-04-04 11:01:11 +02:00
|
|
|
// multiline by default
|
|
|
|
$phpDocInfo->makeMultiLined();
|
|
|
|
return $phpDocInfo;
|
2019-02-28 22:50:53 +01:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Needed for printing
|
|
|
|
*/
|
2021-05-10 22:23:08 +00:00
|
|
|
private function setPositionOfLastToken(\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode $phpDocNode) : void
|
2020-02-02 19:15:36 +01:00
|
|
|
{
|
2021-03-20 16:27:18 +01:00
|
|
|
if ($phpDocNode->children === []) {
|
2020-02-02 19:15:36 +01:00
|
|
|
return;
|
2019-02-28 22:50:53 +01:00
|
|
|
}
|
2021-03-20 16:27:18 +01:00
|
|
|
$phpDocChildNodes = $phpDocNode->children;
|
2021-05-09 20:15:43 +00:00
|
|
|
$lastChildNode = \array_pop($phpDocChildNodes);
|
2021-05-10 22:23:08 +00:00
|
|
|
$startAndEnd = $lastChildNode->getAttribute(\Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey::START_AND_END);
|
|
|
|
if ($startAndEnd instanceof \Rector\BetterPhpDocParser\ValueObject\StartAndEnd) {
|
|
|
|
$phpDocNode->setAttribute(\Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey::LAST_PHP_DOC_TOKEN_POSITION, $startAndEnd->getEnd());
|
2019-02-28 22:50:53 +01:00
|
|
|
}
|
2020-02-02 19:15:36 +01:00
|
|
|
}
|
2021-05-10 22:23:08 +00:00
|
|
|
private function createFromPhpDocNode(\PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode $phpDocNode, \Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator $betterTokenIterator, \PhpParser\Node $node) : \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo
|
2021-05-09 20:15:43 +00:00
|
|
|
{
|
2021-04-06 20:36:50 +02:00
|
|
|
$this->phpDocNodeMapper->transform($phpDocNode, $betterTokenIterator);
|
2021-07-01 14:46:27 +00:00
|
|
|
$phpDocInfo = new \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo($phpDocNode, $betterTokenIterator, $this->staticTypeMapper, $node, $this->annotationNaming, $this->currentNodeProvider, $this->rectorChangeCollector, $this->phpDocNodeByTypeFinder);
|
2021-05-10 22:23:08 +00:00
|
|
|
$node->setAttribute(\Rector\NodeTypeResolver\Node\AttributeKey::PHP_DOC_INFO, $phpDocInfo);
|
2020-05-04 22:06:33 +02:00
|
|
|
return $phpDocInfo;
|
|
|
|
}
|
2019-02-28 22:50:53 +01:00
|
|
|
}
|