@@ -1433,20 +1433,17 @@ static void reflection_type_factory(
1433
1433
if (closure_object ) {
1434
1434
ZVAL_OBJ_COPY (& intern -> obj , closure_object );
1435
1435
1436
- /* If bound to a class */
1437
- //if (object_ce) {
1438
- zend_function * fptr = NULL ;
1439
- zend_class_entry * called_scope = NULL ;
1440
- zend_object * this_obj = NULL ;
1441
- closure_object -> ce -> default_object_handlers -> get_closure (closure_object , & called_scope , & fptr , & this_obj , /* check_only */ true);
1442
- /* it was bound to something, assign ce to be zend_ce_closure as static can be completely different than self/parent
1443
- * and needs to be resolved depending on the type. */
1444
- if (type_kind == SELF_PARENT_TYPE ) {
1445
- intern -> ce = fptr -> common .scope ;
1446
- } else {
1447
- intern -> ce = called_scope ;
1448
- }
1449
- //}
1436
+ zend_function * fptr = NULL ;
1437
+ zend_class_entry * called_scope = NULL ;
1438
+ zend_object * this_obj = NULL ;
1439
+ closure_object -> ce -> default_object_handlers -> get_closure (closure_object , & called_scope , & fptr , & this_obj , /* check_only */ true);
1440
+ /* it was bound to something, assign ce to be zend_ce_closure as static can be completely different than self/parent
1441
+ * and needs to be resolved depending on the type. */
1442
+ if (type_kind == STATIC_TYPE ) {
1443
+ intern -> ce = called_scope ;
1444
+ } else {
1445
+ intern -> ce = fptr -> common .scope ;
1446
+ }
1450
1447
} else {
1451
1448
ZVAL_UNDEF (& intern -> obj );
1452
1449
}
@@ -3162,55 +3159,12 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3162
3159
}
3163
3160
GET_REFLECTION_OBJECT_PTR (param );
3164
3161
3165
- /* Is closure */
3166
- if (!Z_ISUNDEF (intern -> obj )) {
3167
- /* Unbound closures can use relative class types */
3168
- if (!intern -> ce ) {
3169
- ZEND_ASSERT (!Z_ISUNDEF (intern -> obj ));
3170
- zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3171
- "Cannot resolve relative class name for a closure" );
3172
- RETURN_THROWS ();
3173
- }
3174
-
3175
- /* Attempt to resolve bound Closure */
3176
- zend_function * fptr = NULL ;
3177
- zend_class_entry * called_scope = NULL ;
3178
- zend_object * this_obj = NULL ;
3179
-
3180
- Z_OBJ_HANDLER (intern -> obj , get_closure )(Z_OBJ (intern -> obj ), & called_scope , & fptr , & this_obj , /* check_only */ true);
3181
-
3182
- /* Support for legacy behaviour of nullable types and ReflectionNamedType */
3183
- bool allows_null = ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_NULL ;
3184
- zend_type resolved_closure_type ;
3185
-
3186
- if (ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_STATIC ) {
3187
- resolved_closure_type = (zend_type ) ZEND_TYPE_INIT_CLASS (called_scope -> name , allows_null , /* extra flags */ 0 );
3188
- } else {
3189
- ZEND_ASSERT (ZEND_TYPE_HAS_NAME (param -> type ));
3190
- ZEND_ASSERT (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" ) || zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "parent" ));
3191
-
3192
- zend_class_entry * self_ce = fptr -> common .scope ;
3193
- if (zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "self" )) {
3194
- resolved_closure_type = (zend_type ) ZEND_TYPE_INIT_CLASS (self_ce -> name , allows_null , /* extra flags */ 0 );
3195
- } else {
3196
- if (!self_ce -> parent ) {
3197
- zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3198
- "Cannot resolve \"parent\" type when class has no parent" );
3199
- RETURN_THROWS ();
3200
- }
3201
- resolved_closure_type = (zend_type ) ZEND_TYPE_INIT_CLASS (self_ce -> parent -> name , allows_null , /* extra flags */ 0 );
3202
- }
3203
- }
3204
-
3205
-
3206
- reflection_type_factory (
3207
- resolved_closure_type ,
3208
- return_value ,
3209
- /* legacy_behavior */ true,
3210
- intern -> ce ,
3211
- /* closure_object */ NULL
3212
- );
3213
- return ;
3162
+ /* Unbound closures can have relative class types that we cannot resolve */
3163
+ if (!intern -> ce ) {
3164
+ ZEND_ASSERT (!Z_ISUNDEF (intern -> obj ));
3165
+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3166
+ "Cannot resolve relative class name for a static closure" );
3167
+ RETURN_THROWS ();
3214
3168
}
3215
3169
3216
3170
if (intern -> ce -> ce_flags & ZEND_ACC_TRAIT ) {
@@ -3219,8 +3173,6 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3219
3173
RETURN_THROWS ();
3220
3174
}
3221
3175
3222
- /* For all other case self and parent will have been resolved at compile time */
3223
- ZEND_ASSERT (ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_STATIC );
3224
3176
/* Support for legacy behaviour of nullable types and ReflectionNamedType */
3225
3177
bool allows_null = ZEND_TYPE_PURE_MASK (param -> type ) & MAY_BE_NULL ;
3226
3178
zend_type resolved_type ;
@@ -3230,7 +3182,18 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
3230
3182
"Cannot resolve \"static\" type of an interface" );
3231
3183
RETURN_THROWS ();
3232
3184
}
3233
- resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> name , allows_null , /* extra flags */ 0 );
3185
+
3186
+ /* The only cases where self/parent are not resolved at compile time is in Closures */
3187
+ if (ZEND_TYPE_IS_COMPLEX (param -> type ) && zend_string_equals_literal_ci (ZEND_TYPE_NAME (param -> type ), "parent" )) {
3188
+ if (!intern -> ce -> parent ) {
3189
+ zend_throw_exception_ex (reflection_exception_ptr , 0 ,
3190
+ "Cannot resolve \"parent\" type when class has no parent" );
3191
+ RETURN_THROWS ();
3192
+ }
3193
+ resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> parent -> name , allows_null , /* extra flags */ 0 );
3194
+ } else {
3195
+ resolved_type = (zend_type ) ZEND_TYPE_INIT_CLASS (intern -> ce -> name , allows_null , /* extra flags */ 0 );
3196
+ }
3234
3197
3235
3198
reflection_type_factory (
3236
3199
resolved_type ,
0 commit comments