Skip to content

Commit

Permalink
[DX] Lower current node dependency - pass it directly to doc node par…
Browse files Browse the repository at this point in the history
…sing (#5023)
  • Loading branch information
TomasVotruba committed Sep 15, 2023
1 parent 307b9d6 commit f606358
Show file tree
Hide file tree
Showing 20 changed files with 129 additions and 203 deletions.
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Tests\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser;

use Iterator;
use PhpParser\Node\Scalar\String_;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
use Rector\BetterPhpDocParser\PhpDoc\StringNode;
Expand Down Expand Up @@ -32,7 +33,9 @@ public function test(string $docContent, array $expectedArrayItemNodes): void
{
$betterTokenIterator = $this->tokenIteratorFactory->create($docContent);

$arrayItemNodes = $this->arrayParser->parseCurlyArray($betterTokenIterator);
$string = new String_('some_node');

$arrayItemNodes = $this->arrayParser->parseCurlyArray($betterTokenIterator, $string);
$this->assertEquals($expectedArrayItemNodes, $arrayItemNodes);
}

Expand Down
Expand Up @@ -5,6 +5,7 @@
namespace Rector\Tests\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser;

use Iterator;
use PhpParser\Node\Scalar\String_;
use PHPUnit\Framework\Attributes\DataProvider;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
use Rector\BetterPhpDocParser\PhpDoc\StringNode;
Expand Down Expand Up @@ -33,7 +34,8 @@ public function test(string $docContent, CurlyListNode | array $expectedValue):
{
$betterTokenIterator = $this->tokenIteratorFactory->create($docContent);

$value = $this->staticDoctrineAnnotationParser->resolveAnnotationValue($betterTokenIterator);
$string = new String_('some_node');
$value = $this->staticDoctrineAnnotationParser->resolveAnnotationValue($betterTokenIterator, $string);

// "equals" on purpose to compare 2 object with same content
$this->assertEquals($expectedValue, $value);
Expand Down
Expand Up @@ -42,7 +42,7 @@ protected function setUp(): void
$this->processCommand = $this->make(ProcessCommand::class);
}

/**
/**
* @param array<string, mixed> $inputParameters
*/
#[DataProvider('provideDataSpacedMainScript')]
Expand Down
8 changes: 0 additions & 8 deletions packages/BetterPhpDocParser/PhpDocInfo/PhpDocInfoFactory.php
Expand Up @@ -15,7 +15,6 @@
use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator;
use Rector\BetterPhpDocParser\ValueObject\PhpDocAttributeKey;
use Rector\BetterPhpDocParser\ValueObject\StartAndEnd;
use Rector\Core\Configuration\CurrentNodeProvider;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;

Expand All @@ -28,7 +27,6 @@ final class PhpDocInfoFactory

public function __construct(
private readonly PhpDocNodeMapper $phpDocNodeMapper,
private readonly CurrentNodeProvider $currentNodeProvider,
private readonly Lexer $lexer,
private readonly BetterPhpDocParser $betterPhpDocParser,
private readonly StaticTypeMapper $staticTypeMapper,
Expand Down Expand Up @@ -61,9 +59,6 @@ public function createFromNode(Node $node): ?PhpDocInfo
return $this->phpDocInfosByObjectId[$objectId];
}

/** @see \Rector\BetterPhpDocParser\PhpDocParser\DoctrineAnnotationDecorator::decorate() */
$this->currentNodeProvider->setNode($node);

$docComment = $node->getDocComment();
if (! $docComment instanceof Doc) {
if ($node->getComments() === []) {
Expand Down Expand Up @@ -92,9 +87,6 @@ public function createFromNode(Node $node): ?PhpDocInfo
*/
public function createEmpty(Node $node): PhpDocInfo
{
/** @see \Rector\BetterPhpDocParser\PhpDocParser\DoctrineAnnotationDecorator::decorate() */
$this->currentNodeProvider->setNode($node);

$phpDocNode = new PhpDocNode([]);
$phpDocInfo = $this->createFromPhpDocNode($phpDocNode, new BetterTokenIterator([]), $node);

Expand Down
Expand Up @@ -157,7 +157,10 @@ private function transformGenericTagValueNodesToDoctrineAnnotationTagValueNodes(
foreach ($phpDocNode->children as $key => $phpDocChildNode) {
// the @\FQN use case
if ($phpDocChildNode instanceof PhpDocTextNode) {
$spacelessPhpDocTagNode = $this->resolveFqnAnnotationSpacelessPhpDocTagNode($phpDocChildNode);
$spacelessPhpDocTagNode = $this->resolveFqnAnnotationSpacelessPhpDocTagNode(
$phpDocChildNode,
$currentPhpNode
);
if (! $spacelessPhpDocTagNode instanceof SpacelessPhpDocTagNode) {
continue;
}
Expand Down Expand Up @@ -192,7 +195,8 @@ private function transformGenericTagValueNodesToDoctrineAnnotationTagValueNodes(
$spacelessPhpDocTagNode = $this->createSpacelessPhpDocTagNode(
$phpDocChildNode->name,
$phpDocChildNode->value,
$fullyQualifiedAnnotationClass
$fullyQualifiedAnnotationClass,
$currentPhpNode
);

$this->attributeMirrorer->mirror($phpDocChildNode, $spacelessPhpDocTagNode);
Expand Down Expand Up @@ -241,30 +245,36 @@ private function isClosedContent(string $composedContent): bool
private function createSpacelessPhpDocTagNode(
string $tagName,
GenericTagValueNode $genericTagValueNode,
string $fullyQualifiedAnnotationClass
string $fullyQualifiedAnnotationClass,
Node $currentPhpNode
): SpacelessPhpDocTagNode {
$formerStartEnd = $genericTagValueNode->getAttribute(PhpDocAttributeKey::START_AND_END);

return $this->createDoctrineSpacelessPhpDocTagNode(
$genericTagValueNode->value,
$tagName,
$fullyQualifiedAnnotationClass,
$formerStartEnd
$formerStartEnd,
$currentPhpNode
);
}

private function createDoctrineSpacelessPhpDocTagNode(
string $annotationContent,
string $tagName,
string $fullyQualifiedAnnotationClass,
StartAndEnd $startAndEnd
StartAndEnd $startAndEnd,
Node $currentPhpNode
): SpacelessPhpDocTagNode {
$nestedTokenIterator = $this->tokenIteratorFactory->create($annotationContent);

// mimics doctrine behavior just in phpdoc-parser syntax :)
// https://github.com/doctrine/annotations/blob/c66f06b7c83e9a2a7523351a9d5a4b55f885e574/lib/Doctrine/Common/Annotations/DocParser.php#L742

$values = $this->staticDoctrineAnnotationParser->resolveAnnotationMethodCall($nestedTokenIterator);
$values = $this->staticDoctrineAnnotationParser->resolveAnnotationMethodCall(
$nestedTokenIterator,
$currentPhpNode
);

$identifierTypeNode = new IdentifierTypeNode($tagName);
$identifierTypeNode->setAttribute(PhpDocAttributeKey::RESOLVED_CLASS, $fullyQualifiedAnnotationClass);
Expand Down Expand Up @@ -294,8 +304,10 @@ private function combineStartAndEnd(
return new StartAndEnd($currentStartAndEnd->getStart(), $nextStartAndEnd->getEnd());
}

private function resolveFqnAnnotationSpacelessPhpDocTagNode(PhpDocTextNode $phpDocTextNode): ?SpacelessPhpDocTagNode
{
private function resolveFqnAnnotationSpacelessPhpDocTagNode(
PhpDocTextNode $phpDocTextNode,
Node $currentPhpNode
): ?SpacelessPhpDocTagNode {
$match = Strings::match($phpDocTextNode->text, self::LONG_ANNOTATION_REGEX);
$fullyQualifiedAnnotationClass = $match['class_name'] ?? null;

Expand All @@ -312,7 +324,8 @@ private function resolveFqnAnnotationSpacelessPhpDocTagNode(PhpDocTextNode $phpD
$annotationContent,
$tagName,
$fullyQualifiedAnnotationClass,
$formerStartEnd
$formerStartEnd,
$currentPhpNode
);
}
}
Expand Up @@ -4,6 +4,7 @@

namespace Rector\BetterPhpDocParser\PhpDocParser;

use PhpParser\Node;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode;
Expand Down Expand Up @@ -31,7 +32,7 @@ public function __construct(
*
* @return ArrayItemNode[]
*/
public function resolveAnnotationMethodCall(BetterTokenIterator $tokenIterator): array
public function resolveAnnotationMethodCall(BetterTokenIterator $tokenIterator, Node $currentPhpNode): array
{
if (! $tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
return [];
Expand All @@ -44,7 +45,7 @@ public function resolveAnnotationMethodCall(BetterTokenIterator $tokenIterator):
return [];
}

return $this->resolveAnnotationValues($tokenIterator);
return $this->resolveAnnotationValues($tokenIterator, $currentPhpNode);
}

/**
Expand All @@ -53,24 +54,25 @@ public function resolveAnnotationMethodCall(BetterTokenIterator $tokenIterator):
* @return CurlyListNode|string|array<mixed>|ConstExprNode|DoctrineAnnotationTagValueNode|StringNode
*/
public function resolveAnnotationValue(
BetterTokenIterator $tokenIterator
BetterTokenIterator $tokenIterator,
Node $currentPhpNode
): CurlyListNode | string | array | ConstExprNode | DoctrineAnnotationTagValueNode | StringNode {
// skips dummy tokens like newlines
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);

// no assign
if (! $tokenIterator->isNextTokenType(Lexer::TOKEN_EQUAL)) {
// 1. plain value - mimics https://github.com/doctrine/annotations/blob/0cb0cd2950a5c6cdbf22adbe2bfd5fd1ea68588f/lib/Doctrine/Common/Annotations/DocParser.php#L1234-L1282
return $this->parseValue($tokenIterator);
return $this->parseValue($tokenIterator, $currentPhpNode);
}

// 2. assign key = value - mimics FieldAssignment() https://github.com/doctrine/annotations/blob/0cb0cd2950a5c6cdbf22adbe2bfd5fd1ea68588f/lib/Doctrine/Common/Annotations/DocParser.php#L1291-L1303
/** @var int $key */
$key = $this->parseValue($tokenIterator);
$key = $this->parseValue($tokenIterator, $currentPhpNode);
$tokenIterator->consumeTokenType(Lexer::TOKEN_EQUAL);

// mimics https://github.com/doctrine/annotations/blob/1.13.x/lib/Doctrine/Common/Annotations/DocParser.php#L1236-L1238
$value = $this->parseValue($tokenIterator);
$value = $this->parseValue($tokenIterator, $currentPhpNode);

return [
// plain token value
Expand All @@ -83,10 +85,10 @@ public function resolveAnnotationValue(
*
* @return ArrayItemNode[]
*/
private function resolveAnnotationValues(BetterTokenIterator $tokenIterator): array
private function resolveAnnotationValues(BetterTokenIterator $tokenIterator, Node $currentPhpNode): array
{
$values = [];
$resolvedValue = $this->resolveAnnotationValue($tokenIterator);
$resolvedValue = $this->resolveAnnotationValue($tokenIterator, $currentPhpNode);

if (is_array($resolvedValue)) {
$values = array_merge($values, $resolvedValue);
Expand All @@ -102,7 +104,7 @@ private function resolveAnnotationValues(BetterTokenIterator $tokenIterator): ar
continue;
}

$nestedValues = $this->resolveAnnotationValue($tokenIterator);
$nestedValues = $this->resolveAnnotationValue($tokenIterator, $currentPhpNode);

if (is_array($nestedValues)) {
$values = array_merge($values, $nestedValues);
Expand All @@ -122,13 +124,14 @@ private function resolveAnnotationValues(BetterTokenIterator $tokenIterator): ar
* @return CurlyListNode|string|array<mixed>|ConstExprNode|DoctrineAnnotationTagValueNode|StringNode
*/
private function parseValue(
BetterTokenIterator $tokenIterator
BetterTokenIterator $tokenIterator,
Node $currentPhpNode
): CurlyListNode | string | array | ConstExprNode | DoctrineAnnotationTagValueNode | StringNode {
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) {
$items = $this->arrayParser->parseCurlyArray($tokenIterator);
$items = $this->arrayParser->parseCurlyArray($tokenIterator, $currentPhpNode);
return new CurlyListNode($items);
}

return $this->plainValueParser->parseValue($tokenIterator);
return $this->plainValueParser->parseValue($tokenIterator, $currentPhpNode);
}
}
Expand Up @@ -4,6 +4,7 @@

namespace Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser;

use PhpParser\Node;
use PhpParser\Node\Scalar\String_;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
use PHPStan\PhpDocParser\Lexer\Lexer;
Expand All @@ -26,7 +27,7 @@ public function __construct(
*
* @return ArrayItemNode[]
*/
public function parseCurlyArray(BetterTokenIterator $tokenIterator): array
public function parseCurlyArray(BetterTokenIterator $tokenIterator, Node $currentPhpNode): array
{
$values = [];

Expand All @@ -44,7 +45,7 @@ public function parseCurlyArray(BetterTokenIterator $tokenIterator): array
}

// first item
$values[] = $this->resolveArrayItem($tokenIterator);
$values[] = $this->resolveArrayItem($tokenIterator, $currentPhpNode);

// 2nd+ item
while ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_COMMA)) {
Expand All @@ -56,7 +57,7 @@ public function parseCurlyArray(BetterTokenIterator $tokenIterator): array
break;
}

$values[] = $this->resolveArrayItem($tokenIterator);
$values[] = $this->resolveArrayItem($tokenIterator, $currentPhpNode);
if ($tokenIterator->isNextTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
break;
}
Expand Down Expand Up @@ -108,7 +109,7 @@ public function createArrayFromValues(array $values): array
* Mimics https://github.com/doctrine/annotations/blob/c66f06b7c83e9a2a7523351a9d5a4b55f885e574/lib/Doctrine/Common/Annotations/DocParser.php#L1354-L1385
* @return array<null|mixed, mixed>
*/
private function resolveArrayItem(BetterTokenIterator $tokenIterator): array
private function resolveArrayItem(BetterTokenIterator $tokenIterator, Node $currentPhpNode): array
{
// skip newlines
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
Expand Down Expand Up @@ -145,20 +146,20 @@ private function resolveArrayItem(BetterTokenIterator $tokenIterator): array

if ($key === null) {
if ($tokenIterator->isNextTokenType(Lexer::TOKEN_IDENTIFIER)) {
$key = $this->plainValueParser->parseValue($tokenIterator);
$key = $this->plainValueParser->parseValue($tokenIterator, $currentPhpNode);
} else {
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_COMMA);
$key = $this->plainValueParser->parseValue($tokenIterator);
$key = $this->plainValueParser->parseValue($tokenIterator, $currentPhpNode);
}
}

$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_COLON);

return [$key, $this->plainValueParser->parseValue($tokenIterator)];
return [$key, $this->plainValueParser->parseValue($tokenIterator, $currentPhpNode)];
}

return [$key, $this->plainValueParser->parseValue($tokenIterator)];
return [$key, $this->plainValueParser->parseValue($tokenIterator, $currentPhpNode)];
}

/**
Expand Down

0 comments on commit f606358

Please sign in to comment.