reflection: Add ReflectionGenerator::isClosed() (#14358)

* reflection: Add `ReflectionGenerator::isClosed()`

see https://github.com/php/php-src/pull/14167#issuecomment-2133641998

* Fix test expectation

* Drop `{{{` / `}}}` comments around `ReflectionGenerator::isClosed()`
This commit is contained in:
Tim Düsterhus 2024-05-29 19:07:09 +02:00 committed by GitHub
parent f90a32c9bf
commit 8a87206211
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 111 additions and 3 deletions

1
NEWS
View File

@ -215,6 +215,7 @@ PHP NEWS
(nielsdos)
. Make ReflectionGenerator::getFunction() legal after generator termination.
(timwolla)
. Added ReflectionGenerator::isClosed(). (timwolla)
- SimpleXML:
. Fixed bug GH-12192 (SimpleXML infinite loop when getName() is called

View File

@ -286,6 +286,7 @@ PHP 8.4 UPGRADE NOTES
now returns the attached doc comments.
. ReflectionConstant was introduced.
. ReflectionClassConstant::isDeprecated() was introduced.
. ReflectionGenerator::isClosed() was introduced.
- Standard:
. stream_bucket_make_writeable() and stream_bucket_new() will now return a

View File

@ -2271,7 +2271,7 @@ ZEND_METHOD(ReflectionGenerator, __construct)
#define REFLECTION_CHECK_VALID_GENERATOR(ex) \
if (!ex) { \
_DO_THROW("Cannot fetch information from a terminated Generator"); \
_DO_THROW("Cannot fetch information from a closed Generator"); \
RETURN_THROWS(); \
}
@ -2403,6 +2403,18 @@ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator)
}
/* }}} */
ZEND_METHOD(ReflectionGenerator, isClosed)
{
zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj);
zend_execute_data *ex = generator->execute_data;
if (zend_parse_parameters_none() == FAILURE) {
RETURN_THROWS();
}
RETURN_BOOL(ex == NULL);
}
/* {{{ Constructor. Throws an Exception in case the given method does not exist */
ZEND_METHOD(ReflectionParameter, __construct)
{

View File

@ -163,6 +163,8 @@ final class ReflectionGenerator
/** @tentative-return-type */
public function getExecutingGenerator(): Generator {}
public function isClosed(): bool {}
}
class ReflectionMethod extends ReflectionFunctionAbstract

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: f3fd5084866ba31bfa4e7e2bf78d95107cfe4b61 */
* Stub hash: 53cb11e3aaa2215f8dbb39778dfbc1bd28f629af */
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 1, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
@ -128,6 +128,8 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionGenerator_getExecutingGenerator, 0, 0, Generator, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_ReflectionGenerator_isClosed arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionMethod___construct, 0, 0, 1)
ZEND_ARG_TYPE_MASK(0, objectOrMethod, MAY_BE_OBJECT|MAY_BE_STRING, NULL)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, method, IS_STRING, 1, "null")
@ -677,6 +679,7 @@ ZEND_METHOD(ReflectionGenerator, getTrace);
ZEND_METHOD(ReflectionGenerator, getFunction);
ZEND_METHOD(ReflectionGenerator, getThis);
ZEND_METHOD(ReflectionGenerator, getExecutingGenerator);
ZEND_METHOD(ReflectionGenerator, isClosed);
ZEND_METHOD(ReflectionMethod, __construct);
ZEND_METHOD(ReflectionMethod, createFromMethodName);
ZEND_METHOD(ReflectionMethod, __toString);
@ -939,6 +942,7 @@ static const zend_function_entry class_ReflectionGenerator_methods[] = {
ZEND_ME(ReflectionGenerator, getFunction, arginfo_class_ReflectionGenerator_getFunction, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionGenerator, getThis, arginfo_class_ReflectionGenerator_getThis, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionGenerator, getExecutingGenerator, arginfo_class_ReflectionGenerator_getExecutingGenerator, ZEND_ACC_PUBLIC)
ZEND_ME(ReflectionGenerator, isClosed, arginfo_class_ReflectionGenerator_isClosed, ZEND_ACC_PUBLIC)
ZEND_FE_END
};

View File

@ -19,4 +19,4 @@ try {
}
?>
--EXPECT--
Cannot fetch information from a terminated Generator
Cannot fetch information from a closed Generator

View File

@ -0,0 +1,46 @@
--TEST--
ReflectionGenerator::isClosed
--FILE--
<?php
function empty_generator() {
return;
yield;
}
$gens = [
(function() {
yield;
})(),
empty_generator(),
];
foreach ($gens as $gen) {
$ref = new ReflectionGenerator($gen);
var_dump($ref->getExecutingLine());
var_dump($ref->isClosed());
var_dump($ref->getExecutingLine());
foreach ($gen as $dummy);
var_dump($ref->isClosed());
try {
var_dump($ref->getExecutingLine());
} catch (\Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
echo PHP_EOL;
}
?>
--EXPECTF--
int(10)
bool(false)
int(10)
bool(true)
Cannot fetch information from a closed Generator
int(4)
bool(false)
int(4)
bool(true)
Cannot fetch information from a closed Generator

View File

@ -0,0 +1,42 @@
--TEST--
ReflectionGenerator::isClosed: ->valid() terminates an empty generator.
--FILE--
<?php
function empty_generator() {
return;
yield;
}
$gens = [
(function() {
yield;
})(),
empty_generator(),
];
foreach ($gens as $gen) {
$ref = new ReflectionGenerator($gen);
var_dump($ref->isClosed());
var_dump($gen->valid());
var_dump($ref->isClosed());
try {
var_dump($ref->getExecutingLine());
} catch (\Exception $e) {
echo $e->getMessage(), PHP_EOL;
}
echo PHP_EOL;
}
?>
--EXPECTF--
bool(false)
bool(true)
bool(false)
int(11)
bool(false)
bool(false)
bool(true)
Cannot fetch information from a closed Generator