From 1d1dc73fcbac8f15b4af03b7baa5ee90fe71f0e2 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 30 Jun 2021 02:48:45 +0200 Subject: [PATCH] [PHP 8.0] Fix attribute multi-line (#337) Co-authored-by: GitHub Action --- .../StaticDoctrineAnnotationParser.php | 8 ++- .../PlainValueParser.php | 49 ++++++++++++++----- .../MethodParameterTypeResolver.php | 9 +--- .../Printer/PhpAttributeGroupFactory.php | 1 - .../Fixture/multiline_content.php.inc | 31 ++++++++++++ .../FuncGetArgsToVariadicParamRector.php | 3 +- 6 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 rules-tests/Php80/Rector/Class_/AnnotationToAttributeRector/Fixture/multiline_content.php.inc diff --git a/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser.php b/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser.php index 60e718b7205..d5639ed66e2 100644 --- a/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser.php +++ b/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser.php @@ -4,9 +4,7 @@ namespace Rector\BetterPhpDocParser\PhpDocParser; -use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprFalseNode; -use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode; -use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprTrueNode; +use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode; use PHPStan\PhpDocParser\Lexer\Lexer; use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser; @@ -52,7 +50,7 @@ public function resolveAnnotationMethodCall(BetterTokenIterator $tokenIterator): */ public function resolveAnnotationValue( BetterTokenIterator $tokenIterator - ): CurlyListNode | string | array | ConstExprFalseNode | ConstExprTrueNode | ConstExprIntegerNode | DoctrineAnnotationTagValueNode { + ): CurlyListNode | string | array | ConstExprNode | DoctrineAnnotationTagValueNode { // skips dummy tokens like newlines $tokenIterator->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); @@ -116,7 +114,7 @@ private function resolveAnnotationValues(BetterTokenIterator $tokenIterator): ar */ private function parseValue( BetterTokenIterator $tokenIterator - ): CurlyListNode | string | array | ConstExprFalseNode | ConstExprTrueNode | ConstExprIntegerNode | DoctrineAnnotationTagValueNode { + ): CurlyListNode | string | array | ConstExprNode | DoctrineAnnotationTagValueNode { if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) { $items = $this->arrayParser->parseCurlyArray($tokenIterator); return new CurlyListNode($items); diff --git a/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/PlainValueParser.php b/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/PlainValueParser.php index 3b97ae9f102..fb2b00543fc 100644 --- a/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/PlainValueParser.php +++ b/packages/BetterPhpDocParser/PhpDocParser/StaticDoctrineAnnotationParser/PlainValueParser.php @@ -7,6 +7,7 @@ use PhpParser\Node; use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprFalseNode; use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode; +use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode; use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprTrueNode; use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Lexer\Lexer; @@ -44,7 +45,7 @@ public function autowirePlainValueParser( */ public function parseValue( BetterTokenIterator $tokenIterator - ): string | array | ConstExprFalseNode | ConstExprTrueNode | ConstExprIntegerNode | DoctrineAnnotationTagValueNode { + ): string | array | ConstExprNode | DoctrineAnnotationTagValueNode { $currentTokenValue = $tokenIterator->currentTokenValue(); // temporary hackaround multi-line doctrine annotations @@ -61,16 +62,9 @@ public function parseValue( $tokenIterator->next(); // normalize value - if (strtolower($currentTokenValue) === 'false') { - return new ConstExprFalseNode(); - } - - if (strtolower($currentTokenValue) === 'true') { - return new ConstExprTrueNode(); - } - - if (is_numeric($currentTokenValue) && (string) (int) $currentTokenValue === $currentTokenValue) { - return new ConstExprIntegerNode($currentTokenValue); + $constantValue = $this->matchConstantValue($currentTokenValue); + if ($constantValue !== null) { + return $constantValue; } while ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_DOUBLE_COLON) || @@ -85,6 +79,21 @@ public function parseValue( return $this->parseNestedDoctrineAnnotationTagValueNode($currentTokenValue, $tokenIterator); } + $start = $tokenIterator->currentPosition(); + + if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) { + while ($tokenIterator->isCurrentTokenTypes( + [Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_IDENTIFIER, Lexer::TOKEN_COLON] + )) { + $tokenIterator->next(); + } + } + + $end = $tokenIterator->currentPosition(); + if ($start + 1 < $end) { + return $tokenIterator->printFromTo($start, $end); + } + return $currentTokenValue; } @@ -113,4 +122,22 @@ private function parseNestedDoctrineAnnotationTagValueNode( $identifierTypeNode = new IdentifierTypeNode($fullyQualifiedAnnotationClass); return new DoctrineAnnotationTagValueNode($identifierTypeNode, $annotationShortName, $values); } + + private function matchConstantValue(string $currentTokenValue): ConstExprNode | null + { + if (strtolower($currentTokenValue) === 'false') { + return new ConstExprFalseNode(); + } + + if (strtolower($currentTokenValue) === 'true') { + return new ConstExprTrueNode(); + } + if (! is_numeric($currentTokenValue)) { + return null; + } + if ((string) (int) $currentTokenValue !== $currentTokenValue) { + return null; + } + return new ConstExprIntegerNode($currentTokenValue); + } } diff --git a/packages/NodeTypeResolver/MethodParameterTypeResolver.php b/packages/NodeTypeResolver/MethodParameterTypeResolver.php index 9ce1d248ae8..0460e41242e 100644 --- a/packages/NodeTypeResolver/MethodParameterTypeResolver.php +++ b/packages/NodeTypeResolver/MethodParameterTypeResolver.php @@ -29,14 +29,7 @@ public function provideParameterTypesByStaticCall(StaticCall $staticCall): array return []; } - $parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); - - $parameterTypes = []; - foreach ($parametersAcceptor->getParameters() as $parameterReflection) { - $parameterTypes[] = $parameterReflection->getType(); - } - - return $parameterTypes; + return $this->provideParameterTypesFromMethodReflection($methodReflection); } /** diff --git a/packages/PhpAttribute/Printer/PhpAttributeGroupFactory.php b/packages/PhpAttribute/Printer/PhpAttributeGroupFactory.php index 4015d70af33..87b5657a1a4 100644 --- a/packages/PhpAttribute/Printer/PhpAttributeGroupFactory.php +++ b/packages/PhpAttribute/Printer/PhpAttributeGroupFactory.php @@ -75,7 +75,6 @@ public function create( public function createArgsFromItems(array $items, ?string $silentKey = null): array { $args = []; - if ($silentKey !== null && isset($items[$silentKey])) { $silentValue = BuilderHelpers::normalizeValue($items[$silentKey]); $this->normalizeStringDoubleQuote($silentValue); diff --git a/rules-tests/Php80/Rector/Class_/AnnotationToAttributeRector/Fixture/multiline_content.php.inc b/rules-tests/Php80/Rector/Class_/AnnotationToAttributeRector/Fixture/multiline_content.php.inc new file mode 100644 index 00000000000..8f2914fe578 --- /dev/null +++ b/rules-tests/Php80/Rector/Class_/AnnotationToAttributeRector/Fixture/multiline_content.php.inc @@ -0,0 +1,31 @@ + +----- + diff --git a/rules/CodingStyle/Rector/ClassMethod/FuncGetArgsToVariadicParamRector.php b/rules/CodingStyle/Rector/ClassMethod/FuncGetArgsToVariadicParamRector.php index d1309fbb8c4..09f136edc5e 100644 --- a/rules/CodingStyle/Rector/ClassMethod/FuncGetArgsToVariadicParamRector.php +++ b/rules/CodingStyle/Rector/ClassMethod/FuncGetArgsToVariadicParamRector.php @@ -96,8 +96,7 @@ public function refactor(Node $node): ?Node private function hasFunctionOrClosureInside( ClassMethod | Function_ | Closure $functionLike, Variable $variable - ): bool - { + ): bool { if ($functionLike->stmts === null) { return false; }