|
13 | 13 | use PhpParser\Node\Expr\FuncCall; |
14 | 14 | use PhpParser\Node\Expr\Isset_; |
15 | 15 | use PhpParser\Node\Expr\Ternary; |
| 16 | +use Rector\NodeTypeResolver\Node\AttributeKey; |
16 | 17 | use Rector\PhpParser\Node\Value\ValueResolver; |
17 | 18 | use Rector\Rector\AbstractRector; |
| 19 | +use Rector\ValueObject\Application\File; |
18 | 20 | use Rector\ValueObject\PhpVersionFeature; |
19 | 21 | use Rector\VersionBonding\Contract\MinPhpVersionInterface; |
20 | 22 | use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; |
@@ -162,9 +164,43 @@ private function processTernaryWithIsset(Ternary $ternary, Isset_ $isset): ?Coal |
162 | 164 | return null; |
163 | 165 | } |
164 | 166 |
|
| 167 | + if ($ternary->else instanceof Ternary && $this->isTernaryParenthesized($this->file, $ternary->cond, $ternary)) { |
| 168 | + $ternary->else->setAttribute(AttributeKey::WRAPPED_IN_PARENTHESES, true); |
| 169 | + } |
| 170 | + |
165 | 171 | return new Coalesce($ternary->if, $ternary->else); |
166 | 172 | } |
167 | 173 |
|
| 174 | + private function isTernaryParenthesized(File $file, Expr $expr, Ternary $ternary): bool |
| 175 | + { |
| 176 | + $oldTokens = $file->getOldTokens(); |
| 177 | + $endTokenPost = $ternary->getEndTokenPos(); |
| 178 | + |
| 179 | + if (isset($oldTokens[$endTokenPost]) && (string) $oldTokens[$endTokenPost] === ')') { |
| 180 | + $startTokenPos = $ternary->else->getStartTokenPos(); |
| 181 | + $previousEndTokenPost = $expr->getEndTokenPos(); |
| 182 | + |
| 183 | + while ($startTokenPos > $previousEndTokenPost) { |
| 184 | + --$startTokenPos; |
| 185 | + |
| 186 | + if (! isset($oldTokens[$startTokenPos])) { |
| 187 | + return false; |
| 188 | + } |
| 189 | + |
| 190 | + // handle space before open parentheses |
| 191 | + if (trim((string) $oldTokens[$startTokenPos]) === '') { |
| 192 | + continue; |
| 193 | + } |
| 194 | + |
| 195 | + return (string) $oldTokens[$startTokenPos] === '('; |
| 196 | + } |
| 197 | + |
| 198 | + return false; |
| 199 | + } |
| 200 | + |
| 201 | + return false; |
| 202 | + } |
| 203 | + |
168 | 204 | private function isNullMatch(Expr $possibleNullExpr, Expr $firstNode, Expr $secondNode): bool |
169 | 205 | { |
170 | 206 | if (! $this->valueResolver->isNull($possibleNullExpr)) { |
|
0 commit comments