@@ -1462,20 +1462,17 @@ static void reflection_type_factory(
1462
1462
if (closure_object ) {
1463
1463
ZVAL_OBJ_COPY (& intern -> obj , closure_object );
1464
1464
1465
- /* If bound to a class */
1466
- //if (object_ce) {
1467
- zend_function * fptr = NULL ;
1468
- zend_class_entry * called_scope = NULL ;
1469
- zend_object * this_obj = NULL ;
1470
- closure_object -> ce -> default_object_handlers -> get_closure (closure_object , & called_scope , & fptr , & this_obj , /* check_only */ true);
1471
- /* it was bound to something, assign ce to be zend_ce_closure as static can be completely different than self/parent
1472
- * and needs to be resolved depending on the type. */
1473
- if (type_kind == SELF_PARENT_TYPE ) {
1474
- intern -> ce = fptr -> common .scope ;
1475
- } else {
1476
- intern -> ce = called_scope ;
1477
- }
1478
- //}
1465
+ zend_function * fptr = NULL ;
1466
+ zend_class_entry * called_scope = NULL ;
1467
+ zend_object * this_obj = NULL ;
1468
+ closure_object -> ce -> default_object_handlers -> get_closure (closure_object , & called_scope , & fptr , & this_obj , /* check_only */ true);
1469
+ /* it was bound to something, assign ce to be zend_ce_closure as static can be completely different than self/parent
1470
+ * and needs to be resolved depending on the type. */
1471
+ if (type_kind == STATIC_TYPE ) {
1472
+ intern -> ce = called_scope ;
1473
+ } else {
1474
+ intern -> ce = fptr -> common .scope ;
1475
+ }
1479
1476
} else {
1480
1477
ZVAL_UNDEF (& intern -> obj );
1481
1478
}
@@ -3191,55 +3188,12 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3191
3188
}
3192
3189
GET_REFLECTION_OBJECT_PTR (param );
3193
3190
3194
- /* Is closure */
3195
- if (!Z_ISUNDEF (intern -> obj )) {
3196
- /* Unbound closures can use relative class types */
3197
- if (!intern -> ce ) {
3198
- ZEND_ASSERT (!Z_ISUNDEF (intern -> obj ));
3199
- zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3200
- "Cannot resolve relative class name for a closure" );
3201
- RETURN_THROWS ();
3202
- }
3203
-
3204
- /* Attempt to resolve bound Closure */
3205
- zend_function * fptr = NULL ;
3206
- zend_class_entry * called_scope = NULL ;
3207
- zend_object * this_obj = NULL ;
3208
-
3209
- Z_OBJ_HANDLER (intern -> obj , get_closure )(Z_OBJ (intern -> obj ), & called_scope , & fptr , & this_obj , /* check_only */ true);
3210
-
3211
- /* Support for legacy behaviour of nullable types and ReflectionNamedType */
3212
- bool allows_null = ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_NULL ;
3213
- zend_type resolved_closure_type ;
3214
-
3215
- if (ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_STATIC ) {
3216
- resolved_closure_type = (zend_type ) ZEND_TYPE_INIT_CLASS (called_scope -> name , allows_null , /* extra flags */ 0 );
3217
- } else {
3218
- ZEND_ASSERT (ZEND_TYPE_HAS_NAME (param -> type ));
3219
- ZEND_ASSERT (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" ) || zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "parent" ));
3220
-
3221
- zend_class_entry * self_ce = fptr -> common .scope ;
3222
- if (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" )) {
3223
- resolved_closure_type = (zend_type ) ZEND_TYPE_INIT_CLASS (self_ce -> name , allows_null , /* extra flags */ 0 );
3224
- } else {
3225
- if (!self_ce -> parent ) {
3226
- zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3227
- "Cannot resolve \"parent\" type when class has no parent" );
3228
- RETURN_THROWS ();
3229
- }
3230
- resolved_closure_type = (zend_type ) ZEND_TYPE_INIT_CLASS (self_ce -> parent -> name , allows_null , /* extra flags */ 0 );
3231
- }
3232
- }
3233
-
3234
-
3235
- reflection_type_factory (
3236
- resolved_closure_type ,
3237
- return_value ,
3238
- /* legacy_behavior */ true,
3239
- intern -> ce ,
3240
- /* closure_object */ NULL
3241
- );
3242
- return ;
3191
+ /* Unbound closures can have relative class types that we cannot resolve */
3192
+ if (!intern -> ce ) {
3193
+ ZEND_ASSERT (!Z_ISUNDEF (intern -> obj ));
3194
+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3195
+ "Cannot resolve relative class name for a static closure" );
3196
+ RETURN_THROWS ();
3243
3197
}
3244
3198
3245
3199
if (intern -> ce -> ce_flags & ZEND_ACC_TRAIT ) {
@@ -3248,8 +3202,6 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3248
3202
RETURN_THROWS ();
3249
3203
}
3250
3204
3251
- /* For all other case self and parent will have been resolved at compile time */
3252
- ZEND_ASSERT (ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_STATIC );
3253
3205
/* Support for legacy behaviour of nullable types and ReflectionNamedType */
3254
3206
bool allows_null = ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_NULL ;
3255
3207
zend_type resolved_type ;
@@ -3259,7 +3211,18 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3259
3211
"Cannot resolve \"static\" type of an interface" );
3260
3212
RETURN_THROWS ();
3261
3213
}
3262
- resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> name , allows_null , /* extra flags */ 0 );
3214
+
3215
+ /* The only cases where self/parent are not resolved at compile time is in Closures */
3216
+ if (ZEND_TYPE_IS_COMPLEX (param -> type ) && zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "parent" )) {
3217
+ if (!intern -> ce -> parent ) {
3218
+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3219
+ "Cannot resolve \"parent\" type when class has no parent" );
3220
+ RETURN_THROWS ();
3221
+ }
3222
+ resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> parent -> name , allows_null , /* extra flags */ 0 );
3223
+ } else {
3224
+ resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> name , allows_null , /* extra flags */ 0 );
3225
+ }
3263
3226
3264
3227
reflection_type_factory (
3265
3228
resolved_type ,
0 commit comments