mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix #80097: Have ReflectionAttribute implement Reflector and __toString
Implement printing for ReflectionAttribute. Attributes aren't printed as part of reflection output for other structures (classes etc) yet. Closes GH-6117.
This commit is contained in:
parent
ce3846cd87
commit
bc39abe8c3
5 changed files with 90 additions and 5 deletions
3
NEWS
3
NEWS
|
@ -2,7 +2,8 @@ PHP NEWS
|
||||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
?? ??? ????, PHP 8.1.0beta1
|
?? ??? ????, PHP 8.1.0beta1
|
||||||
|
|
||||||
|
- Reflection:
|
||||||
|
. Fixed bug #80097 (ReflectionAttribute is not a Reflector). (beberlei)
|
||||||
|
|
||||||
08 Jul 2021, PHP 8.1.0alpha3
|
08 Jul 2021, PHP 8.1.0alpha3
|
||||||
|
|
||||||
|
|
|
@ -6452,6 +6452,57 @@ ZEND_METHOD(ReflectionAttribute, __clone)
|
||||||
_DO_THROW("Cannot clone object using __clone()");
|
_DO_THROW("Cannot clone object using __clone()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* {{{ Returns a string representation */
|
||||||
|
ZEND_METHOD(ReflectionAttribute, __toString)
|
||||||
|
{
|
||||||
|
reflection_object *intern;
|
||||||
|
attribute_reference *attr;
|
||||||
|
|
||||||
|
if (zend_parse_parameters_none() == FAILURE) {
|
||||||
|
RETURN_THROWS();
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_REFLECTION_OBJECT_PTR(attr);
|
||||||
|
|
||||||
|
smart_str str = {0};
|
||||||
|
smart_str_appends(&str, "Attribute [ ");
|
||||||
|
smart_str_append(&str, attr->data->name);
|
||||||
|
smart_str_appends(&str, " ]");
|
||||||
|
|
||||||
|
if (attr->data->argc > 0) {
|
||||||
|
smart_str_appends(&str, " {\n");
|
||||||
|
smart_str_append_printf(&str, " - Arguments [%d] {\n", attr->data->argc);
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < attr->data->argc; i++) {
|
||||||
|
zval tmp;
|
||||||
|
if (FAILURE == zend_get_attribute_value(&tmp, attr->data, i, attr->scope)) {
|
||||||
|
RETURN_THROWS();
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_str_append_printf(&str, " Argument #%d [ ", i);
|
||||||
|
if (attr->data->args[i].name != NULL) {
|
||||||
|
smart_str_append(&str, attr->data->args[i].name);
|
||||||
|
smart_str_appends(&str, " = ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format_default_value(&str, &tmp, NULL) == FAILURE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
smart_str_appends(&str, " ]\n");
|
||||||
|
zval_ptr_dtor(&tmp);
|
||||||
|
}
|
||||||
|
smart_str_appends(&str, " }\n");
|
||||||
|
|
||||||
|
smart_str_appends(&str, "}\n");
|
||||||
|
} else {
|
||||||
|
smart_str_appendc(&str, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_STR(smart_str_extract(&str));
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ * Returns the name of the attribute */
|
/* {{{ * Returns the name of the attribute */
|
||||||
ZEND_METHOD(ReflectionAttribute, getName)
|
ZEND_METHOD(ReflectionAttribute, getName)
|
||||||
{
|
{
|
||||||
|
@ -7121,7 +7172,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */
|
||||||
reflection_reference_ptr = register_class_ReflectionReference();
|
reflection_reference_ptr = register_class_ReflectionReference();
|
||||||
reflection_init_class_handlers(reflection_reference_ptr);
|
reflection_init_class_handlers(reflection_reference_ptr);
|
||||||
|
|
||||||
reflection_attribute_ptr = register_class_ReflectionAttribute();
|
reflection_attribute_ptr = register_class_ReflectionAttribute(reflector_ptr);
|
||||||
reflection_init_class_handlers(reflection_attribute_ptr);
|
reflection_init_class_handlers(reflection_attribute_ptr);
|
||||||
|
|
||||||
reflection_enum_ptr = register_class_ReflectionEnum(reflection_class_ptr);
|
reflection_enum_ptr = register_class_ReflectionEnum(reflection_class_ptr);
|
||||||
|
|
|
@ -687,7 +687,7 @@ final class ReflectionReference
|
||||||
private function __construct() {}
|
private function __construct() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class ReflectionAttribute
|
final class ReflectionAttribute implements Reflector
|
||||||
{
|
{
|
||||||
public function getName(): string {}
|
public function getName(): string {}
|
||||||
public function getTarget(): int {}
|
public function getTarget(): int {}
|
||||||
|
@ -695,6 +695,8 @@ final class ReflectionAttribute
|
||||||
public function getArguments(): array {}
|
public function getArguments(): array {}
|
||||||
public function newInstance(): object {}
|
public function newInstance(): object {}
|
||||||
|
|
||||||
|
public function __toString(): string {}
|
||||||
|
|
||||||
private function __clone(): void {}
|
private function __clone(): void {}
|
||||||
|
|
||||||
private function __construct() {}
|
private function __construct() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* This is a generated file, edit the .stub.php file instead.
|
/* This is a generated file, edit the .stub.php file instead.
|
||||||
* Stub hash: 2564122a201ca462ee35ead1562c94da3ea3c8a3 */
|
* Stub hash: b70561858fb66134ce9596921215881fd9b946c0 */
|
||||||
|
|
||||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0)
|
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)
|
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
|
||||||
|
@ -543,6 +543,8 @@ ZEND_END_ARG_INFO()
|
||||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionAttribute_newInstance, 0, 0, IS_OBJECT, 0)
|
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionAttribute_newInstance, 0, 0, IS_OBJECT, 0)
|
||||||
ZEND_END_ARG_INFO()
|
ZEND_END_ARG_INFO()
|
||||||
|
|
||||||
|
#define arginfo_class_ReflectionAttribute___toString arginfo_class_ReflectionFunction___toString
|
||||||
|
|
||||||
#define arginfo_class_ReflectionAttribute___clone arginfo_class_ReflectionFunctionAbstract___clone
|
#define arginfo_class_ReflectionAttribute___clone arginfo_class_ReflectionFunctionAbstract___clone
|
||||||
|
|
||||||
#define arginfo_class_ReflectionAttribute___construct arginfo_class_ReflectionReference___construct
|
#define arginfo_class_ReflectionAttribute___construct arginfo_class_ReflectionReference___construct
|
||||||
|
@ -800,6 +802,7 @@ ZEND_METHOD(ReflectionAttribute, getTarget);
|
||||||
ZEND_METHOD(ReflectionAttribute, isRepeated);
|
ZEND_METHOD(ReflectionAttribute, isRepeated);
|
||||||
ZEND_METHOD(ReflectionAttribute, getArguments);
|
ZEND_METHOD(ReflectionAttribute, getArguments);
|
||||||
ZEND_METHOD(ReflectionAttribute, newInstance);
|
ZEND_METHOD(ReflectionAttribute, newInstance);
|
||||||
|
ZEND_METHOD(ReflectionAttribute, __toString);
|
||||||
ZEND_METHOD(ReflectionAttribute, __clone);
|
ZEND_METHOD(ReflectionAttribute, __clone);
|
||||||
ZEND_METHOD(ReflectionAttribute, __construct);
|
ZEND_METHOD(ReflectionAttribute, __construct);
|
||||||
ZEND_METHOD(ReflectionEnum, __construct);
|
ZEND_METHOD(ReflectionEnum, __construct);
|
||||||
|
@ -1130,6 +1133,7 @@ static const zend_function_entry class_ReflectionAttribute_methods[] = {
|
||||||
ZEND_ME(ReflectionAttribute, isRepeated, arginfo_class_ReflectionAttribute_isRepeated, ZEND_ACC_PUBLIC)
|
ZEND_ME(ReflectionAttribute, isRepeated, arginfo_class_ReflectionAttribute_isRepeated, ZEND_ACC_PUBLIC)
|
||||||
ZEND_ME(ReflectionAttribute, getArguments, arginfo_class_ReflectionAttribute_getArguments, ZEND_ACC_PUBLIC)
|
ZEND_ME(ReflectionAttribute, getArguments, arginfo_class_ReflectionAttribute_getArguments, ZEND_ACC_PUBLIC)
|
||||||
ZEND_ME(ReflectionAttribute, newInstance, arginfo_class_ReflectionAttribute_newInstance, ZEND_ACC_PUBLIC)
|
ZEND_ME(ReflectionAttribute, newInstance, arginfo_class_ReflectionAttribute_newInstance, ZEND_ACC_PUBLIC)
|
||||||
|
ZEND_ME(ReflectionAttribute, __toString, arginfo_class_ReflectionAttribute___toString, ZEND_ACC_PUBLIC)
|
||||||
ZEND_ME(ReflectionAttribute, __clone, arginfo_class_ReflectionAttribute___clone, ZEND_ACC_PRIVATE)
|
ZEND_ME(ReflectionAttribute, __clone, arginfo_class_ReflectionAttribute___clone, ZEND_ACC_PRIVATE)
|
||||||
ZEND_ME(ReflectionAttribute, __construct, arginfo_class_ReflectionAttribute___construct, ZEND_ACC_PRIVATE)
|
ZEND_ME(ReflectionAttribute, __construct, arginfo_class_ReflectionAttribute___construct, ZEND_ACC_PRIVATE)
|
||||||
ZEND_FE_END
|
ZEND_FE_END
|
||||||
|
@ -1435,13 +1439,14 @@ static zend_class_entry *register_class_ReflectionReference(void)
|
||||||
return class_entry;
|
return class_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
static zend_class_entry *register_class_ReflectionAttribute(void)
|
static zend_class_entry *register_class_ReflectionAttribute(zend_class_entry *class_entry_Reflector)
|
||||||
{
|
{
|
||||||
zend_class_entry ce, *class_entry;
|
zend_class_entry ce, *class_entry;
|
||||||
|
|
||||||
INIT_CLASS_ENTRY(ce, "ReflectionAttribute", class_ReflectionAttribute_methods);
|
INIT_CLASS_ENTRY(ce, "ReflectionAttribute", class_ReflectionAttribute_methods);
|
||||||
class_entry = zend_register_internal_class_ex(&ce, NULL);
|
class_entry = zend_register_internal_class_ex(&ce, NULL);
|
||||||
class_entry->ce_flags |= ZEND_ACC_FINAL;
|
class_entry->ce_flags |= ZEND_ACC_FINAL;
|
||||||
|
zend_class_implements(class_entry, 1, class_entry_Reflector);
|
||||||
|
|
||||||
return class_entry;
|
return class_entry;
|
||||||
}
|
}
|
||||||
|
|
26
ext/reflection/tests/ReflectionAttribute_toString.phpt
Normal file
26
ext/reflection/tests/ReflectionAttribute_toString.phpt
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
--TEST--
|
||||||
|
ReflectionAttribute::__toString
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
#[Foo, Bar(a: "foo", b: 1234), Baz("foo", 1234)]
|
||||||
|
function foo() {}
|
||||||
|
|
||||||
|
$refl = new ReflectionFunction('foo');
|
||||||
|
echo $refl->getAttributes()[0];
|
||||||
|
echo $refl->getAttributes()[1];
|
||||||
|
echo $refl->getAttributes()[2];
|
||||||
|
--EXPECTF--
|
||||||
|
Attribute [ Foo ]
|
||||||
|
Attribute [ Bar ] {
|
||||||
|
- Arguments [2] {
|
||||||
|
Argument #0 [ a = 'foo' ]
|
||||||
|
Argument #1 [ b = 1234 ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Attribute [ Baz ] {
|
||||||
|
- Arguments [2] {
|
||||||
|
Argument #0 [ 'foo' ]
|
||||||
|
Argument #1 [ 1234 ]
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue