Implement ReflectionProperty::isFinal()

Closes GH-15919
This commit is contained in:
Ilija Tovilo 2024-09-16 14:50:47 +02:00
parent 1ce07b0957
commit 2fce0bb877
No known key found for this signature in database
GPG Key ID: 5050C66BFCD1015A
6 changed files with 61 additions and 3 deletions

1
NEWS
View File

@ -19,6 +19,7 @@ PHP NEWS
- Reflection:
. Add missing ReflectionProperty::hasHook[s]() methods. (ilutov)
. Add missing ReflectionProperty::isFinal() method. (ilutov)
- SimpleXML:
. Fixed bug GH-15837 (Segmentation fault in ext/simplexml/simplexml.c).

View File

@ -5960,7 +5960,7 @@ ZEND_METHOD(ReflectionProperty, getModifiers)
{
reflection_object *intern;
property_reference *ref;
uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL;
uint32_t keep_flags = ZEND_ACC_PPP_MASK | ZEND_ACC_PPP_SET_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY | ZEND_ACC_ABSTRACT | ZEND_ACC_VIRTUAL | ZEND_ACC_FINAL;
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
@ -6604,6 +6604,11 @@ ZEND_METHOD(ReflectionProperty, getHook)
reflection_method_factory(hook->common.scope, hook, NULL, return_value);
}
ZEND_METHOD(ReflectionProperty, isFinal)
{
_property_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_FINAL);
}
/* {{{ Constructor. Throws an Exception in case the given extension does not exist */
ZEND_METHOD(ReflectionExtension, __construct)
{

View File

@ -470,6 +470,8 @@ class ReflectionProperty implements Reflector
public const int IS_PROTECTED_SET = UNKNOWN;
/** @cvalue ZEND_ACC_PRIVATE_SET */
public const int IS_PRIVATE_SET = UNKNOWN;
/** @cvalue ZEND_ACC_FINAL */
public const int IS_FINAL = UNKNOWN;
public string $name;
public string $class;
@ -565,6 +567,8 @@ class ReflectionProperty implements Reflector
public function hasHook(PropertyHookType $type): bool {}
public function getHook(PropertyHookType $type): ?ReflectionMethod {}
public function isFinal(): bool {}
}
/** @not-serializable */

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 83e9d4a4b2f49739af3e7faa3037df13e779bb8b */
* Stub hash: 261798b92d4eac170538185ced1068bc72705385 */
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
@ -460,6 +460,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionProperty_getHook,
ZEND_ARG_OBJ_INFO(0, type, PropertyHookType, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionProperty_isFinal arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
#define arginfo_class_ReflectionClassConstant___clone arginfo_class_ReflectionFunctionAbstract___clone
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionClassConstant___construct, 0, 0, 2)
@ -868,6 +870,7 @@ ZEND_METHOD(ReflectionProperty, hasHooks);
ZEND_METHOD(ReflectionProperty, getHooks);
ZEND_METHOD(ReflectionProperty, hasHook);
ZEND_METHOD(ReflectionProperty, getHook);
ZEND_METHOD(ReflectionProperty, isFinal);
ZEND_METHOD(ReflectionClassConstant, __construct);
ZEND_METHOD(ReflectionClassConstant, __toString);
ZEND_METHOD(ReflectionClassConstant, getName);
@ -1164,6 +1167,7 @@ static const zend_function_entry class_ReflectionProperty_methods[] = {
ZEND_ME(ReflectionProperty, getHooks, arginfo_class_ReflectionProperty_getHooks, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionProperty, hasHook, arginfo_class_ReflectionProperty_hasHook, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionProperty, getHook, arginfo_class_ReflectionProperty_getHook, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionProperty, isFinal, arginfo_class_ReflectionProperty_isFinal, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@ -1607,6 +1611,12 @@ static zend_class_entry *register_class_ReflectionProperty(zend_class_entry *cla
zend_declare_typed_class_constant(class_entry, const_IS_PRIVATE_SET_name, &const_IS_PRIVATE_SET_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(const_IS_PRIVATE_SET_name);
zval const_IS_FINAL_value;
ZVAL_LONG(&const_IS_FINAL_value, ZEND_ACC_FINAL);
zend_string *const_IS_FINAL_name = zend_string_init_interned("IS_FINAL", sizeof("IS_FINAL") - 1, 1);
zend_declare_typed_class_constant(class_entry, const_IS_FINAL_name, &const_IS_FINAL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(const_IS_FINAL_name);
zval property_name_default_value;
ZVAL_UNDEF(&property_name_default_value);
zend_string *property_name_name = zend_string_init("name", sizeof("name") - 1, 1);

View File

@ -10,6 +10,8 @@ class C {
static public $a4;
static protected $a5;
static private $a6;
public final $a7;
public static final $a8;
}
class D extends C {
@ -21,7 +23,7 @@ class D extends C {
static private $a6;
}
for ($i = 1;$i <= 6;$i++) {
for ($i = 1;$i <= 8;$i++) {
$rp = new ReflectionProperty("C", "a$i");
echo "C::a$i: ";
var_dump($rp->getModifiers());
@ -44,3 +46,7 @@ C::a5: int(18)
D::a5: int(18)
C::a6: int(20)
D::a6: int(20)
C::a7: int(33)
D::a7: int(33)
C::a8: int(49)
D::a8: int(49)

View File

@ -0,0 +1,32 @@
--TEST--
ReflectionProperty::isFinal()
--FILE--
<?php
class C {
public $p1;
public final $p2;
public $p3 { get => 42; }
public final $p4 { get => 42; }
public protected(set) mixed $p5;
public protected(set) final mixed $p6;
public private(set) mixed $p7;
public private(set) final mixed $p8;
}
$rc = new ReflectionClass(C::class);
foreach ($rc->getProperties() as $rp) {
echo $rp->getName(), ": ";
var_dump($rp->isFinal());
}
?>
--EXPECT--
p1: bool(false)
p2: bool(true)
p3: bool(false)
p4: bool(true)
p5: bool(false)
p6: bool(true)
p7: bool(true)
p8: bool(true)