Skip to content

Commit 443aefe

Browse files
committed
Support clone with unpacking
1 parent 513a199 commit 443aefe

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

src/main/php/lang/ast/emit/RewriteCloneWith.class.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php namespace lang\ast\emit;
22

3-
use lang\ast\nodes\{Signature, Parameter};
3+
use lang\ast\nodes\{Signature, Parameter, UnpackExpression};
44

55
/** @see https://wiki.php.net/rfc/clone_with_v2 */
66
trait RewriteCloneWith {
@@ -20,6 +20,11 @@ protected function emitClone($result, $clone) {
2020
} else if (isset($clone->arguments['object'])) {
2121
$result->out->write('clone ');
2222
$this->emitOne($result, $expr);
23+
} else if ($expr instanceof UnpackExpression) {
24+
$result->out->write('(function($u) { $c= clone $u["object"] ?? $u[0];');
25+
$result->out->write('foreach ($u["withProperties"] ?? $u[1] ?? [] as $p=>$v) { $c->$p= $v; } return $c;})(');
26+
$this->emitOne($result, $expr->expression);
27+
$result->out->write(')');
2328
} else {
2429
return parent::emitClone($result, $clone);
2530
}

src/test/php/lang/ast/unittest/emit/CloningTest.class.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,18 @@ public function run($in) { return '.$expression.'; }
8686
);
8787
}
8888

89+
#[Test]
90+
public function clone_unpack() {
91+
$clone= $this->run('class %T {
92+
public function run($in) {
93+
$args= ["object" => $in];
94+
return clone(...$args);
95+
}
96+
}', $this->fixture);
97+
98+
Assert::true($clone instanceof $this->fixture && $this->fixture !== $clone);
99+
}
100+
89101
#[Test]
90102
public function clone_with_named_argument() {
91103
$clone= $this->run('class %T {

0 commit comments

Comments
 (0)