Skip to content

Commit 0b7c768

Browse files
committed
Fix private(set) not being implicitely marked as final
See https://wiki.php.net/rfc/asymmetric-visibility-v2#inheritance
1 parent e772b3d commit 0b7c768

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

ChangeLog.md

+3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ XP Compiler ChangeLog
33

44
## ?.?.? / ????-??-??
55

6+
* Fixed `private(set)` not being implicitely marked as *final*, see
7+
https://wiki.php.net/rfc/asymmetric-visibility-v2#inheritance
8+
(@thekid)
69
* Fixed enclosing scopes when using references - @thekid
710

811
## 9.3.0 / 2024-08-31

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

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ protected function emitProperty($result, $property) {
5050
} else if ($modifiers & 0x0001000) {
5151
$checks= [$this->private($property->name, 'modify private(set)')];
5252
$modifiers & MODIFIER_PRIVATE && $modifiers&= ~0x0001000;
53+
$modifiers|= MODIFIER_FINAL;
5354
}
5455

5556
// Emit XP meta information for the reflection API

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

+29-5
Original file line numberDiff line numberDiff line change
@@ -100,19 +100,31 @@ public function rename() {
100100
$t->newInstance()->rename();
101101
}
102102

103-
#[Test, Values(['private', 'protected'])]
104-
public function reflection($modifier) {
103+
#[Test]
104+
public function protected_set_reflection() {
105105
$t= $this->declare('class %T {
106-
public '.$modifier.'(set) string $fixture= "Test";
106+
public protected(set) string $fixture= "Test";
107107
}');
108108

109109
Assert::equals(
110-
'public '.$modifier.'(set) string $fixture',
110+
'public protected(set) string $fixture',
111111
$t->property('fixture')->toString()
112112
);
113113
}
114114

115-
#[Test, Values(['private', 'protected', 'public'])]
115+
#[Test]
116+
public function private_set_implicitely_final_in_reflection() {
117+
$t= $this->declare('class %T {
118+
public private(set) string $fixture= "Test";
119+
}');
120+
121+
Assert::equals(
122+
'public final private(set) string $fixture',
123+
$t->property('fixture')->toString()
124+
);
125+
}
126+
127+
#[Test, Values(['protected', 'public'])]
116128
public function same_modifier_for_get_and_set($modifier) {
117129
$t= $this->declare('class %T {
118130
'.$modifier.' '.$modifier.'(set) string $fixture= "Test";
@@ -124,6 +136,18 @@ public function same_modifier_for_get_and_set($modifier) {
124136
);
125137
}
126138

139+
#[Test]
140+
public function private_modifier_for_get_and_set() {
141+
$t= $this->declare('class %T {
142+
private private(set) string $fixture= "Test";
143+
}');
144+
145+
Assert::equals(
146+
'private final string $fixture',
147+
$t->property('fixture')->toString()
148+
);
149+
}
150+
127151
#[Test]
128152
public function interaction_with_hooks() {
129153
$t= $this->declare('class %T {

0 commit comments

Comments
 (0)