mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
[RFC] Final Property Promotion
https://wiki.php.net/rfc/final_promotion
This commit is contained in:
2
NEWS
2
NEWS
@@ -56,6 +56,8 @@ PHP NEWS
|
||||
. Properly handle __debugInfo() returning an array reference. (nielsdos)
|
||||
. Properly handle reference return value from __toString(). (nielsdos)
|
||||
. Added the pipe (|>) operator. (crell)
|
||||
. Added support for `final` with constructor property promotion.
|
||||
(DanielEScherzer)
|
||||
|
||||
- Curl:
|
||||
. Added curl_multi_get_handles(). (timwolla)
|
||||
|
||||
@@ -146,6 +146,8 @@ PHP 8.5 UPGRADE NOTES
|
||||
RFC: https://wiki.php.net/rfc/attributes-on-constants
|
||||
. Added the pipe (|>) operator.
|
||||
RFC: https://wiki.php.net/rfc/pipe-operator-v3
|
||||
. Constructor property promotion can now be used for final properties.
|
||||
RFC: https://wiki.php.net/rfc/final_promotion
|
||||
|
||||
- Curl:
|
||||
. Added support for share handles that are persisted across multiple PHP
|
||||
|
||||
18
Zend/tests/property_hooks/final_prop_promoted_1.phpt
Normal file
18
Zend/tests/property_hooks/final_prop_promoted_1.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Promoted property may be marked final (hook)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public function __construct(
|
||||
public final $prop { get {} set {} }
|
||||
) {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public $prop { get {} set {} }
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot override final property A::$prop in %s on line %d
|
||||
18
Zend/tests/property_hooks/final_prop_promoted_2.phpt
Normal file
18
Zend/tests/property_hooks/final_prop_promoted_2.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Promoted property may be marked final (normal)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public function __construct(
|
||||
public final $prop
|
||||
) {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public $prop { get {} set {} }
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot override final property A::$prop in %s on line %d
|
||||
18
Zend/tests/property_hooks/final_prop_promoted_3.phpt
Normal file
18
Zend/tests/property_hooks/final_prop_promoted_3.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Promoted property may be marked final (no visibility needed)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public function __construct(
|
||||
final $prop
|
||||
) {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public $prop { get {} set {} }
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot override final property A::$prop in %s on line %d
|
||||
18
Zend/tests/property_hooks/final_prop_promoted_4.phpt
Normal file
18
Zend/tests/property_hooks/final_prop_promoted_4.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Final promoted property conflicts with non-promoted non-hooked property
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public function __construct(
|
||||
final $prop
|
||||
) {}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public $prop;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot override final property A::$prop in %s on line %d
|
||||
28
Zend/tests/property_hooks/final_prop_promoted_5.phpt
Normal file
28
Zend/tests/property_hooks/final_prop_promoted_5.phpt
Normal file
@@ -0,0 +1,28 @@
|
||||
--TEST--
|
||||
Non-promoted constructor parameter does not conflict with final promoted property
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class A {
|
||||
public function __construct(
|
||||
final $prop
|
||||
) {
|
||||
echo __METHOD__ . "(): $prop\n";
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
public function __construct(
|
||||
$prop
|
||||
) {
|
||||
echo __METHOD__ . "(): $prop\n";
|
||||
parent::__construct($prop);
|
||||
}
|
||||
}
|
||||
|
||||
$b = new B("test");
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
B::__construct(): test
|
||||
A::__construct(): test
|
||||
18
Zend/tests/property_hooks/final_prop_promoted_ast.phpt
Normal file
18
Zend/tests/property_hooks/final_prop_promoted_ast.phpt
Normal file
@@ -0,0 +1,18 @@
|
||||
--TEST--
|
||||
Confirm that the AST indicates final promoted properties
|
||||
--FILE--
|
||||
<?php
|
||||
try {
|
||||
assert(false && new class {
|
||||
public function __construct(public final $prop) {}
|
||||
});
|
||||
} catch (Error $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
||||
assert(false && new class {
|
||||
public function __construct(public final $prop) {
|
||||
}
|
||||
|
||||
})
|
||||
@@ -2795,6 +2795,9 @@ simple_list:
|
||||
zend_ast_export_attributes(str, ast->child[3], indent, 0);
|
||||
}
|
||||
zend_ast_export_visibility(str, ast->attr, ZEND_MODIFIER_TARGET_CPP);
|
||||
if (ast->attr & ZEND_ACC_FINAL) {
|
||||
smart_str_appends(str, "final ");
|
||||
}
|
||||
if (ast->child[0]) {
|
||||
zend_ast_export_type(str, ast->child[0], indent);
|
||||
smart_str_appendc(str, ' ');
|
||||
|
||||
@@ -903,13 +903,7 @@ uint32_t zend_modifier_token_to_flag(zend_modifier_target target, uint32_t token
|
||||
}
|
||||
break;
|
||||
case T_FINAL:
|
||||
if (target == ZEND_MODIFIER_TARGET_METHOD
|
||||
|| target == ZEND_MODIFIER_TARGET_CONSTANT
|
||||
|| target == ZEND_MODIFIER_TARGET_PROPERTY
|
||||
|| target == ZEND_MODIFIER_TARGET_PROPERTY_HOOK) {
|
||||
return ZEND_ACC_FINAL;
|
||||
}
|
||||
break;
|
||||
return ZEND_ACC_FINAL;
|
||||
case T_STATIC:
|
||||
if (target == ZEND_MODIFIER_TARGET_PROPERTY || target == ZEND_MODIFIER_TARGET_METHOD) {
|
||||
return ZEND_ACC_STATIC;
|
||||
@@ -7681,7 +7675,7 @@ static void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32
|
||||
zend_string *name = zval_make_interned_string(zend_ast_get_zval(var_ast));
|
||||
bool is_ref = (param_ast->attr & ZEND_PARAM_REF) != 0;
|
||||
bool is_variadic = (param_ast->attr & ZEND_PARAM_VARIADIC) != 0;
|
||||
uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY);
|
||||
uint32_t property_flags = param_ast->attr & (ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_READONLY | ZEND_ACC_FINAL);
|
||||
bool is_promoted = property_flags || hooks_ast;
|
||||
|
||||
znode var_node, default_node;
|
||||
|
||||
@@ -12,6 +12,8 @@ class C {
|
||||
public protected(set) final mixed $p6;
|
||||
public private(set) mixed $p7;
|
||||
public private(set) final mixed $p8;
|
||||
|
||||
public function __construct(final $p9, public $p10) {}
|
||||
}
|
||||
|
||||
$rc = new ReflectionClass(C::class);
|
||||
@@ -30,3 +32,5 @@ p5: bool(false)
|
||||
p6: bool(true)
|
||||
p7: bool(true)
|
||||
p8: bool(true)
|
||||
p9: bool(true)
|
||||
p10: bool(false)
|
||||
|
||||
Reference in New Issue
Block a user