Skip to content

Commit 8be19f7

Browse files
committed
Introduce ReflectionAttribute::getTargetReflector().
1 parent d154c72 commit 8be19f7

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

Zend/tests/attributes/020_userland_attribute_validation.phpt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ $ref = new \ReflectionFunction(#[A1] function () { });
1010
$attr = $ref->getAttributes()[0];
1111
var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_FUNCTION, $attr->isRepeated());
1212
var_dump(get_class($attr->newInstance()));
13+
assert($attr->getTargetReflector() === $ref);
1314

1415
echo "\n";
1516

1617
$ref = new \ReflectionObject(new #[A1] class() { });
1718
$attr = $ref->getAttributes()[0];
1819
var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_CLASS, $attr->isRepeated());
20+
assert($attr->getTargetReflector() === $ref);
1921

2022
try {
2123
$attr->newInstance();
@@ -28,6 +30,7 @@ echo "\n";
2830
$ref = new \ReflectionFunction(#[A1] #[A1] function () { });
2931
$attr = $ref->getAttributes()[0];
3032
var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_FUNCTION, $attr->isRepeated());
33+
assert($attr->getTargetReflector() === $ref);
3134

3235
try {
3336
$attr->newInstance();
@@ -44,6 +47,7 @@ $ref = new \ReflectionObject(new #[A2] #[A2] class() { });
4447
$attr = $ref->getAttributes()[0];
4548
var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_CLASS, $attr->isRepeated());
4649
var_dump(get_class($attr->newInstance()));
50+
assert($attr->getTargetReflector() === $ref);
4751

4852
?>
4953
--EXPECT--

ext/reflection/php_reflection.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ typedef struct _attribute_reference {
157157
zend_class_entry *scope;
158158
zend_string *filename;
159159
uint32_t target;
160+
zval target_reflector;
160161
} attribute_reference;
161162

162163
typedef enum {
@@ -1236,7 +1237,7 @@ static void _extension_string(smart_str *str, const zend_module_entry *module, c
12361237

12371238
/* {{{ reflection_attribute_factory */
12381239
static void reflection_attribute_factory(zval *object, HashTable *attributes, zend_attribute *data,
1239-
zend_class_entry *scope, uint32_t target, zend_string *filename)
1240+
zend_class_entry *scope, uint32_t target, zend_string *filename, zval *target_reflector)
12401241
{
12411242
reflection_object *intern;
12421243
attribute_reference *reference;
@@ -1249,14 +1250,15 @@ static void reflection_attribute_factory(zval *object, HashTable *attributes, ze
12491250
reference->scope = scope;
12501251
reference->filename = filename ? zend_string_copy(filename) : NULL;
12511252
reference->target = target;
1253+
ZVAL_COPY(&reference->target_reflector, target_reflector);
12521254
intern->ptr = reference;
12531255
intern->ref_type = REF_TYPE_ATTRIBUTE;
12541256
ZVAL_STR_COPY(reflection_prop_name(object), data->name);
12551257
}
12561258
/* }}} */
12571259

12581260
static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *scope,
1259-
uint32_t offset, uint32_t target, zend_string *name, zend_class_entry *base, zend_string *filename) /* {{{ */
1261+
uint32_t offset, uint32_t target, zend_string *name, zend_class_entry *base, zend_string *filename, zval *target_reflector) /* {{{ */
12601262
{
12611263
ZEND_ASSERT(attributes != NULL);
12621264

@@ -1269,7 +1271,7 @@ static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *s
12691271

12701272
ZEND_HASH_PACKED_FOREACH_PTR(attributes, attr) {
12711273
if (attr->offset == offset && zend_string_equals(attr->lcname, filter)) {
1272-
reflection_attribute_factory(&tmp, attributes, attr, scope, target, filename);
1274+
reflection_attribute_factory(&tmp, attributes, attr, scope, target, filename, target_reflector);
12731275
add_next_index_zval(ret, &tmp);
12741276
}
12751277
} ZEND_HASH_FOREACH_END();
@@ -1301,7 +1303,7 @@ static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *s
13011303
}
13021304
}
13031305

1304-
reflection_attribute_factory(&tmp, attributes, attr, scope, target, filename);
1306+
reflection_attribute_factory(&tmp, attributes, attr, scope, target, filename, target_reflector);
13051307
add_next_index_zval(ret, &tmp);
13061308
} ZEND_HASH_FOREACH_END();
13071309

@@ -1310,7 +1312,7 @@ static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *s
13101312
/* }}} */
13111313

13121314
static void reflect_attributes(INTERNAL_FUNCTION_PARAMETERS, HashTable *attributes,
1313-
uint32_t offset, zend_class_entry *scope, uint32_t target, zend_string *filename) /* {{{ */
1315+
uint32_t offset, zend_class_entry *scope, uint32_t target, zend_string *filename, zval *target_reflector) /* {{{ */
13141316
{
13151317
zend_string *name = NULL;
13161318
zend_long flags = 0;
@@ -1343,7 +1345,7 @@ static void reflect_attributes(INTERNAL_FUNCTION_PARAMETERS, HashTable *attribut
13431345

13441346
array_init(return_value);
13451347

1346-
if (FAILURE == read_attributes(return_value, attributes, scope, offset, target, name, base, filename)) {
1348+
if (FAILURE == read_attributes(return_value, attributes, scope, offset, target, name, base, filename, target_reflector)) {
13471349
RETURN_THROWS();
13481350
}
13491351
}
@@ -2056,7 +2058,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getAttributes)
20562058

20572059
reflect_attributes(INTERNAL_FUNCTION_PARAM_PASSTHRU,
20582060
fptr->common.attributes, 0, fptr->common.scope, target,
2059-
fptr->type == ZEND_USER_FUNCTION ? fptr->op_array.filename : NULL);
2061+
fptr->type == ZEND_USER_FUNCTION ? fptr->op_array.filename : NULL,
2062+
ZEND_THIS);
20602063
}
20612064
/* }}} */
20622065

@@ -2898,7 +2901,8 @@ ZEND_METHOD(ReflectionParameter, getAttributes)
28982901

28992902
reflect_attributes(INTERNAL_FUNCTION_PARAM_PASSTHRU,
29002903
attributes, param->offset + 1, scope, ZEND_ATTRIBUTE_TARGET_PARAMETER,
2901-
param->fptr->type == ZEND_USER_FUNCTION ? param->fptr->op_array.filename : NULL);
2904+
param->fptr->type == ZEND_USER_FUNCTION ? param->fptr->op_array.filename : NULL,
2905+
ZEND_THIS);
29022906
}
29032907

29042908
/* {{{ Returns the index of the parameter, starting from 0 */
@@ -4020,7 +4024,8 @@ ZEND_METHOD(ReflectionClassConstant, getAttributes)
40204024

40214025
reflect_attributes(INTERNAL_FUNCTION_PARAM_PASSTHRU,
40224026
ref->attributes, 0, ref->ce, ZEND_ATTRIBUTE_TARGET_CLASS_CONST,
4023-
ref->ce->type == ZEND_USER_CLASS ? ref->ce->info.user.filename : NULL);
4027+
ref->ce->type == ZEND_USER_CLASS ? ref->ce->info.user.filename : NULL,
4028+
ZEND_THIS);
40244029
}
40254030
/* }}} */
40264031

@@ -4425,7 +4430,8 @@ ZEND_METHOD(ReflectionClass, getAttributes)
44254430

44264431
reflect_attributes(INTERNAL_FUNCTION_PARAM_PASSTHRU,
44274432
ce->attributes, 0, ce, ZEND_ATTRIBUTE_TARGET_CLASS,
4428-
ce->type == ZEND_USER_CLASS ? ce->info.user.filename : NULL);
4433+
ce->type == ZEND_USER_CLASS ? ce->info.user.filename : NULL,
4434+
ZEND_THIS);
44294435
}
44304436
/* }}} */
44314437

@@ -6353,7 +6359,8 @@ ZEND_METHOD(ReflectionProperty, getAttributes)
63536359

63546360
reflect_attributes(INTERNAL_FUNCTION_PARAM_PASSTHRU,
63556361
ref->prop->attributes, 0, ref->prop->ce, ZEND_ATTRIBUTE_TARGET_PROPERTY,
6356-
ref->prop->ce->type == ZEND_USER_CLASS ? ref->prop->ce->info.user.filename : NULL);
6362+
ref->prop->ce->type == ZEND_USER_CLASS ? ref->prop->ce->info.user.filename : NULL,
6363+
ZEND_THIS);
63576364
}
63586365
/* }}} */
63596366

@@ -7211,6 +7218,19 @@ ZEND_METHOD(ReflectionAttribute, getTarget)
72117218
}
72127219
/* }}} */
72137220

7221+
/* {{{ Returns the reflection object that attribute was obtained from of the attribute */
7222+
ZEND_METHOD(ReflectionAttribute, getTargetReflector)
7223+
{
7224+
reflection_object *intern;
7225+
attribute_reference *attr;
7226+
7227+
ZEND_PARSE_PARAMETERS_NONE();
7228+
GET_REFLECTION_OBJECT_PTR(attr);
7229+
7230+
RETURN_COPY(&attr->target_reflector);
7231+
}
7232+
/* }}} */
7233+
72147234
/* {{{ Returns true if the attribute is repeated */
72157235
ZEND_METHOD(ReflectionAttribute, isRepeated)
72167236
{
@@ -7822,7 +7842,8 @@ ZEND_METHOD(ReflectionConstant, getAttributes)
78227842

78237843
reflect_attributes(INTERNAL_FUNCTION_PARAM_PASSTHRU,
78247844
const_->attributes, 0, NULL, ZEND_ATTRIBUTE_TARGET_CONST,
7825-
const_->filename);
7845+
const_->filename,
7846+
ZEND_THIS);
78267847
}
78277848

78287849
ZEND_METHOD(ReflectionConstant, __toString)

ext/reflection/php_reflection.stub.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,7 @@ class ReflectionAttribute implements Reflector
837837

838838
public function getName(): string {}
839839
public function getTarget(): int {}
840+
public function getTargetReflector(): Reflector {}
840841
public function isRepeated(): bool {}
841842
public function getArguments(): array {}
842843
public function newInstance(): object {}

0 commit comments

Comments
 (0)