Skip to content

Commit 59f47ad

Browse files
committed
Add support for final properties
1 parent 534c343 commit 59f47ad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1579
-38
lines changed

Zend/tests/errmsg_038.phpt

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--TEST--
2+
Test that ArrayAccess works for final properties as expected
3+
--FILE--
4+
<?php
5+
6+
class Foo implements ArrayAccess
7+
{
8+
final private string $property1;
9+
final private string $property2 = "";
10+
11+
function offsetExists($offset)
12+
{
13+
return isset($this->$offset);
14+
}
15+
16+
function offsetGet($offset)
17+
{
18+
return $this->$offset ?? null;
19+
}
20+
21+
function offsetSet($offset, $value)
22+
{
23+
$this->$offset = $value;
24+
}
25+
26+
function offsetUnset($offset){
27+
unset($this->$offset);
28+
}
29+
}
30+
31+
$foo = new Foo();
32+
33+
$foo["property1"] = "foo";
34+
35+
try {
36+
$foo["property1"] = "foo";
37+
} catch (Error $exception) {
38+
echo $exception->getMessage() . "\n";
39+
}
40+
41+
try {
42+
$foo["property2"] = "foo";
43+
} catch (Error $exception) {
44+
echo $exception->getMessage() . "\n";
45+
}
46+
47+
$foo["property3"] = "foo";
48+
49+
?>
50+
--EXPECT--
51+
Cannot modify final property Foo::$property1 after initialization
52+
Cannot modify final property Foo::$property2 after initialization
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Test that final properties can be used with key() and current(), but not with next()
3+
--XFAIL--
4+
Incorrect error message
5+
--FILE--
6+
<?php
7+
8+
class Foo
9+
{
10+
final public array $property1 = ["foo", "bar", "baz"];
11+
}
12+
13+
$foo = new Foo();
14+
15+
var_dump(current($foo->property1));
16+
var_dump(key($foo->property1));
17+
18+
try {
19+
next($foo->property1);
20+
} catch (Error $exception) {
21+
echo $exception->getMessage() . "\n";
22+
}
23+
24+
?>
25+
--EXPECT--
26+
string(3) "foo"
27+
int(0)
28+
Cannot modify final property Foo::$property1 after initialization
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
--TEST--
2+
Test that declared final properties can't be accessed by reference
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
final public int $property1;
9+
final public int $property2 = 2;
10+
11+
public function __construct()
12+
{
13+
$this->property1 = 1;
14+
}
15+
16+
public function &getProperty2(): int
17+
{
18+
return $this->property2;
19+
}
20+
}
21+
22+
$foo = new Foo();
23+
24+
try {
25+
$x = &$foo->property1;
26+
} catch (Error $exception) {
27+
echo $exception->getMessage() . "\n";
28+
}
29+
30+
try {
31+
$foo->getProperty2();
32+
} catch (Error $exception) {
33+
echo $exception->getMessage() . "\n";
34+
}
35+
36+
?>
37+
--EXPECT--
38+
Cannot acquire reference on final property Foo::$property1
39+
Cannot acquire reference on final property Foo::$property2
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
--TEST--
2+
Test that final properties can't be incremented/decremented
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
final public int $property1;
9+
final public int $property2;
10+
}
11+
12+
$foo = new Foo();
13+
14+
try {
15+
++$foo->property1;
16+
} catch (Error $exception) {
17+
echo $exception->getMessage() . "\n";
18+
}
19+
20+
try {
21+
$foo->property1++;
22+
} catch (Error $exception) {
23+
echo $exception->getMessage() . "\n";
24+
}
25+
26+
$foo->property1 = 1;
27+
$foo->property2 = 3;
28+
29+
try {
30+
++$foo->property1;
31+
} catch (Error $exception) {
32+
echo $exception->getMessage() . "\n";
33+
}
34+
35+
try {
36+
++$foo->property2;
37+
} catch (Error $exception) {
38+
echo $exception->getMessage() . "\n";
39+
}
40+
41+
try {
42+
$foo->property1++;
43+
} catch (Error $exception) {
44+
echo $exception->getMessage() . "\n";
45+
}
46+
47+
try {
48+
$foo->property2++;
49+
} catch (Error $exception) {
50+
echo $exception->getMessage() . "\n";
51+
}
52+
53+
try {
54+
--$foo->property1;
55+
} catch (Error $exception) {
56+
echo $exception->getMessage() . "\n";
57+
}
58+
59+
try {
60+
--$foo->property2;
61+
} catch (Error $exception) {
62+
echo $exception->getMessage() . "\n";
63+
}
64+
65+
try {
66+
$foo->property1--;
67+
} catch (Error $exception) {
68+
echo $exception->getMessage() . "\n";
69+
}
70+
71+
try {
72+
$foo->property2--;
73+
} catch (Error $exception) {
74+
echo $exception->getMessage() . "\n";
75+
}
76+
77+
?>
78+
--EXPECT--
79+
Typed property Foo::$property1 must not be accessed before initialization
80+
Typed property Foo::$property1 must not be accessed before initialization
81+
Cannot increment final property Foo::$property1
82+
Cannot increment final property Foo::$property2
83+
Cannot increment final property Foo::$property1
84+
Cannot increment final property Foo::$property2
85+
Cannot decrement final property Foo::$property1
86+
Cannot decrement final property Foo::$property2
87+
Cannot decrement final property Foo::$property1
88+
Cannot decrement final property Foo::$property2
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
--TEST--
2+
Test that final properties can't be incremented/decremented by reference
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
final public int $property1;
9+
final public int $property2 = 2;
10+
11+
public function __construct()
12+
{
13+
$this->property1 = 1;
14+
}
15+
}
16+
17+
$foo = new Foo();
18+
foreach ($foo as &$property) {
19+
try {
20+
++$property;
21+
} catch (Error $exception) {
22+
echo $exception->getMessage() . "\n";
23+
}
24+
}
25+
26+
var_dump($foo);
27+
28+
$foo = new Foo();
29+
foreach ($foo as &$property) {
30+
try {
31+
$property++;
32+
} catch (Error $exception) {
33+
echo $exception->getMessage() . "\n";
34+
}
35+
}
36+
37+
var_dump($foo);
38+
39+
foreach ($foo as &$property) {
40+
try {
41+
--$property;
42+
} catch (Error $exception) {
43+
echo $exception->getMessage() . "\n";
44+
}
45+
}
46+
47+
var_dump($foo);
48+
49+
foreach ($foo as &$property) {
50+
try {
51+
$property--;
52+
} catch (Error $exception) {
53+
echo $exception->getMessage() . "\n";
54+
}
55+
}
56+
57+
var_dump($foo);
58+
59+
?>
60+
--EXPECTF--
61+
Cannot increment a reference held by final property Foo::$property1
62+
Cannot increment a reference held by final property Foo::$property2
63+
object(Foo)#1 (2) {
64+
["property1"]=>
65+
int(%d)
66+
["property2"]=>
67+
&int(%d)
68+
}
69+
Cannot increment a reference held by final property Foo::$property1
70+
Cannot increment a reference held by final property Foo::$property2
71+
object(Foo)#2 (2) {
72+
["property1"]=>
73+
int(%d)
74+
["property2"]=>
75+
&int(%d)
76+
}
77+
Cannot decrement a reference held by final property Foo::$property1
78+
Cannot decrement a reference held by final property Foo::$property2
79+
object(Foo)#2 (2) {
80+
["property1"]=>
81+
int(-%d)
82+
["property2"]=>
83+
&int(-%d)
84+
}
85+
Cannot decrement a reference held by final property Foo::$property1
86+
Cannot decrement a reference held by final property Foo::$property2
87+
object(Foo)#2 (2) {
88+
["property1"]=>
89+
int(-%d)
90+
["property2"]=>
91+
&int(-%d)
92+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test that final array properties can be iterated
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
final public array $property1 = ["foo", "bar", "baz"];
9+
}
10+
11+
$foo = new Foo();
12+
13+
foreach ($foo->property1 as $key => $value) {
14+
var_dump("$key => $value");
15+
}
16+
17+
?>
18+
--EXPECT--
19+
string(8) "0 => foo"
20+
string(8) "1 => bar"
21+
string(8) "2 => baz"
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
Test that the __get() magic method works when reading from a final property
3+
--FILE--
4+
<?php
5+
6+
class Foo
7+
{
8+
final private array $properties = [
9+
"property1" => "foo",
10+
"property2" => null,
11+
];
12+
13+
public function __isset($name): bool
14+
{
15+
return isset($this->properties[$name]);
16+
}
17+
18+
public function __get($name)
19+
{
20+
return $this->properties[$name] ?? null;
21+
}
22+
}
23+
24+
$foo = new Foo();
25+
26+
var_dump(isset($foo->property1));
27+
var_dump($foo->property1);
28+
29+
var_dump(isset($foo->property2));
30+
var_dump($foo->property2);
31+
32+
var_dump(isset($foo->property3));
33+
var_dump($foo->property3);
34+
35+
?>
36+
--EXPECT--
37+
bool(true)
38+
string(3) "foo"
39+
bool(false)
40+
NULL
41+
bool(false)
42+
NULL

0 commit comments

Comments
 (0)