Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4dfba7a

Browse files
[RFC] Final Property Promotion
https://wiki.php.net/rfc/final_promotion
1 parent 01c3001 commit 4dfba7a

11 files changed

+131
-8
lines changed

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ PHP NEWS
5656
. Properly handle __debugInfo() returning an array reference. (nielsdos)
5757
. Properly handle reference return value from __toString(). (nielsdos)
5858
. Added the pipe (|>) operator. (crell)
59+
. Added support for `final` with constructor property promotion.
60+
(DanielEScherzer)
5961

6062
- Curl:
6163
. Added curl_multi_get_handles(). (timwolla)

‎UPGRADING‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ PHP 8.5 UPGRADE NOTES
146146
RFC: https://wiki.php.net/rfc/attributes-on-constants
147147
. Added the pipe (|>) operator.
148148
RFC: https://wiki.php.net/rfc/pipe-operator-v3
149+
. Constructor property promotion can now be used for final properties.
150+
RFC: https://wiki.php.net/rfc/final_promotion
149151

150152
- Curl:
151153
. Added support for share handles that are persisted across multiple PHP
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Promoted property may be marked final (hook)
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function __construct(
8+
public final $prop { get {} set {} }
9+
) {}
10+
}
11+
12+
class B extends A {
13+
public $prop { get {} set {} }
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Cannot override final property A::$prop 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+
Promoted property may be marked final (normal)
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function __construct(
8+
public final $prop
9+
) {}
10+
}
11+
12+
class B extends A {
13+
public $prop { get {} set {} }
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Cannot override final property A::$prop 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+
Promoted property may be marked final (no visibility needed)
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function __construct(
8+
final $prop
9+
) {}
10+
}
11+
12+
class B extends A {
13+
public $prop { get {} set {} }
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Cannot override final property A::$prop 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+
Final promoted property conflicts with non-promoted non-hooked property
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function __construct(
8+
final $prop
9+
) {}
10+
}
11+
12+
class B extends A {
13+
public $prop;
14+
}
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Cannot override final property A::$prop in %s on line %d
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
Non-promoted constructor parameter does not conflict with final promoted property
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function __construct(
8+
final $prop
9+
) {
10+
echo __METHOD__ . "(): $prop\n";
11+
}
12+
}
13+
14+
class B extends A {
15+
public function __construct(
16+
$prop
17+
) {
18+
echo __METHOD__ . "(): $prop\n";
19+
parent::__construct($prop);
20+
}
21+
}
22+
23+
$b = new B("test");
24+
25+
?>
26+
--EXPECT--
27+
B::__construct(): test
28+
A::__construct(): test
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Confirm that the AST indicates final promoted properties
3+
--FILE--
4+
<?php
5+
try {
6+
assert(false && new class {
7+
public function __construct(public final $prop) {}
8+
});
9+
} catch (Error $e) {
10+
echo $e->getMessage(), "\n";
11+
}
12+
?>
13+
--EXPECT--
14+
assert(false && new class {
15+
public function __construct(public final $prop) {
16+
}
17+
18+
})

‎Zend/zend_ast.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2795,6 +2795,9 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
27952795
zend_ast_export_attributes(str, ast->child[3], indent, 0);
27962796
}
27972797
zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP);
2798+
if (ast->attr & ZEND_ACC_FINAL) {
2799+
smart_str_appends(str, "final ");
2800+
}
27982801
if (ast->child[0]) {
27992802
zend_ast_export_type(str, ast->child[0], indent);
28002803
smart_str_appendc(str, ' ');

‎Zend/zend_compile.c‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -903,13 +903,7 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token
903903
}
904904
break;
905905
case T_FINAL:
906-
if (target == ZEND_MODIFIER_TARGET_METHOD
907-
|| target == ZEND_MODIFIER_TARGET_CONSTANT
908-
|| target == ZEND_MODIFIER_TARGET_PROPERTY
909-
|| target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK) {
910-
return ZEND_ACC_FINAL;
911-
}
912-
break;
906+
return ZEND_ACC_FINAL;
913907
case T_STATIC:
914908
if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_METHOD) {
915909
return ZEND_ACC_STATIC;
@@ -7681,7 +7675,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
76817675
zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast));
76827676
bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0;
76837677
bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0;
7684-
uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY);
7678+
uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY | ZEND_ACC_FINAL);
76857679
bool is_promoted = property_flags || hooks_ast;
76867680

76877681
znode var_node, default_node;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /