Skip to content

Commit 577eda4

Browse files
committed
Add tests and try to resolve bound closure
1 parent d5a51e6 commit 577eda4

File tree

4 files changed

+130
-1
lines changed

4 files changed

+130
-1
lines changed

ext/reflection/php_reflection.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1616,8 +1616,13 @@ ZEND_METHOD(ReflectionFunction, __construct)
16161616
Z_PARAM_OBJ_OF_CLASS_OR_STR(closure_obj, zend_ce_closure, fname)
16171617
ZEND_PARSE_PARAMETERS_END();
16181618

1619+
/* Set CE to NULL */
1620+
intern->ce = NULL;
16191621
if (closure_obj) {
16201622
fptr = (zend_function*)zend_get_closure_method_def(closure_obj);
1623+
//zend_object *tmp = NULL;
1624+
///* We use the get_closure object handler that always succeds to fetch the function and CE pointers */
1625+
//closure_obj->handlers->get_closure(closure_obj, &intern->ce, &fptr, /* obj_ptr */ &tmp, /* check_only */ false);
16211626
} else {
16221627
if (UNEXPECTED(ZSTR_VAL(fname)[0] == '\\')) {
16231628
/* Ignore leading "\" */
@@ -1652,7 +1657,6 @@ ZEND_METHOD(ReflectionFunction, __construct)
16521657
} else {
16531658
ZVAL_UNDEF(&intern->obj);
16541659
}
1655-
intern->ce = NULL;
16561660
}
16571661
/* }}} */
16581662

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
ReflectionTypes of relative class types (self, parent) from traits in classes, variadic parameter DNF types
3+
--XFAIL--
4+
I'm confused why it not possible to chope the bound scope via Reflection
5+
--FILE--
6+
<?php
7+
8+
class A {}
9+
class B extends A {}
10+
11+
$fnSelf = function (): self { };
12+
$fnParent = function (): parent {};
13+
$fnStatic = function (): static {};
14+
15+
$instances = [
16+
$fnSelf,
17+
$fnParent,
18+
$fnStatic,
19+
];
20+
21+
$b = new B();
22+
23+
// TODO Method getClosureScopeClass() seems useful
24+
// TODO Need to pass scope to: ZEND_METHOD(ReflectionFunctionAbstract, getParameters) ?
25+
// TODO Need to pass scope to: ZEND_METHOD(ReflectionFunctionAbstract, getReturnType) ?
26+
foreach ($instances as $instance) {
27+
$instance->bindTo($b);
28+
$rc = new ReflectionFunction($instance);
29+
echo "\tBound to: ", $rc->getClosureScopeClass()->name, PHP_EOL;
30+
$type = $rc->getReturnType();
31+
echo "\tType: ", $type, PHP_EOL;
32+
echo "\tInstance of: ", $type::class, PHP_EOL;
33+
try {
34+
$resolvedType = $type->resolveToNamedType();
35+
echo "\t\tResolved Type: ", $resolvedType, PHP_EOL;
36+
echo "\t\tInstance of: ", $resolvedType::class, PHP_EOL;
37+
} catch (\Throwable $e) {
38+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
39+
}
40+
}
41+
42+
?>
43+
--EXPECT--
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
ReflectionTypes of relative class types (self, parent) from traits in classes, variadic parameter DNF types
3+
--FILE--
4+
<?php
5+
6+
$fnSelf = function (): self { };
7+
$fnParent = function (): parent {};
8+
$fnStatic = function (): static {};
9+
10+
$instances = [
11+
$fnSelf,
12+
$fnParent,
13+
$fnStatic,
14+
];
15+
16+
foreach ($instances as $instance) {
17+
$rc = new ReflectionFunction($instance);
18+
$type = $rc->getReturnType();
19+
echo "\t\tType: ", $type, PHP_EOL;
20+
echo "\t\tInstance of: ", $type::class, PHP_EOL;
21+
try {
22+
$resolvedType = $type->resolveToNamedType();
23+
echo "\t\t\tResolved Type: ", $resolvedType, PHP_EOL;
24+
echo "\t\t\tInstance of: ", $resolvedType::class, PHP_EOL;
25+
} catch (\Throwable $e) {
26+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
27+
}
28+
}
29+
30+
?>
31+
--EXPECT--
32+
Type: self
33+
Instance of: ReflectionRelativeClassType
34+
ReflectionException: Cannot resolve relative class name for a closure
35+
Type: parent
36+
Instance of: ReflectionRelativeClassType
37+
ReflectionException: Cannot resolve relative class name for a closure
38+
Type: static
39+
Instance of: ReflectionRelativeClassType
40+
ReflectionException: Cannot resolve relative class name for a closure
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
--TEST--
2+
ReflectionTypes of relative class types (self, parent) from traits in classes, variadic parameter DNF types
3+
--FILE--
4+
<?php
5+
6+
trait TraitExample {
7+
public function bar(object $o): parent { return $o; }
8+
public function ping(object $o): self { return $o; }
9+
public function pong(object $o): static { return $o; }
10+
}
11+
12+
$rc = new ReflectionClass('TraitExample');
13+
14+
$methods = $rc->getMethods();
15+
foreach ($methods as $method) {
16+
echo "Method: ", $method->name, PHP_EOL;
17+
$type = $method->getReturnType();
18+
echo "\tType: ", $type, PHP_EOL;
19+
echo "\tInstance of: ", $type::class, PHP_EOL;
20+
try {
21+
$resolvedType = $type->resolveToNamedType();
22+
echo "\t\tResolved Type: ", $resolvedType, PHP_EOL;
23+
echo "\t\tInstance of: ", $resolvedType::class, PHP_EOL;
24+
} catch (\Throwable $e) {
25+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
26+
}
27+
}
28+
29+
?>
30+
--EXPECT--
31+
Method: bar
32+
Type: parent
33+
Instance of: ReflectionRelativeClassType
34+
ReflectionException: Cannot resolve relative class name for a trait
35+
Method: ping
36+
Type: self
37+
Instance of: ReflectionRelativeClassType
38+
ReflectionException: Cannot resolve relative class name for a trait
39+
Method: pong
40+
Type: static
41+
Instance of: ReflectionRelativeClassType
42+
ReflectionException: Cannot resolve relative class name for a trait

0 commit comments

Comments
 (0)