summaryrefslogtreecommitdiff
path: root/ext/reflection
diff options
context:
space:
mode:
Diffstat (limited to 'ext/reflection')
-rw-r--r--ext/reflection/php_reflection.c255
-rw-r--r--ext/reflection/php_reflection.h3
-rw-r--r--ext/reflection/php_reflection.stub.php37
-rw-r--r--ext/reflection/php_reflection_arginfo.h118
-rw-r--r--ext/reflection/tests/ReflectionClassConstant_isEnumCase.phpt23
-rw-r--r--ext/reflection/tests/ReflectionClass_isEnum.phpt20
-rw-r--r--ext/reflection/tests/ReflectionClass_toString_001.phpt9
-rw-r--r--ext/reflection/tests/ReflectionEnumBackedCase_getBackingValue.phpt38
-rw-r--r--ext/reflection/tests/ReflectionEnumUnitCase_construct.phpt36
-rw-r--r--ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt39
-rw-r--r--ext/reflection/tests/ReflectionEnumUnitCase_getValue.phpt30
-rw-r--r--ext/reflection/tests/ReflectionEnum_construct.phpt34
-rw-r--r--ext/reflection/tests/ReflectionEnum_getBackingType.phpt20
-rw-r--r--ext/reflection/tests/ReflectionEnum_getCase.phpt50
-rw-r--r--ext/reflection/tests/ReflectionEnum_getCases.phpt54
-rw-r--r--ext/reflection/tests/ReflectionEnum_hasCase.phpt20
-rw-r--r--ext/reflection/tests/ReflectionEnum_isBacked.phpt20
-rw-r--r--ext/reflection/tests/ReflectionEnum_toString.phpt39
-rw-r--r--ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt17
-rw-r--r--ext/reflection/tests/ReflectionProperty_setValue_readonly.phpt23
-rw-r--r--ext/reflection/tests/bug36337.phpt4
21 files changed, 876 insertions, 13 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 83d165beb2..280b3fc06c 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -43,6 +43,7 @@
#include "zend_extensions.h"
#include "zend_builtin_functions.h"
#include "zend_smart_str.h"
+#include "zend_enum.h"
#include "php_reflection_arginfo.h"
/* Key used to avoid leaking addresses in ReflectionProperty::getId() */
@@ -87,6 +88,9 @@ PHPAPI zend_class_entry *reflection_extension_ptr;
PHPAPI zend_class_entry *reflection_zend_extension_ptr;
PHPAPI zend_class_entry *reflection_reference_ptr;
PHPAPI zend_class_entry *reflection_attribute_ptr;
+PHPAPI zend_class_entry *reflection_enum_ptr;
+PHPAPI zend_class_entry *reflection_enum_unit_case_ptr;
+PHPAPI zend_class_entry *reflection_enum_backed_case_ptr;
/* Exception throwing macro */
#define _DO_THROW(msg) \
@@ -573,6 +577,9 @@ static void _class_const_string(smart_str *str, char *name, zend_class_constant
if (Z_TYPE(c->value) == IS_ARRAY) {
smart_str_append_printf(str, "%sConstant [ %s %s %s ] { Array }\n",
indent, visibility, type, name);
+ } else if (Z_TYPE(c->value) == IS_OBJECT) {
+ smart_str_append_printf(str, "%sConstant [ %s %s %s ] { Object }\n",
+ indent, visibility, type, name);
} else {
zend_string *tmp_value_str;
zend_string *value_str = zval_get_tmp_string(&c->value, &tmp_value_str);
@@ -1251,6 +1258,18 @@ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object)
}
/* }}} */
+static void zend_reflection_enum_factory(zend_class_entry *ce, zval *object)
+{
+ reflection_object *intern;
+
+ reflection_instantiate(reflection_enum_ptr, object);
+ intern = Z_REFLECTION_P(object);
+ intern->ptr = ce;
+ intern->ref_type = REF_TYPE_OTHER;
+ intern->ce = ce;
+ ZVAL_STR_COPY(reflection_prop_name(object), ce->name);
+}
+
/* {{{ reflection_extension_factory */
static void reflection_extension_factory(zval *object, const char *name_str)
{
@@ -1430,6 +1449,24 @@ static void reflection_class_constant_factory(zend_string *name_str, zend_class_
}
/* }}} */
+static void reflection_enum_case_factory(zend_class_entry *ce, zend_string *name_str, zend_class_constant *constant, zval *object)
+{
+ reflection_object *intern;
+
+ zend_class_entry *case_reflection_class = ce->backed_enum_table == IS_UNDEF
+ ? reflection_enum_unit_case_ptr
+ : reflection_enum_backed_case_ptr;
+ reflection_instantiate(case_reflection_class, object);
+ intern = Z_REFLECTION_P(object);
+ intern->ptr = constant;
+ intern->ref_type = REF_TYPE_CLASS_CONSTANT;
+ intern->ce = constant->ce;
+ intern->ignore_visibility = 0;
+
+ ZVAL_STR_COPY(reflection_prop_name(object), name_str);
+ ZVAL_STR_COPY(reflection_prop_class(object), constant->ce->name);
+}
+
static int get_parameter_default(zval *result, parameter_reference *param) {
if (param->fptr->type == ZEND_INTERNAL_FUNCTION) {
if (param->fptr->common.fn_flags & ZEND_ACC_USER_ARG_INFO) {
@@ -3665,10 +3702,10 @@ ZEND_METHOD(ReflectionClassConstant, getValue)
}
GET_REFLECTION_OBJECT_PTR(ref);
- ZVAL_COPY_OR_DUP(return_value, &ref->value);
- if (Z_TYPE_P(return_value) == IS_CONSTANT_AST) {
- zval_update_constant_ex(return_value, ref->ce);
+ if (Z_TYPE(ref->value) == IS_CONSTANT_AST) {
+ zval_update_constant_ex(&ref->value, ref->ce);
}
+ ZVAL_COPY_OR_DUP(return_value, &ref->value);
}
/* }}} */
@@ -3718,6 +3755,16 @@ ZEND_METHOD(ReflectionClassConstant, getAttributes)
}
/* }}} */
+ZEND_METHOD(ReflectionClassConstant, isEnumCase)
+{
+ reflection_object *intern;
+ zend_class_constant *ref;
+
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ RETURN_BOOL(Z_ACCESS_FLAGS(ref->value) & ZEND_CLASS_CONST_IS_CASE);
+}
+
/* {{{ reflection_class_object_ctor */
static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object)
{
@@ -4637,6 +4684,11 @@ ZEND_METHOD(ReflectionClass, isTrait)
}
/* }}} */
+ZEND_METHOD(ReflectionClass, isEnum)
+{
+ _class_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_ENUM);
+}
+
/* {{{ Returns whether this class is final */
ZEND_METHOD(ReflectionClass, isFinal)
{
@@ -6494,6 +6546,194 @@ ZEND_METHOD(ReflectionAttribute, newInstance)
RETURN_COPY_VALUE(&obj);
}
+ZEND_METHOD(ReflectionEnum, __construct)
+{
+ reflection_class_object_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
+ if (EG(exception)) {
+ RETURN_THROWS();
+ }
+
+ reflection_object *intern;
+ zend_class_entry *ce;
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (!(ce->ce_flags & ZEND_ACC_ENUM)) {
+ zend_throw_exception_ex(reflection_exception_ptr, -1, "Class \"%s\" is not an enum", ZSTR_VAL(ce->name));
+ RETURN_THROWS();
+ }
+}
+
+ZEND_METHOD(ReflectionEnum, hasCase)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_string *name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ zend_class_constant *class_const = zend_hash_find_ptr(&ce->constants_table, name);
+ if (class_const == NULL) {
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(Z_ACCESS_FLAGS(class_const->value) & ZEND_CLASS_CONST_IS_CASE);
+}
+
+ZEND_METHOD(ReflectionEnum, getCase)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_string *name;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ zend_class_constant *constant = zend_hash_find_ptr(&ce->constants_table, name);
+ if (constant == NULL) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0, "Case %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name));
+ RETURN_THROWS();
+ }
+ if (!(Z_ACCESS_FLAGS(constant->value) & ZEND_CLASS_CONST_IS_CASE)) {
+ zend_throw_exception_ex(reflection_exception_ptr, 0, "%s::%s is not a case", ZSTR_VAL(ce->name), ZSTR_VAL(name));
+ RETURN_THROWS();
+ }
+
+ reflection_enum_case_factory(ce, name, constant, return_value);
+}
+
+ZEND_METHOD(ReflectionEnum, getCases)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+ zend_string *name;
+ zend_class_constant *constant;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ array_init(return_value);
+ ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, name, constant) {
+ if (Z_ACCESS_FLAGS(constant->value) & ZEND_CLASS_CONST_IS_CASE) {
+ zval class_const;
+ reflection_enum_case_factory(ce, name, constant, &class_const);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &class_const);
+ }
+ } ZEND_HASH_FOREACH_END();
+}
+
+ZEND_METHOD(ReflectionEnum, isBacked)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+ RETURN_BOOL(ce->enum_backing_type != IS_UNDEF);
+}
+
+ZEND_METHOD(ReflectionEnum, getBackingType)
+{
+ reflection_object *intern;
+ zend_class_entry *ce;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ GET_REFLECTION_OBJECT_PTR(ce);
+
+ if (ce->enum_backing_type == IS_UNDEF) {
+ RETURN_NULL();
+ } else {
+ zend_type type = ZEND_TYPE_INIT_CODE(ce->enum_backing_type, 0, 0);
+ reflection_type_factory(type, return_value, 0);
+ }
+}
+
+ZEND_METHOD(ReflectionEnumUnitCase, __construct)
+{
+ ZEND_MN(ReflectionClassConstant___construct)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (EG(exception)) {
+ RETURN_THROWS();
+ }
+
+ reflection_object *intern;
+ zend_class_constant *ref;
+
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ if (!(Z_ACCESS_FLAGS(ref->value) & ZEND_CLASS_CONST_IS_CASE)) {
+ zval *case_name = reflection_prop_name(ZEND_THIS);
+ zend_throw_exception_ex(reflection_exception_ptr, 0, "Constant %s::%s is not a case", ZSTR_VAL(ref->ce->name), Z_STRVAL_P(case_name));
+ RETURN_THROWS();
+ }
+}
+
+ZEND_METHOD(ReflectionEnumUnitCase, getEnum)
+{
+ reflection_object *intern;
+ zend_class_constant *ref;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ zend_reflection_enum_factory(ref->ce, return_value);
+}
+
+ZEND_METHOD(ReflectionEnumBackedCase, __construct)
+{
+ ZEND_MN(ReflectionEnumUnitCase___construct)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (EG(exception)) {
+ RETURN_THROWS();
+ }
+
+ reflection_object *intern;
+ zend_class_constant *ref;
+
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ if (ref->ce->enum_backing_type == IS_UNDEF) {
+ zval *case_name = reflection_prop_name(ZEND_THIS);
+ zend_throw_exception_ex(reflection_exception_ptr, 0, "Enum case %s::%s is not a backed case", ZSTR_VAL(ref->ce->name), Z_STRVAL_P(case_name));
+ RETURN_THROWS();
+ }
+}
+
+ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue)
+{
+ reflection_object *intern;
+ zend_class_constant *ref;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+ GET_REFLECTION_OBJECT_PTR(ref);
+
+ if (Z_TYPE(ref->value) == IS_CONSTANT_AST) {
+ zval_update_constant_ex(&ref->value, ref->ce);
+ }
+
+ ZEND_ASSERT(intern->ce->enum_backing_type != IS_UNDEF);
+ zval *member_p = zend_enum_fetch_case_value(Z_OBJ(ref->value));
+
+ ZVAL_COPY_OR_DUP(return_value, member_p);
+}
+
/* {{{ _reflection_write_property */
static zval *_reflection_write_property(zend_object *object, zend_string *name, zval *value, void **cache_slot)
{
@@ -6603,6 +6843,15 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
reflection_attribute_ptr = register_class_ReflectionAttribute();
reflection_init_class_handlers(reflection_attribute_ptr);
+ reflection_enum_ptr = register_class_ReflectionEnum(reflection_class_ptr);
+ reflection_init_class_handlers(reflection_enum_ptr);
+
+ reflection_enum_unit_case_ptr = register_class_ReflectionEnumUnitCase(reflection_class_constant_ptr);
+ reflection_init_class_handlers(reflection_enum_unit_case_ptr);
+
+ reflection_enum_backed_case_ptr = register_class_ReflectionEnumBackedCase(reflection_enum_unit_case_ptr);
+ reflection_init_class_handlers(reflection_enum_backed_case_ptr);
+
REGISTER_REFLECTION_CLASS_CONST_LONG(attribute, "IS_INSTANCEOF", REFLECTION_ATTRIBUTE_IS_INSTANCEOF);
REFLECTION_G(key_initialized) = 0;
diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h
index 654ba55256..de368a86c0 100644
--- a/ext/reflection/php_reflection.h
+++ b/ext/reflection/php_reflection.h
@@ -43,6 +43,9 @@ extern PHPAPI zend_class_entry *reflection_extension_ptr;
extern PHPAPI zend_class_entry *reflection_zend_extension_ptr;
extern PHPAPI zend_class_entry *reflection_reference_ptr;
extern PHPAPI zend_class_entry *reflection_attribute_ptr;
+extern PHPAPI zend_class_entry *reflection_enum_ptr;
+extern PHPAPI zend_class_entry *reflection_enum_unit_case_ptr;
+extern PHPAPI zend_class_entry *reflection_enum_backed_case_ptr;
PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object);
diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php
index 9287ae7e9c..e9815558d6 100644
--- a/ext/reflection/php_reflection.stub.php
+++ b/ext/reflection/php_reflection.stub.php
@@ -298,6 +298,8 @@ class ReflectionClass implements Reflector
/** @return bool */
public function isTrait() {}
+ public function isEnum(): bool {}
+
/** @return bool */
public function isAbstract() {}
@@ -479,6 +481,8 @@ class ReflectionClassConstant implements Reflector
/** @return ReflectionAttribute[] */
public function getAttributes(?string $name = null, int $flags = 0): array {}
+
+ public function isEnumCase(): bool {}
}
class ReflectionParameter implements Reflector
@@ -683,3 +687,36 @@ final class ReflectionAttribute
private function __construct() {}
}
+
+final class ReflectionEnum extends ReflectionClass
+{
+ public function __construct(object|string $objectOrClass) {}
+
+ public function hasCase(string $name): bool {}
+
+ public function getCase(string $name): ReflectionEnumUnitCase {}
+
+ /** @return ReflectionEnumUnitCase[] */
+ public function getCases(): array {}
+
+ public function isBacked(): bool {}
+
+ public function getBackingType(): ReflectionType|null {}
+}
+
+class ReflectionEnumUnitCase extends ReflectionClassConstant
+{
+ public function __construct(object|string $class, string $constant) {}
+
+ public function getEnum(): ReflectionEnum {}
+
+ /** @implementation-alias ReflectionClassConstant::getValue */
+ public function getValue(): UnitEnum {}
+}
+
+final class ReflectionEnumBackedCase extends ReflectionEnumUnitCase
+{
+ public function __construct(object|string $class, string $constant) {}
+
+ public function getBackingValue(): int|string {}
+}
diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h
index a9df516fc2..36e6dc3cec 100644
--- a/ext/reflection/php_reflection_arginfo.h
+++ b/ext/reflection/php_reflection_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
- * Stub hash: fb4e29d088862cc76d22c9902c79c86dbfa7ac95 */
+ * Stub hash: 3594ec0b0c3ed7266223be9c6b426aac56e3aabe */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
@@ -218,6 +218,9 @@ ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionClass_isTrait arginfo_class_ReflectionFunctionAbstract_inNamespace
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_isEnum, 0, 0, _IS_BOOL, 0)
+ZEND_END_ARG_INFO()
+
#define arginfo_class_ReflectionClass_isAbstract arginfo_class_ReflectionFunctionAbstract_inNamespace
#define arginfo_class_ReflectionClass_isFinal arginfo_class_ReflectionFunctionAbstract_inNamespace
@@ -308,8 +311,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionProperty_isDefault arginfo_class_ReflectionFunctionAbstract_inNamespace
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionProperty_isPromoted, 0, 0, _IS_BOOL, 0)
-ZEND_END_ARG_INFO()
+#define arginfo_class_ReflectionProperty_isPromoted arginfo_class_ReflectionClass_isEnum
#define arginfo_class_ReflectionProperty_getModifiers arginfo_class_ReflectionFunctionAbstract_inNamespace
@@ -323,7 +325,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionProperty_hasType arginfo_class_ReflectionFunctionAbstract_inNamespace
-#define arginfo_class_ReflectionProperty_hasDefaultValue arginfo_class_ReflectionProperty_isPromoted
+#define arginfo_class_ReflectionProperty_hasDefaultValue arginfo_class_ReflectionClass_isEnum
#define arginfo_class_ReflectionProperty_getDefaultValue arginfo_class_ReflectionFunctionAbstract_inNamespace
@@ -356,6 +358,8 @@ ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionClassConstant_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes
+#define arginfo_class_ReflectionClassConstant_isEnumCase arginfo_class_ReflectionClass_isEnum
+
#define arginfo_class_ReflectionParameter___clone arginfo_class_ReflectionFunctionAbstract___clone
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionParameter___construct, 0, 0, 2)
@@ -401,7 +405,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionParameter_isVariadic arginfo_class_ReflectionFunctionAbstract_inNamespace
-#define arginfo_class_ReflectionParameter_isPromoted arginfo_class_ReflectionProperty_isPromoted
+#define arginfo_class_ReflectionParameter_isPromoted arginfo_class_ReflectionClass_isEnum
#define arginfo_class_ReflectionParameter_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes
@@ -478,7 +482,7 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionAttribute_getTarget, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO()
-#define arginfo_class_ReflectionAttribute_isRepeated arginfo_class_ReflectionProperty_isPromoted
+#define arginfo_class_ReflectionAttribute_isRepeated arginfo_class_ReflectionClass_isEnum
#define arginfo_class_ReflectionAttribute_getArguments arginfo_class_ReflectionUnionType_getTypes
@@ -489,6 +493,36 @@ ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionAttribute___construct arginfo_class_ReflectionFunctionAbstract_inNamespace
+#define arginfo_class_ReflectionEnum___construct arginfo_class_ReflectionClass___construct
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionEnum_hasCase, 0, 1, _IS_BOOL, 0)
+ ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionEnum_getCase, 0, 1, ReflectionEnumUnitCase, 0)
+ ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_ReflectionEnum_getCases arginfo_class_ReflectionUnionType_getTypes
+
+#define arginfo_class_ReflectionEnum_isBacked arginfo_class_ReflectionClass_isEnum
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionEnum_getBackingType, 0, 0, ReflectionType, 1)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_ReflectionEnumUnitCase___construct arginfo_class_ReflectionClassConstant___construct
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionEnumUnitCase_getEnum, 0, 0, ReflectionEnum, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionEnumUnitCase_getValue, 0, 0, UnitEnum, 0)
+ZEND_END_ARG_INFO()
+
+#define arginfo_class_ReflectionEnumBackedCase___construct arginfo_class_ReflectionClassConstant___construct
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_ReflectionEnumBackedCase_getBackingValue, 0, 0, MAY_BE_LONG|MAY_BE_STRING)
+ZEND_END_ARG_INFO()
+
ZEND_METHOD(Reflection, getModifierNames);
ZEND_METHOD(ReflectionClass, __clone);
@@ -579,6 +613,7 @@ ZEND_METHOD(ReflectionClass, getTraits);
ZEND_METHOD(ReflectionClass, getTraitNames);
ZEND_METHOD(ReflectionClass, getTraitAliases);
ZEND_METHOD(ReflectionClass, isTrait);
+ZEND_METHOD(ReflectionClass, isEnum);
ZEND_METHOD(ReflectionClass, isAbstract);
ZEND_METHOD(ReflectionClass, isFinal);
ZEND_METHOD(ReflectionClass, getModifiers);
@@ -633,6 +668,7 @@ ZEND_METHOD(ReflectionClassConstant, getModifiers);
ZEND_METHOD(ReflectionClassConstant, getDeclaringClass);
ZEND_METHOD(ReflectionClassConstant, getDocComment);
ZEND_METHOD(ReflectionClassConstant, getAttributes);
+ZEND_METHOD(ReflectionClassConstant, isEnumCase);
ZEND_METHOD(ReflectionParameter, __construct);
ZEND_METHOD(ReflectionParameter, __toString);
ZEND_METHOD(ReflectionParameter, getName);
@@ -690,6 +726,16 @@ ZEND_METHOD(ReflectionAttribute, getArguments);
ZEND_METHOD(ReflectionAttribute, newInstance);
ZEND_METHOD(ReflectionAttribute, __clone);
ZEND_METHOD(ReflectionAttribute, __construct);
+ZEND_METHOD(ReflectionEnum, __construct);
+ZEND_METHOD(ReflectionEnum, hasCase);
+ZEND_METHOD(ReflectionEnum, getCase);
+ZEND_METHOD(ReflectionEnum, getCases);
+ZEND_METHOD(ReflectionEnum, isBacked);
+ZEND_METHOD(ReflectionEnum, getBackingType);
+ZEND_METHOD(ReflectionEnumUnitCase, __construct);
+ZEND_METHOD(ReflectionEnumUnitCase, getEnum);
+ZEND_METHOD(ReflectionEnumBackedCase, __construct);
+ZEND_METHOD(ReflectionEnumBackedCase, getBackingValue);
static const zend_function_entry class_ReflectionException_methods[] = {
@@ -818,6 +864,7 @@ static const zend_function_entry class_ReflectionClass_methods[] = {
ZEND_ME(ReflectionClass, getTraitNames, arginfo_class_ReflectionClass_getTraitNames, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClass, getTraitAliases, arginfo_class_ReflectionClass_getTraitAliases, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClass, isTrait, arginfo_class_ReflectionClass_isTrait, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionClass, isEnum, arginfo_class_ReflectionClass_isEnum, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClass, isAbstract, arginfo_class_ReflectionClass_isAbstract, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClass, isFinal, arginfo_class_ReflectionClass_isFinal, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClass, getModifiers, arginfo_class_ReflectionClass_getModifiers, ZEND_ACC_PUBLIC)
@@ -890,6 +937,7 @@ static const zend_function_entry class_ReflectionClassConstant_methods[] = {
ZEND_ME(ReflectionClassConstant, getDeclaringClass, arginfo_class_ReflectionClassConstant_getDeclaringClass, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClassConstant, getDocComment, arginfo_class_ReflectionClassConstant_getDocComment, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionClassConstant, getAttributes, arginfo_class_ReflectionClassConstant_getAttributes, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionClassConstant, isEnumCase, arginfo_class_ReflectionClassConstant_isEnumCase, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
@@ -995,6 +1043,32 @@ static const zend_function_entry class_ReflectionAttribute_methods[] = {
ZEND_FE_END
};
+
+static const zend_function_entry class_ReflectionEnum_methods[] = {
+ ZEND_ME(ReflectionEnum, __construct, arginfo_class_ReflectionEnum___construct, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnum, hasCase, arginfo_class_ReflectionEnum_hasCase, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnum, getCase, arginfo_class_ReflectionEnum_getCase, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnum, getCases, arginfo_class_ReflectionEnum_getCases, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnum, isBacked, arginfo_class_ReflectionEnum_isBacked, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnum, getBackingType, arginfo_class_ReflectionEnum_getBackingType, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+
+static const zend_function_entry class_ReflectionEnumUnitCase_methods[] = {
+ ZEND_ME(ReflectionEnumUnitCase, __construct, arginfo_class_ReflectionEnumUnitCase___construct, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnumUnitCase, getEnum, arginfo_class_ReflectionEnumUnitCase_getEnum, ZEND_ACC_PUBLIC)
+ ZEND_MALIAS(ReflectionClassConstant, getValue, getValue, arginfo_class_ReflectionEnumUnitCase_getValue, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+
+static const zend_function_entry class_ReflectionEnumBackedCase_methods[] = {
+ ZEND_ME(ReflectionEnumBackedCase, __construct, arginfo_class_ReflectionEnumBackedCase___construct, ZEND_ACC_PUBLIC)
+ ZEND_ME(ReflectionEnumBackedCase, getBackingValue, arginfo_class_ReflectionEnumBackedCase_getBackingValue, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
static zend_class_entry *register_class_ReflectionException(zend_class_entry *class_entry_Exception)
{
zend_class_entry ce, *class_entry;
@@ -1258,3 +1332,35 @@ static zend_class_entry *register_class_ReflectionAttribute(void)
return class_entry;
}
+
+static zend_class_entry *register_class_ReflectionEnum(zend_class_entry *class_entry_ReflectionClass)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_CLASS_ENTRY(ce, "ReflectionEnum", class_ReflectionEnum_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClass);
+ class_entry->ce_flags |= ZEND_ACC_FINAL;
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_ReflectionEnumUnitCase(zend_class_entry *class_entry_ReflectionClassConstant)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_CLASS_ENTRY(ce, "ReflectionEnumUnitCase", class_ReflectionEnumUnitCase_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionClassConstant);
+
+ return class_entry;
+}
+
+static zend_class_entry *register_class_ReflectionEnumBackedCase(zend_class_entry *class_entry_ReflectionEnumUnitCase)
+{
+ zend_class_entry ce, *class_entry;
+
+ INIT_CLASS_ENTRY(ce, "ReflectionEnumBackedCase", class_ReflectionEnumBackedCase_methods);
+ class_entry = zend_register_internal_class_ex(&ce, class_entry_ReflectionEnumUnitCase);
+ class_entry->ce_flags |= ZEND_ACC_FINAL;
+
+ return class_entry;
+}
diff --git a/ext/reflection/tests/ReflectionClassConstant_isEnumCase.phpt b/ext/reflection/tests/ReflectionClassConstant_isEnumCase.phpt
new file mode 100644
index 0000000000..7125075085
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClassConstant_isEnumCase.phpt
@@ -0,0 +1,23 @@
+--TEST--
+ReflectionClassConstant::isEnumCase()
+--FILE--
+<?php
+
+enum Foo {
+ case Bar;
+ const Baz = self::Bar;
+}
+
+class Qux {
+ const Quux = 0;
+}
+
+var_dump((new ReflectionClassConstant(Foo::class, 'Bar'))->isEnumCase());
+var_dump((new ReflectionClassConstant(Foo::class, 'Baz'))->isEnumCase());
+var_dump((new ReflectionClassConstant(Qux::class, 'Quux'))->isEnumCase());
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionClass_isEnum.phpt b/ext/reflection/tests/ReflectionClass_isEnum.phpt
new file mode 100644
index 0000000000..b781c61509
--- /dev/null
+++ b/ext/reflection/tests/ReflectionClass_isEnum.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Testing ReflectionClass::isEnum()
+--FILE--
+<?php
+
+class Foo {}
+enum Bar {
+ case Baz;
+}
+
+$fooReflection = new ReflectionClass(Foo::class);
+$barReflection = new ReflectionClass(Bar::class);
+
+var_dump($fooReflection->isEnum());
+var_dump($barReflection->isEnum());
+
+?>
+--EXPECT--
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt
index e218e8b470..e8baf72689 100644
--- a/ext/reflection/tests/ReflectionClass_toString_001.phpt
+++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt
@@ -27,7 +27,7 @@ Class [ <internal:Reflection> class ReflectionClass implements Reflector, String
Property [ public string $name ]
}
- - Methods [54] {
+ - Methods [55] {
Method [ <internal:Reflection> final private method __clone ] {
- Parameters [0] {
@@ -234,6 +234,13 @@ Class [ <internal:Reflection> class ReflectionClass implements Reflector, String
}
}
+ Method [ <internal:Reflection> public method isEnum ] {
+
+ - Parameters [0] {
+ }
+ - Return [ bool ]
+ }
+
Method [ <internal:Reflection> public method isAbstract ] {
- Parameters [0] {
diff --git a/ext/reflection/tests/ReflectionEnumBackedCase_getBackingValue.phpt b/ext/reflection/tests/ReflectionEnumBackedCase_getBackingValue.phpt
new file mode 100644
index 0000000000..f81241d73a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnumBackedCase_getBackingValue.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ReflectionEnumBackedCase::getBackingValue()
+--FILE--
+<?php
+
+enum Enum_ {
+ case Foo;
+}
+
+enum IntEnum: int {
+ case Foo = 0;
+}
+
+enum StringEnum: string {
+ case Foo = 'Foo';
+}
+
+try {
+ var_dump(new ReflectionEnumBackedCase(Enum_::class, 'Foo'));
+} catch (ReflectionException $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ var_dump(new ReflectionEnumBackedCase([], 'Foo'));
+} catch (Error $e) {
+ echo $e->getMessage() . "\n";
+}
+
+var_dump((new ReflectionEnumBackedCase(IntEnum::class, 'Foo'))->getBackingValue());
+var_dump((new ReflectionEnumBackedCase(StringEnum::class, 'Foo'))->getBackingValue());
+
+?>
+--EXPECT--
+Enum case Enum_::Foo is not a backed case
+ReflectionEnumBackedCase::__construct(): Argument #1 ($class) must be of type object|string, array given
+int(0)
+string(3) "Foo"
diff --git a/ext/reflection/tests/ReflectionEnumUnitCase_construct.phpt b/ext/reflection/tests/ReflectionEnumUnitCase_construct.phpt
new file mode 100644
index 0000000000..de5af5c549
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnumUnitCase_construct.phpt
@@ -0,0 +1,36 @@
+--TEST--
+ReflectionEnumUnitCase::__construct()
+--FILE--
+<?php
+
+enum Foo {
+ case Bar;
+ const Baz = self::Bar;
+}
+
+echo (new ReflectionEnumUnitCase(Foo::class, 'Bar'))->getName() . "\n";
+
+try {
+ new ReflectionEnumUnitCase(Foo::class, 'Baz');
+} catch (\Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ new ReflectionEnumUnitCase(Foo::class, 'Qux');
+} catch (\Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ new ReflectionEnumUnitCase([], 'Foo');
+} catch (Error $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECT--
+Bar
+Constant Foo::Baz is not a case
+Constant Foo::Qux does not exist
+ReflectionEnumUnitCase::__construct(): Argument #1 ($class) must be of type object|string, array given
diff --git a/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt b/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt
new file mode 100644
index 0000000000..3d3bcc227e
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnumUnitCase_getEnum.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionEnumUnitCase::getEnum()
+--FILE--
+<?php
+
+enum Foo {
+ case Bar;
+}
+
+echo (new ReflectionEnumUnitCase(Foo::class, 'Bar'))->getEnum();
+
+?>
+--EXPECTF--
+Class [ <user> final class Foo implements UnitEnum ] {
+ @@ %sReflectionEnumUnitCase_getEnum.php 3-5
+
+ - Constants [1] {
+ Constant [ public Foo Bar ] { Object }
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [1] {
+ Method [ <internal, prototype UnitEnum> static public method cases ] {
+
+ - Parameters [0] {
+ }
+ - Return [ array ]
+ }
+ }
+
+ - Properties [1] {
+ Property [ public string $name ]
+ }
+
+ - Methods [0] {
+ }
+}
diff --git a/ext/reflection/tests/ReflectionEnumUnitCase_getValue.phpt b/ext/reflection/tests/ReflectionEnumUnitCase_getValue.phpt
new file mode 100644
index 0000000000..ec5f22d9f8
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnumUnitCase_getValue.phpt
@@ -0,0 +1,30 @@
+--TEST--
+ReflectionEnumUnitCase::getValue()
+--FILE--
+<?php
+
+enum Foo {
+ case Bar;
+ case Baz;
+}
+
+$barFromReflection = (new ReflectionEnumUnitCase(Foo::class, 'Bar'))->getValue();
+$bazFromReflection = (new ReflectionEnumUnitCase(Foo::class, 'Baz'))->getValue();
+
+var_dump($barFromReflection);
+var_dump($bazFromReflection);
+
+var_dump(Foo::Bar === $barFromReflection);
+var_dump(Foo::Baz === $barFromReflection);
+
+var_dump(Foo::Bar === $bazFromReflection);
+var_dump(Foo::Baz === $bazFromReflection);
+
+?>
+--EXPECT--
+enum(Foo::Bar)
+enum(Foo::Baz)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionEnum_construct.phpt b/ext/reflection/tests/ReflectionEnum_construct.phpt
new file mode 100644
index 0000000000..4b4a039105
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_construct.phpt
@@ -0,0 +1,34 @@
+--TEST--
+ReflectionEnum::__construct()
+--FILE--
+<?php
+
+enum Foo {}
+class Bar {}
+
+echo (new ReflectionEnum(Foo::class))->getName() . "\n";
+
+try {
+ new ReflectionEnum('Bar');
+} catch (\Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ new ReflectionEnum('Baz');
+} catch (\Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+
+try {
+ new ReflectionEnum([]);
+} catch (Error $e) {
+ echo $e->getMessage() . "\n";
+}
+
+?>
+--EXPECT--
+Foo
+Class "Bar" is not an enum
+Class "Baz" does not exist
+ReflectionEnum::__construct(): Argument #1 ($objectOrClass) must be of type object|string, array given
diff --git a/ext/reflection/tests/ReflectionEnum_getBackingType.phpt b/ext/reflection/tests/ReflectionEnum_getBackingType.phpt
new file mode 100644
index 0000000000..e9d429f592
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_getBackingType.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionEnum::getBackingType()
+--FILE--
+<?php
+
+enum Enum_ {}
+enum IntEnum: int {}
+enum StringEnum: string {}
+
+function test(): string {}
+
+var_dump((new ReflectionEnum(Enum_::class))->getBackingType());
+echo (new ReflectionEnum(IntEnum::class))->getBackingType() . "\n";
+echo (new ReflectionEnum(StringEnum::class))->getBackingType() . "\n";
+
+?>
+--EXPECT--
+NULL
+int
+string
diff --git a/ext/reflection/tests/ReflectionEnum_getCase.phpt b/ext/reflection/tests/ReflectionEnum_getCase.phpt
new file mode 100644
index 0000000000..f2b53cf657
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_getCase.phpt
@@ -0,0 +1,50 @@
+--TEST--
+ReflectionEnum::getCases()
+--FILE--
+<?php
+
+enum Enum_ {
+ case Foo;
+ const Bar = self::Foo;
+}
+
+enum IntEnum: int {
+ case Foo = 0;
+ const Bar = self::Foo;
+}
+
+function test(string $enumName, string $caseName) {
+ try {
+ $reflectionEnum = new ReflectionEnum($enumName);
+ var_dump($reflectionEnum->getCase($caseName));
+ } catch (Throwable $e) {
+ echo get_class($e) . ': ' . $e->getMessage() . "\n";
+ }
+}
+
+test(Enum_::class, 'Foo');
+test(Enum_::class, 'Bar');
+test(Enum_::class, 'Baz');
+
+test(IntEnum::class, 'Foo');
+test(IntEnum::class, 'Bar');
+test(IntEnum::class, 'Baz');
+
+?>
+--EXPECT--
+object(ReflectionEnumUnitCase)#2 (2) {
+ ["name"]=>
+ string(3) "Foo"
+ ["class"]=>
+ string(5) "Enum_"
+}
+ReflectionException: Enum_::Bar is not a case
+ReflectionException: Case Enum_::Baz does not exist
+object(ReflectionEnumBackedCase)#2 (2) {
+ ["name"]=>
+ string(3) "Foo"
+ ["class"]=>
+ string(7) "IntEnum"
+}
+ReflectionException: IntEnum::Bar is not a case
+ReflectionException: Case IntEnum::Baz does not exist
diff --git a/ext/reflection/tests/ReflectionEnum_getCases.phpt b/ext/reflection/tests/ReflectionEnum_getCases.phpt
new file mode 100644
index 0000000000..9365008774
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_getCases.phpt
@@ -0,0 +1,54 @@
+--TEST--
+ReflectionEnum::getCases()
+--FILE--
+<?php
+
+enum Enum_ {
+ case Foo;
+ case Bar;
+ const Baz = self::Bar;
+}
+
+enum IntEnum: int {
+ case Foo = 0;
+ case Bar = 1;
+ const Baz = self::Bar;
+}
+
+var_dump((new ReflectionEnum(Enum_::class))->getCases());
+var_dump((new ReflectionEnum(IntEnum::class))->getCases());
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ object(ReflectionEnumUnitCase)#2 (2) {
+ ["name"]=>
+ string(3) "Foo"
+ ["class"]=>
+ string(5) "Enum_"
+ }
+ [1]=>
+ object(ReflectionEnumUnitCase)#3 (2) {
+ ["name"]=>
+ string(3) "Bar"
+ ["class"]=>
+ string(5) "Enum_"
+ }
+}
+array(2) {
+ [0]=>
+ object(ReflectionEnumBackedCase)#2 (2) {
+ ["name"]=>
+ string(3) "Foo"
+ ["class"]=>
+ string(7) "IntEnum"
+ }
+ [1]=>
+ object(ReflectionEnumBackedCase)#1 (2) {
+ ["name"]=>
+ string(3) "Bar"
+ ["class"]=>
+ string(7) "IntEnum"
+ }
+}
diff --git a/ext/reflection/tests/ReflectionEnum_hasCase.phpt b/ext/reflection/tests/ReflectionEnum_hasCase.phpt
new file mode 100644
index 0000000000..3310f0ef6b
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_hasCase.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionEnum::hasCase()
+--FILE--
+<?php
+
+enum Foo {
+ case Bar;
+ const Baz = self::Bar;
+}
+
+$reflectionEnum = new ReflectionEnum(Foo::class);
+var_dump($reflectionEnum->hasCase('Bar'));
+var_dump($reflectionEnum->hasCase('Baz'));
+var_dump($reflectionEnum->hasCase('Qux'));
+
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(false)
diff --git a/ext/reflection/tests/ReflectionEnum_isBacked.phpt b/ext/reflection/tests/ReflectionEnum_isBacked.phpt
new file mode 100644
index 0000000000..cb449e951a
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_isBacked.phpt
@@ -0,0 +1,20 @@
+--TEST--
+ReflectionEnum::isBacked()
+--FILE--
+<?php
+
+enum Enum_ {}
+enum IntEnum: int {}
+enum StringEnum: string {}
+
+function test(): string {}
+
+var_dump((new ReflectionEnum(Enum_::class))->isBacked());
+var_dump((new ReflectionEnum(IntEnum::class))->isBacked());
+var_dump((new ReflectionEnum(StringEnum::class))->isBacked());
+
+?>
+--EXPECT--
+bool(false)
+bool(true)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionEnum_toString.phpt b/ext/reflection/tests/ReflectionEnum_toString.phpt
new file mode 100644
index 0000000000..567191e594
--- /dev/null
+++ b/ext/reflection/tests/ReflectionEnum_toString.phpt
@@ -0,0 +1,39 @@
+--TEST--
+ReflectionEnum::__toString()
+--FILE--
+<?php
+
+enum Foo {
+ case Bar;
+}
+
+echo new ReflectionEnum(Foo::class);
+
+?>
+--EXPECTF--
+Class [ <user> final class Foo implements UnitEnum ] {
+ @@ %sReflectionEnum_toString.php 3-5
+
+ - Constants [1] {
+ Constant [ public Foo Bar ] { Object }
+ }
+
+ - Static properties [0] {
+ }
+
+ - Static methods [1] {
+ Method [ <internal, prototype UnitEnum> static public method cases ] {
+
+ - Parameters [0] {
+ }
+ - Return [ array ]
+ }
+ }
+
+ - Properties [1] {
+ Property [ public string $name ]
+ }
+
+ - Methods [0] {
+ }
+}
diff --git a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt
index 81d3c8d55b..084e05e118 100644
--- a/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt
+++ b/ext/reflection/tests/ReflectionExtension_getClasses_basic.phpt
@@ -8,7 +8,7 @@ $ext = new ReflectionExtension('reflection');
var_dump($ext->getClasses());
?>
--EXPECT--
-array(19) {
+array(22) {
["ReflectionException"]=>
object(ReflectionClass)#2 (1) {
["name"]=>
@@ -104,4 +104,19 @@ array(19) {
["name"]=>
string(19) "ReflectionAttribute"
}
+ ["ReflectionEnum"]=>
+ object(ReflectionClass)#21 (1) {
+ ["name"]=>
+ string(14) "ReflectionEnum"
+ }
+ ["ReflectionEnumUnitCase"]=>
+ object(ReflectionClass)#22 (1) {
+ ["name"]=>
+ string(22) "ReflectionEnumUnitCase"
+ }
+ ["ReflectionEnumBackedCase"]=>
+ object(ReflectionClass)#23 (1) {
+ ["name"]=>
+ string(24) "ReflectionEnumBackedCase"
+ }
}
diff --git a/ext/reflection/tests/ReflectionProperty_setValue_readonly.phpt b/ext/reflection/tests/ReflectionProperty_setValue_readonly.phpt
new file mode 100644
index 0000000000..6efea38913
--- /dev/null
+++ b/ext/reflection/tests/ReflectionProperty_setValue_readonly.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Test ReflectionProperty::setValue() error cases.
+--FILE--
+<?php
+
+enum Foo: int {
+ case Bar = 0;
+}
+
+$reflection = new ReflectionProperty(Foo::class, 'value');
+
+try {
+ $reflection->setValue(Foo::Bar, 1);
+} catch (Error $e) {
+ echo $e->getMessage() . "\n";
+}
+
+var_dump(Foo::Bar->value);
+
+?>
+--EXPECT--
+Enum properties are immutable
+int(0)
diff --git a/ext/reflection/tests/bug36337.phpt b/ext/reflection/tests/bug36337.phpt
index ebe64431a7..d4a155bda9 100644
--- a/ext/reflection/tests/bug36337.phpt
+++ b/ext/reflection/tests/bug36337.phpt
@@ -3,7 +3,7 @@ Reflection Bug #36337 (ReflectionProperty fails to return correct visibility)
--FILE--
<?php
-abstract class enum {
+abstract class enum_ {
protected $_values;
public function __construct() {
@@ -13,7 +13,7 @@ abstract class enum {
}
-final class myEnum extends enum {
+final class myEnum extends enum_ {
public $_values = array(
0 => 'No value',
);