Skip to content

Commit d19e2f0

Browse files
committed
BC support for Reflection
1 parent 176b604 commit d19e2f0

File tree

7 files changed

+33
-9
lines changed

7 files changed

+33
-9
lines changed

Zend/zend_compile.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6205,9 +6205,11 @@ static zend_type zend_compile_single_typename(zend_ast *ast)
62056205
/* Transform iterable into a type union alias */
62066206
if (type_code == IS_ITERABLE) {
62076207
zend_type iterable = (zend_type) ZEND_TYPE_INIT_CLASS(ZSTR_KNOWN(ZEND_STR_TRAVERSABLE), 0, 0);
6208+
ZEND_TYPE_FULL_MASK(iterable) |= _ZEND_TYPE_NAME_BIT;
62086209
ZEND_TYPE_FULL_MASK(iterable) |= MAY_BE_ARRAY;
6210+
/* Set MAY_BE_ITERABLE for BC compat during Reflection */
6211+
ZEND_TYPE_FULL_MASK(iterable) |= MAY_BE_ITERABLE;
62096212
/* Inform that the type list is a union type */
6210-
ZEND_TYPE_FULL_MASK(iterable) |= _ZEND_TYPE_NAME_BIT;
62116213
ZEND_TYPE_FULL_MASK(iterable) |= _ZEND_TYPE_UNION_BIT;
62126214
return iterable;
62136215
}

Zend/zend_type_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
/* These are used in zend_type, but not for type inference.
3939
* They are allowed to overlap with types used during inference. */
4040
#define MAY_BE_CALLABLE (1 << IS_CALLABLE)
41+
/* Kept as BC for reflection */
42+
#define MAY_BE_ITERABLE (1 << IS_ITERABLE)
4143
#define MAY_BE_VOID (1 << IS_VOID)
4244
#define MAY_BE_NEVER (1 << IS_NEVER)
4345
#define MAY_BE_STATIC (1 << IS_STATIC)

ext/reflection/php_reflection.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,7 @@ typedef enum {
13251325
} reflection_type_kind;
13261326

13271327
/* For backwards compatibility reasons, we need to return T|null style unions
1328+
* and transformation from iterable to Traversable|array
13281329
* as a ReflectionNamedType. Here we determine what counts as a union type and
13291330
* what doesn't. */
13301331
static reflection_type_kind get_type_kind(zend_type type) {
@@ -1339,6 +1340,10 @@ static reflection_type_kind get_type_kind(zend_type type) {
13391340
}
13401341

13411342
if (ZEND_TYPE_IS_COMPLEX(type)) {
1343+
/* BC support for 'iterable' type */
1344+
if (type_mask_without_null == (MAY_BE_ARRAY|MAY_BE_ITERABLE)) {
1345+
return NAMED_TYPE;
1346+
}
13421347
if (type_mask_without_null != 0) {
13431348
return UNION_TYPE;
13441349
}
@@ -1367,6 +1372,10 @@ static void reflection_type_factory(zend_type type, zval *object, bool legacy_be
13671372
reflection_instantiate(reflection_intersection_type_ptr, object);
13681373
break;
13691374
case UNION_TYPE:
1375+
/* Clear fake iterable type */
1376+
if ((ZEND_TYPE_PURE_MASK(type) & MAY_BE_ITERABLE) != 0) {
1377+
ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_ITERABLE;
1378+
}
13701379
reflection_instantiate(reflection_union_type_ptr, object);
13711380
break;
13721381
case NAMED_TYPE:
@@ -2987,9 +2996,17 @@ ZEND_METHOD(ReflectionType, allowsNull)
29872996
}
29882997
/* }}} */
29892998

2999+
/* BC for iterable */
3000+
static zend_string *zend_type_to_string_ex(zend_type type) {
3001+
if (UNEXPECTED((ZEND_TYPE_PURE_MASK(type) & MAY_BE_ITERABLE) != 0)) {
3002+
return ZSTR_KNOWN(ZEND_STR_ITERABLE);
3003+
}
3004+
return zend_type_to_string(type);
3005+
}
3006+
29903007
static zend_string *zend_type_to_string_without_null(zend_type type) {
29913008
ZEND_TYPE_FULL_MASK(type) &= ~MAY_BE_NULL;
2992-
return zend_type_to_string(type);
3009+
return zend_type_to_string_ex(type);
29933010
}
29943011

29953012
/* {{{ Return the text of the type hint */
@@ -3003,7 +3020,7 @@ ZEND_METHOD(ReflectionType, __toString)
30033020
}
30043021
GET_REFLECTION_OBJECT_PTR(param);
30053022

3006-
RETURN_STR(zend_type_to_string(param->type));
3023+
RETURN_STR(zend_type_to_string_ex(param->type));
30073024
}
30083025
/* }}} */
30093026

@@ -3021,7 +3038,7 @@ ZEND_METHOD(ReflectionNamedType, getName)
30213038
if (param->legacy_behavior) {
30223039
RETURN_STR(zend_type_to_string_without_null(param->type));
30233040
}
3024-
RETURN_STR(zend_type_to_string(param->type));
3041+
RETURN_STR(zend_type_to_string_ex(param->type));
30253042
}
30263043
/* }}} */
30273044

@@ -3094,6 +3111,9 @@ ZEND_METHOD(ReflectionUnionType, getTypes)
30943111
if (type_mask & MAY_BE_CALLABLE) {
30953112
append_type_mask(return_value, MAY_BE_CALLABLE);
30963113
}
3114+
if (type_mask & MAY_BE_ITERABLE) {
3115+
append_type_mask(return_value, MAY_BE_ITERABLE);
3116+
}
30973117
if (type_mask & MAY_BE_OBJECT) {
30983118
append_type_mask(return_value, MAY_BE_OBJECT);
30993119
}

ext/reflection/tests/ReflectionClass_isArray.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Deprecated: Method ReflectionParameter::isArray() is deprecated in %s on line %d
2121
bool(true)
2222

2323
Deprecated: Method ReflectionParameter::isArray() is deprecated in %s on line %d
24-
bool(true)
24+
bool(false)
2525

2626
Deprecated: Method ReflectionParameter::isArray() is deprecated in %s on line %d
2727
bool(false)

ext/reflection/tests/ReflectionType_001.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ foreach ($reflector->getProperties() as $name => $property) {
9595
printf("public %s $%s;\n", $type->getName(), $property->getName());
9696
} else {
9797
echo 'public ', implode('|', $type->getTypes()),
98-
' $', $property->getName(), "\n";
98+
' $', $property->getName(), ";\n";
9999
}
100100
} else printf("public $%s;\n", $property->getName());
101101
}
@@ -221,7 +221,7 @@ string(4) "Test"
221221
public int $int;
222222
public string $string;
223223
public array $arr;
224-
public Traversable|array $iterable
224+
public iterable $iterable;
225225
public stdClass $std;
226226
public OtherThing $other;
227227
public $mixed;

ext/reflection/tests/ReflectionType_possible_types.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ string(6) "string"
3333
string(4) "bool"
3434
string(5) "array"
3535
string(8) "callable"
36-
string(17) "Traversable|array"
36+
string(8) "iterable"
3737
string(8) "StdClass"

ext/reflection/tests/bug72661.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ function test(iterable $arg) { }
77
var_dump((string)(new ReflectionParameter("test", 0))->getType());
88
?>
99
--EXPECT--
10-
string(17) "Traversable|array"
10+
string(8) "iterable"

0 commit comments

Comments
 (0)