@@ -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
162163typedef enum {
@@ -1236,7 +1237,7 @@ static void _extension_string(smart_str *str, const zend_module_entry *module, c
12361237
12371238/* {{{ reflection_attribute_factory */
12381239static 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
12581260static 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
13121314static 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 */
72157235ZEND_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
78287849ZEND_METHOD (ReflectionConstant , __toString )
0 commit comments