diff --git a/rules-tests/Php80/Rector/Ternary/TernaryToNullsafeCoalesceRector/Fixture/ternary_fallback.php.inc b/rules-tests/Php80/Rector/Ternary/TernaryToNullsafeCoalesceRector/Fixture/ternary_fallback.php.inc new file mode 100644 index 00000000000..bb1c2efa040 --- /dev/null +++ b/rules-tests/Php80/Rector/Ternary/TernaryToNullsafeCoalesceRector/Fixture/ternary_fallback.php.inc @@ -0,0 +1,51 @@ +name : ($flag ? 'first' : 'second'); + } + + public function method(?SomeObject $someObject, bool $flag): string + { + return $someObject !== null ? $someObject->getName() : ($flag ? 'first' : 'second'); + } + + public function identical(?SomeObject $someObject, string $fallback): string + { + return null === $someObject ? ($fallback ?: 'default') : $someObject->name; + } +} + +?> +----- +name ?? ($flag ? 'first' : 'second'); + } + + public function method(?SomeObject $someObject, bool $flag): string + { + return $someObject?->getName() ?? ($flag ? 'first' : 'second'); + } + + public function identical(?SomeObject $someObject, string $fallback): string + { + return $someObject->name ?? ($fallback ?: 'default'); + } +} + +?> diff --git a/src/PhpParser/Printer/BetterStandardPrinter.php b/src/PhpParser/Printer/BetterStandardPrinter.php index 84d1368f8e8..2ab76c16e13 100644 --- a/src/PhpParser/Printer/BetterStandardPrinter.php +++ b/src/PhpParser/Printer/BetterStandardPrinter.php @@ -18,6 +18,7 @@ use PhpParser\Node\Expr\BinaryOp; use PhpParser\Node\Expr\BinaryOp\BooleanAnd; use PhpParser\Node\Expr\BinaryOp\BooleanOr; +use PhpParser\Node\Expr\BinaryOp\Coalesce; use PhpParser\Node\Expr\BinaryOp\Pipe; use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\Instanceof_; @@ -524,6 +525,11 @@ private function wrapBinaryOpWithBrackets(Node $node): void return; } + // A reused ternary needs parentheses in its new, tighter-binding coalesce context. + if ($node instanceof Coalesce && $node->right instanceof Ternary) { + $node->right->setAttribute(AttributeKey::WRAPPED_IN_PARENTHESES, true); + } + if ($node->left instanceof Assign && $this->origTokens instanceof TokenStream && ! $this->origTokens->haveParens($node->left->getStartTokenPos(), $node->left->getEndTokenPos())) {