mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-13 06:32:22 +00:00
fc10fce13d
* re-enable rectify and ecs * [Rectify] [Php81] Enable Rectify on Readonly Property only * comment * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify * [ci-review] Rector Rectify Co-authored-by: GitHub Action <action@github.com>
128 lines
4.2 KiB
PHP
128 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser;
|
|
|
|
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
|
|
use PHPStan\PhpDocParser\Lexer\Lexer;
|
|
use Rector\BetterPhpDocParser\ValueObject\Parser\BetterTokenIterator;
|
|
|
|
/**
|
|
* @see \Rector\Tests\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParserTest
|
|
*/
|
|
final class ArrayParser
|
|
{
|
|
public function __construct(
|
|
private readonly PlainValueParser $plainValueParser
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Mimics https://github.com/doctrine/annotations/blob/c66f06b7c83e9a2a7523351a9d5a4b55f885e574/lib/Doctrine/Common/Annotations/DocParser.php#L1305-L1352
|
|
* @return mixed[]
|
|
*/
|
|
public function parseCurlyArray(BetterTokenIterator $tokenIterator): array
|
|
{
|
|
$values = [];
|
|
|
|
// nothing
|
|
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
|
return [];
|
|
}
|
|
|
|
$tokenIterator->consumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET);
|
|
|
|
// If the array is empty, stop parsing and return.
|
|
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
|
$tokenIterator->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET);
|
|
return [];
|
|
}
|
|
|
|
// first item
|
|
$values[] = $this->resolveArrayItem($tokenIterator);
|
|
|
|
// 2nd+ item
|
|
while ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_COMMA)) {
|
|
// optional trailing comma
|
|
$tokenIterator->consumeTokenType(Lexer::TOKEN_COMMA);
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
|
|
|
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
|
break;
|
|
}
|
|
|
|
$values[] = $this->resolveArrayItem($tokenIterator);
|
|
if ($tokenIterator->isNextTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
|
break;
|
|
}
|
|
|
|
// skip newlines
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
|
}
|
|
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
|
|
|
// special case for nested doctrine annotations
|
|
if (! $tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET);
|
|
}
|
|
|
|
return $this->createArrayFromValues($values);
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
{
|
|
// skip newlines
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
|
|
|
if ($tokenIterator->isNextTokenTypes([Lexer::TOKEN_EQUAL, Lexer::TOKEN_COLON])) {
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_COLON);
|
|
|
|
if ($tokenIterator->isNextTokenType(Lexer::TOKEN_IDENTIFIER)) {
|
|
$key = $this->plainValueParser->parseValue($tokenIterator);
|
|
} else {
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_COMMA);
|
|
$key = $this->plainValueParser->parseValue($tokenIterator);
|
|
}
|
|
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_EQUAL);
|
|
$tokenIterator->tryConsumeTokenType(Lexer::TOKEN_COLON);
|
|
|
|
return [$key, $this->plainValueParser->parseValue($tokenIterator)];
|
|
}
|
|
|
|
return [null, $this->plainValueParser->parseValue($tokenIterator)];
|
|
}
|
|
|
|
/**
|
|
* @param mixed[] $values
|
|
* @return mixed[]
|
|
*/
|
|
private function createArrayFromValues(array $values): array
|
|
{
|
|
$array = [];
|
|
|
|
foreach ($values as $value) {
|
|
[$key, $val] = $value;
|
|
|
|
if ($key instanceof ConstExprIntegerNode) {
|
|
$key = $key->value;
|
|
}
|
|
|
|
if ($key !== null) {
|
|
$array[$key] = $val;
|
|
} else {
|
|
$array[] = $val;
|
|
}
|
|
}
|
|
|
|
return $array;
|
|
}
|
|
}
|