Skip to content

Commit e77225e

Browse files
committed
Address review comments
1 parent c3c09cb commit e77225e

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
@@ -1433,20 +1433,17 @@ static void reflection_type_factory(
14331433
if (closure_object) {
14341434
ZVAL_OBJ_COPY(&intern->obj, closure_object);
14351435

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+
}
14501447
} else {
14511448
ZVAL_UNDEF(&intern->obj);
14521449
}
@@ -3162,55 +3159,12 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
31623159
}
31633160
GET_REFLECTION_OBJECT_PTR(param);
31643161

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();
32143168
}
32153169

32163170
if (intern->ce->ce_flags & ZEND_ACC_TRAIT) {
@@ -3219,8 +3173,6 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
32193173
RETURN_THROWS();
32203174
}
32213175

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);
32243176
/* Support for legacy behaviour of nullable types and ReflectionNamedType */
32253177
bool allows_null = ZEND_TYPE_PURE_MASK(param->type) & MAY_BE_NULL;
32263178
zend_type resolved_type;
@@ -3230,7 +3182,18 @@ ZEND_METHOD(ReflectionRelativeClassType, resolveToNamedType)
32303182
"Cannot resolve \"static\" type of an interface");
32313183
RETURN_THROWS();
32323184
}
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+
}
32343197

32353198
reflection_type_factory(
32363199
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)