diff --git a/src/Ast/AST.php b/src/Ast/AST.php index e5bd59331..7dca22b23 100644 --- a/src/Ast/AST.php +++ b/src/Ast/AST.php @@ -428,7 +428,7 @@ public function toCode(): string if ($this->oneLine) { $itemsStr = $items->skipLast(1)->map(fn ($x) => "{$x}, ")->join(); $itemsStr = $itemsStr . "{$items->last()}"; - return "[{$itemsStr}]"; + return "[{$itemsStr}]"; } $itemsStr = $items->map(fn ($x) => "{$x},\n")->join(); $firstNl = count($items) === 0 ? '' : "\n"; @@ -773,10 +773,10 @@ public function toCode(): string /** * Create a '??' expression. - * + * * @param Expression $expr The expression to check \isset and !\is_null, as well as the value to return if true. * @param Expression $false The expresion to return if $expr is not set or is null. - * + * * @return Expression */ public static function nullCoalescing(Expression $expr, Expression $false): Expression @@ -795,6 +795,30 @@ public function toCode(): string }; } + /** + * Create a '??=' (noal-coalescing assignment) expression. + * + * @param AST $to Assign a value to this. + * @param mixed $from Assign from this. + * + * @return Expression + */ + public static function nullCoalescingAssign(AST $to, $from): Expression + { + return new class($to, $from) extends Expression { + public function __construct($to, $from) + { + $this->to = $to; + $this->from = $from; + } + public function toCode(): string + { + return static::toPhp($this->to) . + ' ??= ' . static::toPhp($this->from); + } + }; + } + /** * Create a while statement. This method returns a callable into which the loop code is passed. * diff --git a/tests/Unit/Ast/ASTTest.php b/tests/Unit/Ast/ASTTest.php index e1922ea88..45b15f09e 100644 --- a/tests/Unit/Ast/ASTTest.php +++ b/tests/Unit/Ast/ASTTest.php @@ -85,4 +85,11 @@ public function testAccessSelf(): void $ast = AST::Access(AST::SELF, "\0property2"); $this->assertEquals('self::property2', $ast->toCode()); } + + public function testNullCoalescingAssign(): void + { + $xIndex = AST::index(AST::var('x'), 'foo'); + $ast = AST::nullCoalescingAssign($xIndex, 'bar'); + $this->assertEquals("\$x['foo'] ??= 'bar'", $ast->toCode()); + } }