Skip to content

Commit 9a7a394

Browse files
committed
Add support for property initialization during cloning
1 parent 7edf034 commit 9a7a394

23 files changed

+1733
-611
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Test that the property initializer list is required when "with" is given
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public function withProperties()
9+
{
10+
return clone $this with;
11+
}
12+
}
13+
14+
?>
15+
--EXPECTF--
16+
Parse error: syntax error, unexpected token ";", expecting "{" in %s on line %d
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Test that the property initializer list cannot contain integer keys
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public function withProperties()
9+
{
10+
return clone $this with {1: "value"};
11+
}
12+
}
13+
14+
?>
15+
--EXPECTF--
16+
Parse error: syntax error, unexpected integer "1" in %s on line %d
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Test that the property initializer list can only contain literals
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public function withProperties()
9+
{
10+
$property = "string";
11+
12+
return clone $this with {$property: "value"};
13+
}
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Parse error: syntax error, unexpected variable "$property" in %s on line %d
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test that the clone property initializer respects visibility
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
private $bar;
9+
}
10+
11+
$foo = new Foo();
12+
13+
try {
14+
$foo = clone $foo with {bar: 1};
15+
} catch (Error $exception) {
16+
echo $exception->getMessage() . "\n";
17+
}
18+
19+
?>
20+
--EXPECT--
21+
Cannot access private property Foo::$bar
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Test that the "clone with" doesn't support expressions as property names
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public $bar;
9+
}
10+
11+
$property = "bar";
12+
13+
$foo = new Foo();
14+
$foo = clone $foo with {$property: 1};
15+
var_dump($foo);
16+
17+
?>
18+
--EXPECTF--
19+
Parse error: syntax error, unexpected variable "$property" in %s on line %d
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Test that declared properties can be initialized during cloning
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public int $property1;
9+
public string $property2;
10+
11+
public function withProperties()
12+
{
13+
return clone $this with {
14+
property1: 1,
15+
property2: "foo",
16+
};
17+
}
18+
}
19+
20+
$foo = new Foo();
21+
var_dump($foo);
22+
$bar = $foo->withProperties();
23+
var_dump($bar);
24+
25+
?>
26+
--EXPECT--
27+
object(Foo)#1 (0) {
28+
["property1"]=>
29+
uninitialized(int)
30+
["property2"]=>
31+
uninitialized(string)
32+
}
33+
object(Foo)#2 (2) {
34+
["property1"]=>
35+
int(1)
36+
["property2"]=>
37+
string(3) "foo"
38+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
Test that dynamic properties can be initialized during cloning
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public function withProperties()
9+
{
10+
return clone $this with {
11+
property1: 1,
12+
property2: "foo",
13+
};
14+
}
15+
}
16+
17+
$foo = new Foo();
18+
var_dump($foo);
19+
$bar = $foo->withProperties();
20+
var_dump($bar);
21+
22+
?>
23+
--EXPECT--
24+
object(Foo)#1 (0) {
25+
}
26+
object(Foo)#2 (2) {
27+
["property1"]=>
28+
int(1)
29+
["property2"]=>
30+
string(3) "foo"
31+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
Test that the property initializer list can be empty
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public function withProperties()
9+
{
10+
return clone $this with {};
11+
}
12+
}
13+
14+
$foo = new Foo();
15+
var_dump($foo);
16+
$bar = $foo->withProperties();
17+
var_dump($bar);
18+
19+
?>
20+
--EXPECT--
21+
object(Foo)#1 (0) {
22+
}
23+
object(Foo)#2 (0) {
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Test that the "clone with" is still chainable
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
public $bar = 1;
9+
10+
public function withProperties()
11+
{
12+
return (clone $this with {})->bar;
13+
}
14+
}
15+
16+
$foo = new Foo();
17+
var_dump($foo);
18+
$bar = $foo->withProperties();
19+
var_dump($bar);
20+
21+
?>
22+
--EXPECT--
23+
object(Foo)#1 (1) {
24+
["bar"]=>
25+
int(1)
26+
}
27+
int(1)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test that the "clone with" works with dynamic properties
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
}
9+
10+
$foo = new Foo();
11+
$foo = clone $foo with {bar: 1, baz: ""};
12+
var_dump($foo);
13+
14+
?>
15+
--EXPECT--
16+
object(Foo)#2 (2) {
17+
["bar"]=>
18+
int(1)
19+
["baz"]=>
20+
string(0) ""
21+
}

0 commit comments

Comments
 (0)