@@ -147,6 +147,7 @@ typedef struct _attribute_reference {
147
147
zend_attribute * data ;
148
148
zend_class_entry * scope ;
149
149
zend_string * filename ;
150
+ bool is_user_defined ;
150
151
uint32_t target ;
151
152
} attribute_reference ;
152
153
@@ -1116,7 +1117,7 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i
1116
1117
1117
1118
/* {{{ reflection_attribute_factory */
1118
1119
static void reflection_attribute_factory (zval * object , HashTable * attributes , zend_attribute * data ,
1119
- zend_class_entry * scope , uint32_t target , zend_string * filename )
1120
+ zend_class_entry * scope , uint32_t target , zend_string * filename , bool is_user_defined )
1120
1121
{
1121
1122
reflection_object * intern ;
1122
1123
attribute_reference * reference ;
@@ -1129,14 +1130,15 @@ static void reflection_attribute_factory(zval *object, HashTable *attributes, ze
1129
1130
reference -> scope = scope ;
1130
1131
reference -> filename = filename ? zend_string_copy (filename ) : NULL ;
1131
1132
reference -> target = target ;
1133
+ reference -> is_user_defined = is_user_defined ;
1132
1134
intern -> ptr = reference ;
1133
1135
intern -> ref_type = REF_TYPE_ATTRIBUTE ;
1134
1136
ZVAL_STR_COPY (reflection_prop_name (object ), data -> name );
1135
1137
}
1136
1138
/* }}} */
1137
1139
1138
1140
static int read_attributes (zval * ret , HashTable * attributes , zend_class_entry * scope ,
1139
- uint32_t offset , uint32_t target , zend_string * name , zend_class_entry * base , zend_string * filename ) /* {{{ */
1141
+ uint32_t offset , uint32_t target , zend_string * name , zend_class_entry * base , zend_string * filename , bool is_user_defined ) /* {{{ */
1140
1142
{
1141
1143
ZEND_ASSERT (attributes != NULL );
1142
1144
@@ -1149,7 +1151,7 @@ static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *s
1149
1151
1150
1152
ZEND_HASH_PACKED_FOREACH_PTR (attributes , attr ) {
1151
1153
if (attr -> offset == offset && zend_string_equals (attr -> lcname , filter )) {
1152
- reflection_attribute_factory (& tmp , attributes , attr , scope , target , filename );
1154
+ reflection_attribute_factory (& tmp , attributes , attr , scope , target , filename , is_user_defined );
1153
1155
add_next_index_zval (ret , & tmp );
1154
1156
}
1155
1157
} ZEND_HASH_FOREACH_END ();
@@ -1181,7 +1183,7 @@ static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *s
1181
1183
}
1182
1184
}
1183
1185
1184
- reflection_attribute_factory (& tmp , attributes , attr , scope , target , filename );
1186
+ reflection_attribute_factory (& tmp , attributes , attr , scope , target , filename , is_user_defined );
1185
1187
add_next_index_zval (ret , & tmp );
1186
1188
} ZEND_HASH_FOREACH_END ();
1187
1189
@@ -1190,7 +1192,7 @@ static int read_attributes(zval *ret, HashTable *attributes, zend_class_entry *s
1190
1192
/* }}} */
1191
1193
1192
1194
static void reflect_attributes (INTERNAL_FUNCTION_PARAMETERS , HashTable * attributes ,
1193
- uint32_t offset , zend_class_entry * scope , uint32_t target , zend_string * filename ) /* {{{ */
1195
+ uint32_t offset , zend_class_entry * scope , uint32_t target , zend_string * filename , bool is_user_defined ) /* {{{ */
1194
1196
{
1195
1197
zend_string * name = NULL ;
1196
1198
zend_long flags = 0 ;
@@ -1223,7 +1225,7 @@ static void reflect_attributes(INTERNAL_FUNCTION_PARAMETERS, HashTable *attribut
1223
1225
1224
1226
array_init (return_value );
1225
1227
1226
- if (FAILURE == read_attributes (return_value , attributes , scope , offset , target , name , base , filename )) {
1228
+ if (FAILURE == read_attributes (return_value , attributes , scope , offset , target , name , base , filename , is_user_defined )) {
1227
1229
RETURN_THROWS ();
1228
1230
}
1229
1231
}
@@ -1956,7 +1958,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, getAttributes)
1956
1958
1957
1959
reflect_attributes (INTERNAL_FUNCTION_PARAM_PASSTHRU ,
1958
1960
fptr -> common .attributes , 0 , fptr -> common .scope , target ,
1959
- fptr -> type == ZEND_USER_FUNCTION ? fptr -> op_array .filename : NULL );
1961
+ fptr -> type == ZEND_USER_FUNCTION ? fptr -> op_array .filename : NULL , ZEND_USER_CODE ( fptr -> type ) );
1960
1962
}
1961
1963
/* }}} */
1962
1964
@@ -2837,7 +2839,7 @@ ZEND_METHOD(ReflectionParameter, getAttributes)
2837
2839
2838
2840
reflect_attributes (INTERNAL_FUNCTION_PARAM_PASSTHRU ,
2839
2841
attributes , param -> offset + 1 , scope , ZEND_ATTRIBUTE_TARGET_PARAMETER ,
2840
- param -> fptr -> type == ZEND_USER_FUNCTION ? param -> fptr -> op_array .filename : NULL );
2842
+ param -> fptr -> type == ZEND_USER_FUNCTION ? param -> fptr -> op_array .filename : NULL , ZEND_USER_CODE ( param -> fptr -> type ) );
2841
2843
}
2842
2844
2843
2845
/* {{{ Returns whether this parameter is an optional parameter */
@@ -4021,7 +4023,7 @@ ZEND_METHOD(ReflectionClassConstant, getAttributes)
4021
4023
4022
4024
reflect_attributes (INTERNAL_FUNCTION_PARAM_PASSTHRU ,
4023
4025
ref -> attributes , 0 , ref -> ce , ZEND_ATTRIBUTE_TARGET_CLASS_CONST ,
4024
- ref -> ce -> type == ZEND_USER_CLASS ? ref -> ce -> info .user .filename : NULL );
4026
+ ref -> ce -> type == ZEND_USER_CLASS ? ref -> ce -> info .user .filename : NULL , ref -> ce -> type == ZEND_USER_CLASS );
4025
4027
}
4026
4028
/* }}} */
4027
4029
@@ -4429,7 +4431,7 @@ ZEND_METHOD(ReflectionClass, getAttributes)
4429
4431
4430
4432
reflect_attributes (INTERNAL_FUNCTION_PARAM_PASSTHRU ,
4431
4433
ce -> attributes , 0 , ce , ZEND_ATTRIBUTE_TARGET_CLASS ,
4432
- ce -> type == ZEND_USER_CLASS ? ce -> info .user .filename : NULL );
4434
+ ce -> type == ZEND_USER_CLASS ? ce -> info .user .filename : NULL , ce -> type == ZEND_USER_CLASS );
4433
4435
}
4434
4436
/* }}} */
4435
4437
@@ -5866,7 +5868,7 @@ ZEND_METHOD(ReflectionProperty, getAttributes)
5866
5868
5867
5869
reflect_attributes (INTERNAL_FUNCTION_PARAM_PASSTHRU ,
5868
5870
ref -> prop -> attributes , 0 , ref -> prop -> ce , ZEND_ATTRIBUTE_TARGET_PROPERTY ,
5869
- ref -> prop -> ce -> type == ZEND_USER_CLASS ? ref -> prop -> ce -> info .user .filename : NULL );
5871
+ ref -> prop -> ce -> type == ZEND_USER_CLASS ? ref -> prop -> ce -> info .user .filename : NULL , ref -> prop -> ce -> type == ZEND_USER_CLASS );
5870
5872
}
5871
5873
/* }}} */
5872
5874
@@ -6681,6 +6683,53 @@ ZEND_METHOD(ReflectionAttribute, getArguments)
6681
6683
}
6682
6684
/* }}} */
6683
6685
6686
+ /* {{{ Returns true if the attribute is defined by user land code, false otherwise */
6687
+ ZEND_METHOD (ReflectionAttribute , isUserDefined )
6688
+ {
6689
+ reflection_object * intern ;
6690
+ attribute_reference * attr ;
6691
+
6692
+ if (zend_parse_parameters_none () == FAILURE ) {
6693
+ RETURN_THROWS ();
6694
+ }
6695
+ GET_REFLECTION_OBJECT_PTR (attr );
6696
+
6697
+ RETURN_BOOL (attr -> is_user_defined );
6698
+ }
6699
+ /* }}} */
6700
+
6701
+ /* {{{ Returns the filename (if it exists : user land code) at which the attribute was defined */
6702
+ ZEND_METHOD (ReflectionAttribute , getFileName )
6703
+ {
6704
+ reflection_object * intern ;
6705
+ attribute_reference * attr ;
6706
+
6707
+ if (zend_parse_parameters_none () == FAILURE ) {
6708
+ RETURN_THROWS ();
6709
+ }
6710
+ GET_REFLECTION_OBJECT_PTR (attr );
6711
+ if (attr -> filename != NULL ) {
6712
+ RETURN_STR_COPY (attr -> filename );
6713
+ }
6714
+ RETURN_FALSE ;
6715
+ }
6716
+ /* }}} */
6717
+
6718
+ /* {{{ Returns the line at which the attribute was defined */
6719
+ ZEND_METHOD (ReflectionAttribute , getLine )
6720
+ {
6721
+ reflection_object * intern ;
6722
+ attribute_reference * attr ;
6723
+
6724
+ if (zend_parse_parameters_none () == FAILURE ) {
6725
+ RETURN_THROWS ();
6726
+ }
6727
+ GET_REFLECTION_OBJECT_PTR (attr );
6728
+
6729
+ RETURN_LONG (attr -> data -> lineno );
6730
+ }
6731
+ /* }}} */
6732
+
6684
6733
static int call_attribute_constructor (
6685
6734
zend_attribute * attr , zend_class_entry * ce , zend_object * obj ,
6686
6735
zval * args , uint32_t argc , HashTable * named_params , zend_string * filename )
0 commit comments