From b2e46e49b8201a4f3e62aa4057f9da05c6031bff Mon Sep 17 00:00:00 2001 From: SpacePossum Date: Tue, 19 Jul 2022 13:31:33 +0200 Subject: [PATCH] NoUnneededControlParenthesesFixer - Fix some curly close cases --- .../NoAlternativeSyntaxFixer.php | 2 +- .../NoUnneededControlParenthesesFixer.php | 37 +++++- tests/AutoReview/FixerFactoryTest.php | 1 + .../NoUnneededControlParenthesesFixerTest.php | 118 +++++++++++++++++- ...yntax,no_unneeded_control_parentheses.test | 11 ++ 5 files changed, 160 insertions(+), 9 deletions(-) create mode 100644 tests/Fixtures/Integration/priority/no_alternative_syntax,no_unneeded_control_parentheses.test diff --git a/src/Fixer/ControlStructure/NoAlternativeSyntaxFixer.php b/src/Fixer/ControlStructure/NoAlternativeSyntaxFixer.php index b863638af81..0c74585a6de 100644 --- a/src/Fixer/ControlStructure/NoAlternativeSyntaxFixer.php +++ b/src/Fixer/ControlStructure/NoAlternativeSyntaxFixer.php @@ -60,7 +60,7 @@ public function isCandidate(Tokens $tokens): bool /** * {@inheritdoc} * - * Must run before BracesFixer, ElseifFixer, NoSuperfluousElseifFixer, NoUselessElseFixer, SwitchContinueToBreakFixer. + * Must run before BracesFixer, ElseifFixer, NoSuperfluousElseifFixer, NoUnneededControlParenthesesFixer, NoUselessElseFixer, SwitchContinueToBreakFixer. */ public function getPriority(): int { diff --git a/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php b/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php index f1001a37d9b..d836b882782 100644 --- a/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php +++ b/src/Fixer/ControlStructure/NoUnneededControlParenthesesFixer.php @@ -52,7 +52,6 @@ final class NoUnneededControlParenthesesFixer extends AbstractFixer implements C private const BEFORE_TYPES = [ ';', '{', - '}', [T_OPEN_TAG], [T_OPEN_TAG_WITH_ECHO], [T_ECHO], @@ -163,6 +162,7 @@ public function getDefinition(): FixerDefinitionInterface * {@inheritdoc} * * Must run before ConcatSpaceFixer, NoTrailingWhitespaceFixer. + * Must run after NoAlternativeSyntaxFixer. */ public function getPriority(): int { @@ -408,7 +408,12 @@ private function isWrappedPartOfOperation(Tokens $tokens, int $beforeOpenIndex, return true; } - $beforeIsStatementOpen = $beforeToken->equalsAny(self::BEFORE_TYPES) || $beforeToken->isGivenKind(T_CASE); + if ($tokens[$beforeOpenIndex]->equals('}')) { + $beforeIsStatementOpen = !$this->closeCurlyBelongsToDynamicElement($tokens, $beforeOpenIndex); + } else { + $beforeIsStatementOpen = $beforeToken->equalsAny(self::BEFORE_TYPES) || $beforeToken->isGivenKind(T_CASE); + } + $afterIsStatementEnd = $afterToken->equalsAny([';', [T_CLOSE_TAG]]); return @@ -436,7 +441,15 @@ private function isSingleStatement(Tokens $tokens, int $beforeOpenIndex, int $af return $tokens[$afterCloseIndex]->equalsAny([':', ';']); // `switch case` } - return $tokens[$afterCloseIndex]->equalsAny([';', [T_CLOSE_TAG]]) && $tokens[$beforeOpenIndex]->equalsAny(self::BEFORE_TYPES); + if (!$tokens[$afterCloseIndex]->equalsAny([';', [T_CLOSE_TAG]])) { + return false; + } + + if ($tokens[$beforeOpenIndex]->equals('}')) { + return !$this->closeCurlyBelongsToDynamicElement($tokens, $beforeOpenIndex); + } + + return $tokens[$beforeOpenIndex]->equalsAny(self::BEFORE_TYPES); } private function isSimpleAssignment(Tokens $tokens, int $beforeOpenIndex, int $afterCloseIndex): bool @@ -716,4 +729,22 @@ private function removeBrace(Tokens $tokens, int $index, bool $needsSpace): void $tokens->clearTokenAndMergeSurroundingWhitespace($index); } } + + private function closeCurlyBelongsToDynamicElement(Tokens $tokens, int $beforeOpenIndex): bool + { + $index = $tokens->findBlockStart(Tokens::BLOCK_TYPE_CURLY_BRACE, $beforeOpenIndex); + $index = $tokens->getPrevMeaningfulToken($index); + + if ($tokens[$index]->isGivenKind(T_DOUBLE_COLON)) { + return true; + } + + if ($tokens[$index]->equals(':')) { + $index = $tokens->getPrevTokenOfKind($index, [[T_CASE], '?']); + + return !$tokens[$index]->isGivenKind(T_CASE); + } + + return false; + } } diff --git a/tests/AutoReview/FixerFactoryTest.php b/tests/AutoReview/FixerFactoryTest.php index 2ae91f90bd6..7ec02bcbaa3 100644 --- a/tests/AutoReview/FixerFactoryTest.php +++ b/tests/AutoReview/FixerFactoryTest.php @@ -517,6 +517,7 @@ private static function getFixersPriorityGraph(): array 'braces', 'elseif', 'no_superfluous_elseif', + 'no_unneeded_control_parentheses', 'no_useless_else', 'switch_continue_to_break', ], diff --git a/tests/Fixer/ControlStructure/NoUnneededControlParenthesesFixerTest.php b/tests/Fixer/ControlStructure/NoUnneededControlParenthesesFixerTest.php index 774e0144fe7..0aeb1037c52 100644 --- a/tests/Fixer/ControlStructure/NoUnneededControlParenthesesFixerTest.php +++ b/tests/Fixer/ControlStructure/NoUnneededControlParenthesesFixerTest.php @@ -913,15 +913,15 @@ function foo() { ' [ + yield 'inside `{` and `}`' => [ ' [ + ' [ ' [ + ' [ + ' [ + ' [ + ' (new F()); ', ]; + + yield [ + '