From a92a1d55e0db0c971cb8ddc2cae8b6fac089f496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 29 May 2024 16:00:15 +0200 Subject: [PATCH 1/3] reflection: Add `ReflectionGenerator::isClosed()` see https://github.com/php/php-src/pull/14167#issuecomment-2133641998 --- NEWS | 1 + UPGRADING | 1 + ext/reflection/php_reflection.c | 16 ++++++- ext/reflection/php_reflection.stub.php | 2 + ext/reflection/php_reflection_arginfo.h | 6 ++- .../tests/ReflectionGenerator_isClosed.phpt | 46 +++++++++++++++++++ .../ReflectionGenerator_isClosed_002.phpt | 42 +++++++++++++++++ 7 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 ext/reflection/tests/ReflectionGenerator_isClosed.phpt create mode 100644 ext/reflection/tests/ReflectionGenerator_isClosed_002.phpt diff --git a/NEWS b/NEWS index 42168212aa523..077949c919fb3 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/UPGRADING b/UPGRADING index ab17035d54adf..37d192e03da69 100644 --- a/UPGRADING +++ b/UPGRADING @@ -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 diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a23834710de93..a543ff6b4f4f3 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -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,20 @@ 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) { diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index d3eee1ee3cf5c..59f27981d8b20 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -163,6 +163,8 @@ public function getThis(): ?object {} /** @tentative-return-type */ public function getExecutingGenerator(): Generator {} + + public function isClosed(): bool {} } class ReflectionMethod extends ReflectionFunctionAbstract diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index a1cfc2f69a9c0..250e91f0926bd 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -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 }; diff --git a/ext/reflection/tests/ReflectionGenerator_isClosed.phpt b/ext/reflection/tests/ReflectionGenerator_isClosed.phpt new file mode 100644 index 0000000000000..059a174657d6f --- /dev/null +++ b/ext/reflection/tests/ReflectionGenerator_isClosed.phpt @@ -0,0 +1,46 @@ +--TEST-- +ReflectionGenerator::isClosed +--FILE-- +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 diff --git a/ext/reflection/tests/ReflectionGenerator_isClosed_002.phpt b/ext/reflection/tests/ReflectionGenerator_isClosed_002.phpt new file mode 100644 index 0000000000000..c3dda39a283a9 --- /dev/null +++ b/ext/reflection/tests/ReflectionGenerator_isClosed_002.phpt @@ -0,0 +1,42 @@ +--TEST-- +ReflectionGenerator::isClosed: ->valid() terminates an empty generator. +--FILE-- +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 From ad97082f9ec882d248248e0f2ddcf8517665646e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 29 May 2024 17:03:11 +0200 Subject: [PATCH 2/3] Fix test expectation --- ext/reflection/tests/027.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/reflection/tests/027.phpt b/ext/reflection/tests/027.phpt index add38f14767d1..40153791ad343 100644 --- a/ext/reflection/tests/027.phpt +++ b/ext/reflection/tests/027.phpt @@ -19,4 +19,4 @@ try { } ?> --EXPECT-- -Cannot fetch information from a terminated Generator +Cannot fetch information from a closed Generator From 3a1f7c84e8032bbe54dbd6e762960d21ab834ff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 29 May 2024 17:03:29 +0200 Subject: [PATCH 3/3] Drop `{{{` / `}}}` comments around `ReflectionGenerator::isClosed()` --- ext/reflection/php_reflection.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a543ff6b4f4f3..88f2253e98a55 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -2403,7 +2403,6 @@ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator) } /* }}} */ -/* {{{ */ ZEND_METHOD(ReflectionGenerator, isClosed) { zend_generator *generator = (zend_generator *) Z_OBJ(Z_REFLECTION_P(ZEND_THIS)->obj); @@ -2415,7 +2414,6 @@ ZEND_METHOD(ReflectionGenerator, isClosed) RETURN_BOOL(ex == NULL); } -/* }}} */ /* {{{ Constructor. Throws an Exception in case the given method does not exist */ ZEND_METHOD(ReflectionParameter, __construct)