Skip to content

Commit c0a2da3

Browse files
committed
Address review comments
1 parent 118ca1c commit c0a2da3

File tree

6 files changed

+39
-76
lines changed

6 files changed

+39
-76
lines changed

Zend/tests/type_declarations/intersection_types/resolved_relativre_type_valid.phpt renamed to Zend/tests/type_declarations/intersection_types/resolved_relative_type_valid.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
--TEST--
2-
parent type cannot take part in an intersection type
2+
parent/self type can take part in an intersection type if it is resolvable at compile time
33
--FILE--
44
<?php
55

ext/reflection/php_reflection.c

Lines changed: 29 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,20 +1462,17 @@ static void reflection_type_factory(
14621462
if (closure_object) {
14631463
ZVAL_OBJ_COPY(&intern->obj, closure_object);
14641464

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+
}
14791476
} else {
14801477
ZVAL_UNDEF(&intern->obj);
14811478
}
@@ -3191,55 +3188,12 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
31913188
}
31923189
GET_REFLECTION_OBJECT_PTR(param);
31933190

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();
32433197
}
32443198

32453199
if (intern->ce->ce_flags & ZEND_ACC_TRAIT) {
@@ -3248,8 +3202,6 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
32483202
RETURN_THROWS();
32493203
}
32503204

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);
32533205
/* Support for legacy behaviour of nullable types and ReflectionNamedType */
32543206
bool allows_null = ZEND_TYPE_PURE_MASK(param->type) & MAY_BE_NULL;
32553207
zend_type resolved_type;
@@ -3259,7 +3211,18 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
32593211
"Cannot resolve \"static\" type of an interface");
32603212
RETURN_THROWS();
32613213
}
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+
}
32633226

32643227
reflection_type_factory(
32653228
resolved_type,

ext/reflection/tests/types/relative_class_types/closure_unresolvable_relative_types.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ foreach ($instances as $instance) {
3131
--EXPECT--
3232
Type: self
3333
Instance of: ReflectionRelativeClassType
34-
ReflectionException: Cannot resolve relative class name for a closure
34+
ReflectionException: Cannot resolve relative class name for a static closure
3535
Type: parent
3636
Instance of: ReflectionRelativeClassType
37-
ReflectionException: Cannot resolve relative class name for a closure
37+
ReflectionException: Cannot resolve relative class name for a static closure
3838
Type: static
3939
Instance of: ReflectionRelativeClassType
40-
ReflectionException: Cannot resolve relative class name for a closure
40+
ReflectionException: Cannot resolve relative class name for a static closure

ext/reflection/tests/types/unresolved_relative_class_types.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ foreach ($methods as $method) {
5656
Closure:
5757
Type: self
5858
Instance of: ReflectionRelativeClassType
59-
Cannot resolve relative class name for a closure
59+
Cannot resolve relative class name for a static closure
6060
Closure:
6161
Type: parent
6262
Instance of: ReflectionRelativeClassType
63-
Cannot resolve relative class name for a closure
63+
Cannot resolve relative class name for a static closure
6464
Closure:
6565
Type: static
6666
Instance of: ReflectionRelativeClassType
67-
Cannot resolve relative class name for a closure
67+
Cannot resolve relative class name for a static closure
6868

6969
Trait:
7070
Method: bar

ext/reflection/tests/types/unresolved_relative_class_types_union_type.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ foreach ($methods as $method) {
6666
Closure:
6767
Type: self
6868
Instance of: ReflectionRelativeClassType
69-
Cannot resolve relative class name for a closure
69+
Cannot resolve relative class name for a static closure
7070
Closure:
7171
Type: parent
7272
Instance of: ReflectionRelativeClassType
73-
Cannot resolve relative class name for a closure
73+
Cannot resolve relative class name for a static closure
7474
Closure:
7575
Type: static
7676
Instance of: ReflectionRelativeClassType
77-
Cannot resolve relative class name for a closure
77+
Cannot resolve relative class name for a static closure
7878

7979
Trait:
8080
Method: bar

0 commit comments

Comments
 (0)