mirror of
https://github.com/bdnugget/php-src.git
synced 2026-11-07 09:17:29 +00:00
Add support for tentative return types of internal methods
RFC: https://wiki.php.net/rfc/internal_method_return_types Closses GH-6971
This commit is contained in:
39 files changed
+668
-291
No files matched your search
@@ -57,6 +57,10 @@ PHP 8.1 UPGRADE NOTES
|
||||
This means that static variables in methods now behave the same way as
|
||||
static properties.
|
||||
RFC: https://wiki.php.net/rfc/static_variable_inheritance
|
||||
. Most non-final internal methods now require overriding methods to declare a
|
||||
compatible return type, otherwise a deprecated notice is emitted during
|
||||
inheritance validation.
|
||||
RFC: https://wiki.php.net/rfc/internal_method_return_types
|
||||
|
||||
- Fileinfo:
|
||||
. The fileinfo functions now accept and return, respectively, finfo objects
|
||||
|
||||
@@ -844,7 +844,7 @@ ZEND_API uint32_t zend_get_func_info(
|
||||
#endif
|
||||
|
||||
ret = zend_get_return_info_from_signature_only(
|
||||
callee_func, /* script */ NULL, ce, ce_is_instanceof);
|
||||
callee_func, /* script */ NULL, ce, ce_is_instanceof, /* use_tentative_return_info */ !call_info->is_prototype);
|
||||
|
||||
#if ZEND_DEBUG
|
||||
if (internal_ret) {
|
||||
@@ -884,7 +884,7 @@ ZEND_API uint32_t zend_get_func_info(
|
||||
}
|
||||
if (!ret) {
|
||||
ret = zend_get_return_info_from_signature_only(
|
||||
callee_func, /* TODO: script */ NULL, ce, ce_is_instanceof);
|
||||
callee_func, /* TODO: script */ NULL, ce, ce_is_instanceof, /* use_tentative_return_info */ !call_info->is_prototype);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -4001,9 +4001,11 @@ static int is_recursive_tail_call(const zend_op_array *op_array,
|
||||
|
||||
uint32_t zend_get_return_info_from_signature_only(
|
||||
const zend_function *func, const zend_script *script,
|
||||
zend_class_entry **ce, bool *ce_is_instanceof) {
|
||||
zend_class_entry **ce, bool *ce_is_instanceof, bool use_tentative_return_info) {
|
||||
uint32_t type;
|
||||
if (func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
|
||||
if (func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE &&
|
||||
(use_tentative_return_info || !ZEND_ARG_TYPE_IS_TENTATIVE(func->common.arg_info - 1))
|
||||
) {
|
||||
zend_arg_info *ret_info = func->common.arg_info - 1;
|
||||
type = zend_fetch_arg_info_type(script, ret_info, ce);
|
||||
*ce_is_instanceof = ce != NULL;
|
||||
@@ -4025,15 +4027,15 @@ uint32_t zend_get_return_info_from_signature_only(
|
||||
ZEND_API void zend_init_func_return_info(
|
||||
const zend_op_array *op_array, const zend_script *script, zend_ssa_var_info *ret)
|
||||
{
|
||||
if (op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
|
||||
zend_ssa_range tmp_range = {0, 0, 0, 0};
|
||||
bool is_instanceof = false;
|
||||
ret->type = zend_get_return_info_from_signature_only(
|
||||
(zend_function *) op_array, script, &ret->ce, &is_instanceof);
|
||||
ret->is_instanceof = is_instanceof;
|
||||
ret->range = tmp_range;
|
||||
ret->has_range = 0;
|
||||
}
|
||||
ZEND_ASSERT((op_array->fn_flags & ZEND_ACC_HAS_RETURN_TYPE));
|
||||
|
||||
zend_ssa_range tmp_range = {0, 0, 0, 0};
|
||||
bool is_instanceof = false;
|
||||
ret->type = zend_get_return_info_from_signature_only(
|
||||
(zend_function *) op_array, script, &ret->ce, &is_instanceof, /* use_tentative_return_info */ 1);
|
||||
ret->is_instanceof = is_instanceof;
|
||||
ret->range = tmp_range;
|
||||
ret->has_range = 0;
|
||||
}
|
||||
|
||||
void zend_func_return_info(const zend_op_array *op_array,
|
||||
|
||||
@@ -271,7 +271,7 @@ ZEND_API void zend_init_func_return_info(
|
||||
const zend_op_array *op_array, const zend_script *script, zend_ssa_var_info *ret);
|
||||
uint32_t zend_get_return_info_from_signature_only(
|
||||
const zend_function *func, const zend_script *script,
|
||||
zend_class_entry **ce, bool *ce_is_instanceof);
|
||||
zend_class_entry **ce, bool *ce_is_instanceof, bool use_tentative_return_info);
|
||||
void zend_func_return_info(const zend_op_array *op_array,
|
||||
const zend_script *script,
|
||||
int recursive,
|
||||
|
||||
@@ -4,10 +4,10 @@ The default value is a class constant in the parent class method's signature.
|
||||
<?php
|
||||
class MyDateTimeZone extends DateTimeZone
|
||||
{
|
||||
public static function listIdentifiers()
|
||||
public static function listIdentifiers(): array
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of MyDateTimeZone::listIdentifiers() must be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null) in %s on line %d
|
||||
Fatal error: Declaration of MyDateTimeZone::listIdentifiers(): array must be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array in %s on line %d
|
||||
@@ -4,10 +4,10 @@ The default value is a constant in the parent class method's signature.
|
||||
<?php
|
||||
class MyDateTimeZone extends DateTimeZone
|
||||
{
|
||||
public function getTransitions()
|
||||
public function getTransitions(): array|false
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of MyDateTimeZone::getTransitions() must be compatible with DateTimeZone::getTransitions(int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX) in %s on line %d
|
||||
Fatal error: Declaration of MyDateTimeZone::getTransitions(): array|false must be compatible with DateTimeZone::getTransitions(int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX): array|false in %s on line %d
|
||||
@@ -5,8 +5,8 @@ The default value is false in the parent class method's signature.
|
||||
|
||||
interface MyDateTimeInterface extends DateTimeInterface
|
||||
{
|
||||
public function diff();
|
||||
public function diff(): DateInterval;
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of MyDateTimeInterface::diff() must be compatible with DateTimeInterface::diff(DateTimeInterface $targetObject, bool $absolute = false) in %s on line %d
|
||||
Fatal error: Declaration of MyDateTimeInterface::diff(): DateInterval must be compatible with DateTimeInterface::diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval in %s on line %d
|
||||
@@ -4,10 +4,10 @@ The default value is an integer in the parent class method's signature.
|
||||
<?php
|
||||
class MyDateTime extends DateTime
|
||||
{
|
||||
public function setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false)
|
||||
public function setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false): DateTime
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of MyDateTime::setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false) must be compatible with DateTime::setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0) in %s on line %d
|
||||
Fatal error: Declaration of MyDateTime::setTime(int $hour, int $minute, int $second = 0, bool $microsecond = false): DateTime must be compatible with DateTime::setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTime in %s on line %d
|
||||
@@ -4,10 +4,10 @@ The default value is null in the parent class method's signature.
|
||||
<?php
|
||||
class MyDateTime extends DateTime
|
||||
{
|
||||
public static function createFromFormat()
|
||||
public static function createFromFormat(): DateTime|false
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Declaration of MyDateTime::createFromFormat() must be compatible with DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null) in %s on line %d
|
||||
Fatal error: Declaration of MyDateTime::createFromFormat(): DateTime|false must be compatible with DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false in %s on line %d
|
||||
@@ -1,12 +0,0 @@
|
||||
--TEST--
|
||||
Internal class as parent
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test extends DateTime {
|
||||
public static function createFromFormat($format, $datetime, Wrong $timezone = null) { }
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Could not check compatibility between Test::createFromFormat($format, $datetime, ?Wrong $timezone = null) and DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null), because class Wrong is not available in %s on line %d
|
||||
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Test that no notice is emitted when the return type/value of the overriding method is compatible with the tentative return type/value of the overridden method
|
||||
--FILE--
|
||||
<?php
|
||||
class MyDateTimeZone extends DateTimeZone
|
||||
{
|
||||
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(MyDateTimeZone::listIdentifiers());
|
||||
?>
|
||||
--EXPECT--
|
||||
array(0) {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
--TEST--
|
||||
Test that a notice is emitted when the return type/value of the overriding method is incompatible with the tentative return type/value of the overridden method
|
||||
--FILE--
|
||||
<?php
|
||||
class MyDateTimeZone extends DateTimeZone
|
||||
{
|
||||
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): string
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
var_dump(MyDateTimeZone::listIdentifiers());
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Declaration of MyDateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): string should be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array in %s on line %d
|
||||
string(0) ""
|
||||
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Test that a notice is emitted when the tentative return type of the overridden method is omitted
|
||||
--FILE--
|
||||
<?php
|
||||
class MyDateTimeZone extends DateTimeZone
|
||||
{
|
||||
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null)
|
||||
{
|
||||
}
|
||||
}
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: Declaration of MyDateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null) should be compatible with DateTimeZone::listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array in %s on line %d
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Test unresolvable inheritance check due to unavailable parameter type when the parent has a tentative return type.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test extends DateTime {
|
||||
public static function createFromFormat($format, $datetime, Wrong $timezone = null): DateTime|false {}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Could not check compatibility between Test::createFromFormat($format, $datetime, ?Wrong $timezone = null): DateTime|false and DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false, because class Wrong is not available in %s on line %d
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
--TEST--
|
||||
Test unresolvable inheritance check due to unavailable return type when the parent has a tentative return type.
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Test extends DateTime {
|
||||
public static function createFromFormat($format, $datetime, $timezone = null): Wrong { }
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Could not check compatibility between Test::createFromFormat($format, $datetime, $timezone = null): Wrong and DateTime::createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false, because class Wrong is not available in %s on line %d
|
||||
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
Test that the ReturnTypeWillChange attribute cannot target classes
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
class Foo
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Attribute "ReturnTypeWillChange" cannot target class (allowed targets: method) in %s on line %d
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Test that the ReturnTypeWillChange attribute cannot target functions
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
#[ReturnTypeWillChange]
|
||||
function foo() {}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Attribute "ReturnTypeWillChange" cannot target function (allowed targets: method) in %s on line %d
|
||||
@@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Test that the ReturnTypeWillChange attribute cannot be used with functions
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Foo
|
||||
{
|
||||
#[ReturnTypeWillChange]
|
||||
public int $bar;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Attribute "ReturnTypeWillChange" cannot target property (allowed targets: method) in %s on line %d
|
||||
@@ -0,0 +1,21 @@
|
||||
--TEST--
|
||||
Test that the notice can be suppressed when the return type/value of the overriding method is incompatible with the tentative return type/value of the overridden method
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyDateTime extends DateTime
|
||||
{
|
||||
/**
|
||||
* @return DateTime|false
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
public function modify(string $modifier) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$date = new MyDateTime("2021-01-01 00:00:00");
|
||||
var_dump($date->modify("+1 sec"));
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
+49
-24
@@ -107,66 +107,91 @@ typedef struct _zend_fcall_info_cache {
|
||||
|
||||
#define ZEND_FE_END { NULL, NULL, NULL, 0, 0 }
|
||||
|
||||
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic) \
|
||||
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0))
|
||||
#define _ZEND_ARG_INFO_FLAGS(pass_by_ref, is_variadic, is_tentative) \
|
||||
(((pass_by_ref) << _ZEND_SEND_MODE_SHIFT) | ((is_variadic) ? _ZEND_IS_VARIADIC_BIT : 0) | ((is_tentative) ? _ZEND_IS_TENTATIVE_BIT : 0))
|
||||
|
||||
/* Arginfo structures without type information */
|
||||
#define ZEND_ARG_INFO(pass_by_ref, name) \
|
||||
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
|
||||
#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
|
||||
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
|
||||
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
|
||||
#define ZEND_ARG_VARIADIC_INFO(pass_by_ref, name) \
|
||||
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
|
||||
/* Arginfo structures with simple type information */
|
||||
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
|
||||
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
|
||||
#define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
|
||||
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
|
||||
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
|
||||
#define ZEND_ARG_VARIADIC_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) \
|
||||
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_CODE(type_hint, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
|
||||
/* Arginfo structures with complex type information */
|
||||
#define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \
|
||||
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
|
||||
{ #name, ZEND_TYPE_INIT_MASK(type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
|
||||
#define ZEND_ARG_OBJ_TYPE_MASK(pass_by_ref, name, class_name, type_mask, default_value) \
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type_mask | _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
|
||||
/* Arginfo structures with object type information */
|
||||
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
|
||||
#define ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, classname, allow_null, default_value) \
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), default_value },
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), default_value },
|
||||
#define ZEND_ARG_VARIADIC_OBJ_INFO(pass_by_ref, name, classname, allow_null) \
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_CLASS_CONST(#classname, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 1, 0)), NULL },
|
||||
/* Legacy arginfo structures */
|
||||
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) \
|
||||
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_CODE(IS_ARRAY, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
|
||||
#define ZEND_ARG_CALLABLE_INFO(pass_by_ref, name, allow_null) \
|
||||
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0)), NULL },
|
||||
{ #name, ZEND_TYPE_INIT_CODE(IS_CALLABLE, allow_null, _ZEND_ARG_INFO_FLAGS(pass_by_ref, 0, 0)), NULL },
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, return_reference, required_num_args, class_name, allow_null, is_tentative_return_type) \
|
||||
static const zend_internal_arg_info name[] = { \
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), \
|
||||
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
|
||||
ZEND_TYPE_INIT_CLASS_CONST(#class_name, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_tentative_return_type)), NULL },
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, return_reference, required_num_args, class_name, allow_null, 0)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, return_reference, required_num_args, class_name, allow_null, 1)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO(name, class_name, allow_null) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, 0, -1, class_name, allow_null)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX2(name, 0, -1, class_name, allow_null, 0)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX2(name, return_reference, required_num_args, type, is_tentative_return_type) \
|
||||
static const zend_internal_arg_info name[] = { \
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_tentative_return_type)), NULL },
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX2(name, return_reference, required_num_args, type, 0)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(name, return_reference, required_num_args, type) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX2(name, return_reference, required_num_args, type, 1)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX2(name, return_reference, required_num_args, class_name, type, is_tentative_return_type) \
|
||||
static const zend_internal_arg_info name[] = { \
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_MASK(type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_tentative_return_type)), NULL },
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX2(name, return_reference, required_num_args, class_name, type, 0)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX2(name, return_reference, required_num_args, class_name, type, 1)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, return_reference, required_num_args, type, allow_null, is_tentative_return_type) \
|
||||
static const zend_internal_arg_info name[] = { \
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CLASS_CONST_MASK(#class_name, type | _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0, is_tentative_return_type)), NULL },
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
|
||||
static const zend_internal_arg_info name[] = { \
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_CODE(type, allow_null, _ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, return_reference, required_num_args, type, allow_null, 0)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, type, allow_null) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, return_reference, required_num_args, type, allow_null, 1)
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(name, type, allow_null) \
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, 0, -1, type, allow_null)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX2(name, 0, -1, type, allow_null, 0)
|
||||
|
||||
#define ZEND_BEGIN_ARG_INFO_EX(name, _unused, return_reference, required_num_args) \
|
||||
static const zend_internal_arg_info name[] = { \
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0)), NULL },
|
||||
{ (const char*)(zend_uintptr_t)(required_num_args), ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(return_reference, 0, 0)), NULL },
|
||||
#define ZEND_BEGIN_ARG_INFO(name, _unused) \
|
||||
ZEND_BEGIN_ARG_INFO_EX(name, {}, ZEND_RETURN_VALUE, -1)
|
||||
#define ZEND_END_ARG_INFO() };
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "zend_smart_str.h"
|
||||
|
||||
ZEND_API zend_class_entry *zend_ce_attribute;
|
||||
ZEND_API zend_class_entry *zend_ce_return_type_will_change_attribute;
|
||||
|
||||
static HashTable internal_attributes;
|
||||
|
||||
@@ -67,6 +68,11 @@ ZEND_METHOD(Attribute, __construct)
|
||||
ZVAL_LONG(OBJ_PROP_NUM(Z_OBJ_P(ZEND_THIS), 0), flags);
|
||||
}
|
||||
|
||||
ZEND_METHOD(ReturnTypeWillChange, __construct)
|
||||
{
|
||||
ZEND_PARSE_PARAMETERS_NONE();
|
||||
}
|
||||
|
||||
static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset)
|
||||
{
|
||||
if (attributes) {
|
||||
@@ -278,6 +284,9 @@ void zend_register_attribute_ce(void)
|
||||
zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_PARAMETER"), ZEND_ATTRIBUTE_TARGET_PARAMETER);
|
||||
zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("TARGET_ALL"), ZEND_ATTRIBUTE_TARGET_ALL);
|
||||
zend_declare_class_constant_long(zend_ce_attribute, ZEND_STRL("IS_REPEATABLE"), ZEND_ATTRIBUTE_IS_REPEATABLE);
|
||||
|
||||
zend_ce_return_type_will_change_attribute = register_class_ReturnTypeWillChange();
|
||||
zend_internal_attribute_register(zend_ce_return_type_will_change_attribute, ZEND_ATTRIBUTE_TARGET_METHOD);
|
||||
}
|
||||
|
||||
void zend_attributes_shutdown(void)
|
||||
|
||||
@@ -8,3 +8,8 @@ final class Attribute
|
||||
|
||||
public function __construct(int $flags = Attribute::TARGET_ALL) {}
|
||||
}
|
||||
|
||||
final class ReturnTypeWillChange
|
||||
{
|
||||
public function __construct() {}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 0183e750e66999862a7688ecb251017110d06d1f */
|
||||
* Stub hash: 3fd949e1b9f49666bed3081ed1e8e711acd9f49c */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Attribute___construct, 0, 0, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "Attribute::TARGET_ALL")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReturnTypeWillChange___construct, 0, 0, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
||||
ZEND_METHOD(Attribute, __construct);
|
||||
ZEND_METHOD(ReturnTypeWillChange, __construct);
|
||||
|
||||
|
||||
static const zend_function_entry class_Attribute_methods[] = {
|
||||
@@ -14,6 +18,12 @@ static const zend_function_entry class_Attribute_methods[] = {
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
|
||||
static const zend_function_entry class_ReturnTypeWillChange_methods[] = {
|
||||
ZEND_ME(ReturnTypeWillChange, __construct, arginfo_class_ReturnTypeWillChange___construct, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
static zend_class_entry *register_class_Attribute(void)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
@@ -30,3 +40,14 @@ static zend_class_entry *register_class_Attribute(void)
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
|
||||
static zend_class_entry *register_class_ReturnTypeWillChange(void)
|
||||
{
|
||||
zend_class_entry ce, *class_entry;
|
||||
|
||||
INIT_CLASS_ENTRY(ce, "ReturnTypeWillChange", class_ReturnTypeWillChange_methods);
|
||||
class_entry = zend_register_internal_class_ex(&ce, NULL);
|
||||
class_entry->ce_flags |= ZEND_ACC_FINAL;
|
||||
|
||||
return class_entry;
|
||||
}
|
||||
+2
-2
@@ -6476,7 +6476,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
|
||||
arg_infos->type = zend_compile_typename(
|
||||
return_type_ast, /* force_allow_null */ 0);
|
||||
ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS(
|
||||
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0);
|
||||
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0, /* is_tentative */ 0);
|
||||
} else {
|
||||
arg_infos->type = (zend_type) ZEND_TYPE_INIT_CODE(fallback_return_type, 0, 0);
|
||||
}
|
||||
@@ -6606,7 +6606,7 @@ void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fall
|
||||
zend_alloc_cache_slots(zend_type_get_num_classes(arg_info->type));
|
||||
}
|
||||
|
||||
uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic)
|
||||
uint32_t arg_info_flags = _ZEND_ARG_INFO_FLAGS(is_ref, is_variadic, /* is_tentative */ 0)
|
||||
| (visibility ? _ZEND_IS_PROMOTED_BIT : 0);
|
||||
ZEND_TYPE_FULL_MASK(arg_info->type) |= arg_info_flags;
|
||||
if (opcode == ZEND_RECV) {
|
||||
|
||||
+4
-1
@@ -983,16 +983,19 @@ ZEND_API zend_string *zend_type_to_string(zend_type type);
|
||||
|
||||
#define ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS 1
|
||||
|
||||
/* The send mode and is_variadic flag are stored as part of zend_type */
|
||||
/* The send mode, the is_variadic, the is_promoted, and the is_tentative flags are stored as part of zend_type */
|
||||
#define _ZEND_SEND_MODE_SHIFT _ZEND_TYPE_EXTRA_FLAGS_SHIFT
|
||||
#define _ZEND_IS_VARIADIC_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 2))
|
||||
#define _ZEND_IS_PROMOTED_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 3))
|
||||
#define _ZEND_IS_TENTATIVE_BIT (1 << (_ZEND_TYPE_EXTRA_FLAGS_SHIFT + 4))
|
||||
#define ZEND_ARG_SEND_MODE(arg_info) \
|
||||
((ZEND_TYPE_FULL_MASK((arg_info)->type) >> _ZEND_SEND_MODE_SHIFT) & 3)
|
||||
#define ZEND_ARG_IS_VARIADIC(arg_info) \
|
||||
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_VARIADIC_BIT) != 0)
|
||||
#define ZEND_ARG_IS_PROMOTED(arg_info) \
|
||||
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_PROMOTED_BIT) != 0)
|
||||
#define ZEND_ARG_TYPE_IS_TENTATIVE(arg_info) \
|
||||
((ZEND_TYPE_FULL_MASK((arg_info)->type) & _ZEND_IS_TENTATIVE_BIT) != 0)
|
||||
|
||||
#define ZEND_DIM_IS (1 << 0) /* isset fetch needed for null coalesce */
|
||||
#define ZEND_DIM_ALTERNATIVE_SYNTAX (1 << 1) /* deprecated curly brace usage */
|
||||
|
||||
@@ -1294,6 +1294,7 @@ static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, con
|
||||
static bool zend_verify_internal_return_type(zend_function *zf, zval *ret)
|
||||
{
|
||||
zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1;
|
||||
|
||||
if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_VOID) {
|
||||
if (UNEXPECTED(Z_TYPE_P(ret) != IS_NULL)) {
|
||||
zend_verify_void_return_error(zf, zend_zval_type_name(ret), "");
|
||||
|
||||
+48
-23
@@ -27,10 +27,21 @@
|
||||
#include "zend_operators.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_enum.h"
|
||||
#include "zend_attributes.h"
|
||||
|
||||
ZEND_API zend_class_entry* (*zend_inheritance_cache_get)(zend_class_entry *ce, zend_class_entry *parent, zend_class_entry **traits_and_interfaces) = NULL;
|
||||
ZEND_API zend_class_entry* (*zend_inheritance_cache_add)(zend_class_entry *ce, zend_class_entry *proto, zend_class_entry *parent, zend_class_entry **traits_and_interfaces, HashTable *dependencies) = NULL;
|
||||
|
||||
/* Unresolved means that class declarations that are currently not available are needed to
|
||||
* determine whether the inheritance is valid or not. At runtime UNRESOLVED should be treated
|
||||
* as an ERROR. */
|
||||
typedef enum {
|
||||
INHERITANCE_UNRESOLVED = -1,
|
||||
INHERITANCE_ERROR = 0,
|
||||
INHERITANCE_WARNING = 1,
|
||||
INHERITANCE_SUCCESS = 2,
|
||||
} inheritance_status;
|
||||
|
||||
static void add_dependency_obligation(zend_class_entry *ce, zend_class_entry *dependency_ce);
|
||||
static void add_compatibility_obligation(
|
||||
zend_class_entry *ce, const zend_function *child_fn, zend_class_entry *child_scope,
|
||||
@@ -39,7 +50,12 @@ static void add_property_compatibility_obligation(
|
||||
zend_class_entry *ce, const zend_property_info *child_prop,
|
||||
const zend_property_info *parent_prop);
|
||||
|
||||
static void zend_type_copy_ctor(zend_type *type, bool persistent) {
|
||||
static void ZEND_COLD emit_incompatible_method_error(
|
||||
const zend_function *child, zend_class_entry *child_scope,
|
||||
const zend_function *parent, zend_class_entry *parent_scope,
|
||||
inheritance_status status);
|
||||
|
||||
static void zend_type_copy_ctor(zend_type *type, zend_bool persistent) {
|
||||
if (ZEND_TYPE_HAS_LIST(*type)) {
|
||||
zend_type_list *old_list = ZEND_TYPE_LIST(*type);
|
||||
size_t size = ZEND_TYPE_LIST_SIZE(old_list->num_types);
|
||||
@@ -343,16 +359,6 @@ static bool zend_type_permits_self(
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unresolved means that class declarations that are currently not available are needed to
|
||||
* determine whether the inheritance is valid or not. At runtime UNRESOLVED should be treated
|
||||
* as an ERROR. */
|
||||
typedef enum {
|
||||
INHERITANCE_UNRESOLVED = -1,
|
||||
INHERITANCE_ERROR = 0,
|
||||
INHERITANCE_SUCCESS = 1,
|
||||
} inheritance_status;
|
||||
|
||||
|
||||
static void track_class_dependency(zend_class_entry *ce, zend_string *class_name)
|
||||
{
|
||||
HashTable *ht;
|
||||
@@ -455,7 +461,7 @@ static inheritance_status zend_perform_covariant_class_type_check(
|
||||
|
||||
static inheritance_status zend_perform_covariant_type_check(
|
||||
zend_class_entry *fe_scope, zend_type fe_type,
|
||||
zend_class_entry *proto_scope, zend_type proto_type) /* {{{ */
|
||||
zend_class_entry *proto_scope, zend_type proto_type, bool tentative) /* {{{ */
|
||||
{
|
||||
ZEND_ASSERT(ZEND_TYPE_IS_SET(fe_type) && ZEND_TYPE_IS_SET(proto_type));
|
||||
|
||||
@@ -496,7 +502,7 @@ static inheritance_status zend_perform_covariant_type_check(
|
||||
|
||||
if (added_types) {
|
||||
/* Otherwise adding new types is illegal */
|
||||
return INHERITANCE_ERROR;
|
||||
return tentative ? INHERITANCE_WARNING : INHERITANCE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +528,7 @@ static inheritance_status zend_perform_covariant_type_check(
|
||||
}
|
||||
|
||||
if (status == INHERITANCE_ERROR) {
|
||||
return INHERITANCE_ERROR;
|
||||
return tentative ? INHERITANCE_WARNING : INHERITANCE_ERROR;
|
||||
}
|
||||
if (status != INHERITANCE_SUCCESS) {
|
||||
all_success = 0;
|
||||
@@ -570,7 +576,7 @@ static inheritance_status zend_do_perform_arg_type_hint_check(
|
||||
/* Contravariant type check is performed as a covariant type check with swapped
|
||||
* argument order. */
|
||||
return zend_perform_covariant_type_check(
|
||||
proto_scope, proto_arg_info->type, fe_scope, fe_arg_info->type);
|
||||
proto_scope, proto_arg_info->type, fe_scope, fe_arg_info->type, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -660,18 +666,25 @@ static inheritance_status zend_do_perform_implementation_check(
|
||||
/* Check return type compatibility, but only if the prototype already specifies
|
||||
* a return type. Adding a new return type is always valid. */
|
||||
if (proto->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
|
||||
/* Removing a return type is not valid. */
|
||||
/* Removing a return type is not valid, unless the parent return type is tentative. */
|
||||
if (!(fe->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
|
||||
return INHERITANCE_ERROR;
|
||||
if (ZEND_ARG_TYPE_IS_TENTATIVE(&proto->common.arg_info[-1])) {
|
||||
if (status == INHERITANCE_SUCCESS) {
|
||||
emit_incompatible_method_error(fe, fe_scope, proto, proto_scope, INHERITANCE_WARNING);
|
||||
}
|
||||
return status;
|
||||
} else {
|
||||
return INHERITANCE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
local_status = zend_perform_covariant_type_check(
|
||||
fe_scope, fe->common.arg_info[-1].type,
|
||||
proto_scope, proto->common.arg_info[-1].type);
|
||||
proto_scope, proto->common.arg_info[-1].type, ZEND_ARG_TYPE_IS_TENTATIVE(&proto->common.arg_info[-1]));
|
||||
|
||||
if (UNEXPECTED(local_status != INHERITANCE_SUCCESS)) {
|
||||
if (UNEXPECTED(local_status == INHERITANCE_ERROR)) {
|
||||
return INHERITANCE_ERROR;
|
||||
if (UNEXPECTED(local_status == INHERITANCE_ERROR || local_status == INHERITANCE_WARNING)) {
|
||||
return local_status;
|
||||
}
|
||||
ZEND_ASSERT(local_status == INHERITANCE_UNRESOLVED);
|
||||
status = INHERITANCE_UNRESOLVED;
|
||||
@@ -854,6 +867,18 @@ static void ZEND_COLD emit_incompatible_method_error(
|
||||
zend_error_at(E_COMPILE_ERROR, NULL, func_lineno(child),
|
||||
"Could not check compatibility between %s and %s, because class %s is not available",
|
||||
ZSTR_VAL(child_prototype), ZSTR_VAL(parent_prototype), ZSTR_VAL(unresolved_class));
|
||||
} else if (status == INHERITANCE_WARNING) {
|
||||
zend_attribute *return_type_will_change_attribute = zend_get_attribute_str(
|
||||
child->common.attributes,
|
||||
"returntypewillchange",
|
||||
sizeof("returntypewillchange")-1
|
||||
);
|
||||
|
||||
if (!return_type_will_change_attribute) {
|
||||
zend_error_at(E_DEPRECATED, NULL, func_lineno(child),
|
||||
"Declaration of %s should be compatible with %s",
|
||||
ZSTR_VAL(child_prototype), ZSTR_VAL(parent_prototype));
|
||||
}
|
||||
} else {
|
||||
zend_error_at(E_COMPILE_ERROR, NULL, func_lineno(child),
|
||||
"Declaration of %s must be compatible with %s",
|
||||
@@ -874,7 +899,7 @@ static void perform_delayable_implementation_check(
|
||||
if (EXPECTED(status == INHERITANCE_UNRESOLVED)) {
|
||||
add_compatibility_obligation(ce, fe, fe_scope, proto, proto_scope);
|
||||
} else {
|
||||
ZEND_ASSERT(status == INHERITANCE_ERROR);
|
||||
ZEND_ASSERT(status == INHERITANCE_ERROR || status == INHERITANCE_WARNING);
|
||||
emit_incompatible_method_error(fe, fe_scope, proto, proto_scope, status);
|
||||
}
|
||||
}
|
||||
@@ -1048,9 +1073,9 @@ inheritance_status property_types_compatible(
|
||||
|
||||
/* Perform a covariant type check in both directions to determined invariance. */
|
||||
inheritance_status status1 = zend_perform_covariant_type_check(
|
||||
child_info->ce, child_info->type, parent_info->ce, parent_info->type);
|
||||
child_info->ce, child_info->type, parent_info->ce, parent_info->type, 0);
|
||||
inheritance_status status2 = zend_perform_covariant_type_check(
|
||||
parent_info->ce, parent_info->type, child_info->ce, child_info->type);
|
||||
parent_info->ce, parent_info->type, child_info->ce, child_info->type, 0);
|
||||
if (status1 == INHERITANCE_SUCCESS && status2 == INHERITANCE_SUCCESS) {
|
||||
return INHERITANCE_SUCCESS;
|
||||
}
|
||||
|
||||
+22
-8
@@ -599,16 +599,20 @@ class ReturnInfo {
|
||||
public $type;
|
||||
/** @var Type|null */
|
||||
public $phpDocType;
|
||||
/** @var bool */
|
||||
public $tentativeReturnType;
|
||||
|
||||
public function __construct(bool $byRef, ?Type $type, ?Type $phpDocType) {
|
||||
public function __construct(bool $byRef, ?Type $type, ?Type $phpDocType, bool $tentativeReturnType) {
|
||||
$this->byRef = $byRef;
|
||||
$this->type = $type;
|
||||
$this->phpDocType = $phpDocType;
|
||||
$this->tentativeReturnType = $tentativeReturnType;
|
||||
}
|
||||
|
||||
public function equals(ReturnInfo $other): bool {
|
||||
return $this->byRef === $other->byRef
|
||||
&& Type::equals($this->type, $other->type);
|
||||
&& Type::equals($this->type, $other->type)
|
||||
&& $this->tentativeReturnType === $other->tentativeReturnType;
|
||||
}
|
||||
|
||||
public function getMethodSynopsisType(): ?Type {
|
||||
@@ -1431,6 +1435,7 @@ function parseFunctionLike(
|
||||
$isDeprecated = false;
|
||||
$verify = true;
|
||||
$docReturnType = null;
|
||||
$tentativeReturnType = false;
|
||||
$docParamTypes = [];
|
||||
|
||||
if ($comment) {
|
||||
@@ -1452,8 +1457,10 @@ function parseFunctionLike(
|
||||
}
|
||||
} else if ($tag->name === 'deprecated') {
|
||||
$isDeprecated = true;
|
||||
} else if ($tag->name === 'no-verify') {
|
||||
} else if ($tag->name === 'no-verify') {
|
||||
$verify = false;
|
||||
} else if ($tag->name === 'tentative-return-type') {
|
||||
$tentativeReturnType = true;
|
||||
} else if ($tag->name === 'return') {
|
||||
$docReturnType = $tag->getType();
|
||||
} else if ($tag->name === 'param') {
|
||||
@@ -1530,7 +1537,8 @@ function parseFunctionLike(
|
||||
$return = new ReturnInfo(
|
||||
$func->returnsByRef(),
|
||||
$returnType ? Type::fromNode($returnType) : null,
|
||||
$docReturnType ? Type::fromPhpDoc($docReturnType) : null
|
||||
$docReturnType ? Type::fromPhpDoc($docReturnType) : null,
|
||||
$tentativeReturnType
|
||||
);
|
||||
|
||||
return new FuncInfo(
|
||||
@@ -1814,18 +1822,22 @@ function parseStubFile(string $code): FileInfo {
|
||||
function funcInfoToCode(FuncInfo $funcInfo): string {
|
||||
$code = '';
|
||||
$returnType = $funcInfo->return->type;
|
||||
$isTentativeReturnType = $funcInfo->return->tentativeReturnType;
|
||||
|
||||
if ($returnType !== null) {
|
||||
if (null !== $simpleReturnType = $returnType->tryToSimpleType()) {
|
||||
if ($simpleReturnType->isBuiltin) {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, %d)\n",
|
||||
"%s(%s, %d, %d, %s, %d)\n",
|
||||
$isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX",
|
||||
$funcInfo->getArgInfoName(), $funcInfo->return->byRef,
|
||||
$funcInfo->numRequiredArgs,
|
||||
$simpleReturnType->toTypeCode(), $returnType->isNullable()
|
||||
);
|
||||
} else {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(%s, %d, %d, %s, %d)\n",
|
||||
"%s(%s, %d, %d, %s, %d)\n",
|
||||
$isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX",
|
||||
$funcInfo->getArgInfoName(), $funcInfo->return->byRef,
|
||||
$funcInfo->numRequiredArgs,
|
||||
$simpleReturnType->toEscapedName(), $returnType->isNullable()
|
||||
@@ -1835,14 +1847,16 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
|
||||
$arginfoType = $returnType->toArginfoType();
|
||||
if ($arginfoType->hasClassType()) {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(%s, %d, %d, %s, %s)\n",
|
||||
"%s(%s, %d, %d, %s, %s)\n",
|
||||
$isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX",
|
||||
$funcInfo->getArgInfoName(), $funcInfo->return->byRef,
|
||||
$funcInfo->numRequiredArgs,
|
||||
$arginfoType->toClassTypeString(), $arginfoType->toTypeMask()
|
||||
);
|
||||
} else {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(%s, %d, %d, %s)\n",
|
||||
"%s(%s, %d, %d, %s)\n",
|
||||
$isTentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX",
|
||||
$funcInfo->getArgInfoName(), $funcInfo->return->byRef,
|
||||
$funcInfo->numRequiredArgs,
|
||||
$arginfoType->toTypeMask()
|
||||
|
||||
@@ -336,7 +336,7 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name
|
||||
|
||||
for (i = 0; i < bindptr.lpfuncdesc->cParams; i++) {
|
||||
bool by_ref = (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) != 0;
|
||||
f.arg_info[i].type = (zend_type) ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(by_ref, 0));
|
||||
f.arg_info[i].type = (zend_type) ZEND_TYPE_INIT_NONE(_ZEND_ARG_INFO_FLAGS(by_ref, 0, 0));
|
||||
}
|
||||
|
||||
f.num_args = bindptr.lpfuncdesc->cParams;
|
||||
|
||||
+120
-123
@@ -114,214 +114,211 @@ function date_sunset(
|
||||
|
||||
function date_sun_info(int $timestamp, float $latitude, float $longitude): array {}
|
||||
|
||||
// NB: Adding return types to methods is a BC break!
|
||||
// For now only using @return annotations here.
|
||||
|
||||
interface DateTimeInterface
|
||||
{
|
||||
/** @return string */
|
||||
public function format(string $format);
|
||||
/** @tentative-return-type */
|
||||
public function format(string $format): string;
|
||||
|
||||
/** @return DateTimeZone|false */
|
||||
public function getTimezone();
|
||||
/** @tentative-return-type */
|
||||
public function getTimezone(): DateTimeZone|false;
|
||||
|
||||
/** @return int */
|
||||
public function getOffset();
|
||||
/** @tentative-return-type */
|
||||
public function getOffset(): int;
|
||||
|
||||
/** @return int|false */
|
||||
public function getTimestamp();
|
||||
/** @tentative-return-type */
|
||||
public function getTimestamp(): int|false;
|
||||
|
||||
/** @return DateInterval|false */
|
||||
public function diff(DateTimeInterface $targetObject, bool $absolute = false);
|
||||
/** @tentative-return-type */
|
||||
public function diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval;
|
||||
|
||||
/** @return void */
|
||||
public function __wakeup();
|
||||
/** @tentative-return-type */
|
||||
public function __wakeup(): void;
|
||||
}
|
||||
|
||||
class DateTime implements DateTimeInterface
|
||||
{
|
||||
public function __construct(string $datetime = "now", ?DateTimeZone $timezone = null) {}
|
||||
|
||||
/** @return void */
|
||||
public function __wakeup() {}
|
||||
/** @tentative-return-type */
|
||||
public function __wakeup(): void {}
|
||||
|
||||
/** @return DateTime */
|
||||
public static function __set_state(array $array) {}
|
||||
/** @tentative-return-type */
|
||||
public static function __set_state(array $array): DateTime {}
|
||||
|
||||
/** @return DateTime */
|
||||
public static function createFromImmutable(DateTimeImmutable $object) {}
|
||||
/** @tentative-return-type */
|
||||
public static function createFromImmutable(DateTimeImmutable $object): DateTime {}
|
||||
|
||||
public static function createFromInterface(DateTimeInterface $object): DateTime {}
|
||||
|
||||
/**
|
||||
* @return DateTime|false
|
||||
* @tentative-return-type
|
||||
* @alias date_create_from_format
|
||||
*/
|
||||
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null) {}
|
||||
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTime|false {}
|
||||
|
||||
/**
|
||||
* @return array|false
|
||||
* @tentative-return-type
|
||||
* @alias date_get_last_errors
|
||||
*/
|
||||
public static function getLastErrors() {}
|
||||
public static function getLastErrors(): array|false {}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @tentative-return-type
|
||||
* @alias date_format
|
||||
*/
|
||||
public function format(string $format) {}
|
||||
public function format(string $format): string {}
|
||||
|
||||
/**
|
||||
* @return DateTime|false
|
||||
* @tentative-return-type
|
||||
* @alias date_modify
|
||||
*/
|
||||
public function modify(string $modifier) {}
|
||||
public function modify(string $modifier): DateTime|false {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_add
|
||||
*/
|
||||
public function add(DateInterval $interval) {}
|
||||
public function add(DateInterval $interval): DateTime {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_sub
|
||||
*/
|
||||
public function sub(DateInterval $interval) {}
|
||||
public function sub(DateInterval $interval): DateTime {}
|
||||
|
||||
/**
|
||||
* @return DateTimeZone|false
|
||||
* @tentative-return-type
|
||||
* @alias date_timezone_get
|
||||
*/
|
||||
public function getTimezone() {}
|
||||
public function getTimezone(): DateTimeZone|false {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_timezone_set
|
||||
*/
|
||||
public function setTimezone(DateTimeZone $timezone) {}
|
||||
public function setTimezone(DateTimeZone $timezone): DateTime {}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @tentative-return-type
|
||||
* @alias date_offset_get
|
||||
*/
|
||||
public function getOffset() {}
|
||||
public function getOffset(): int {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_time_set
|
||||
*/
|
||||
public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0) {}
|
||||
public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTime {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_date_set
|
||||
*/
|
||||
public function setDate(int $year, int $month, int $day) {}
|
||||
public function setDate(int $year, int $month, int $day): DateTime {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_isodate_set
|
||||
*/
|
||||
public function setISODate(int $year, int $week, int $dayOfWeek = 1) {}
|
||||
public function setISODate(int $year, int $week, int $dayOfWeek = 1): DateTime {}
|
||||
|
||||
/**
|
||||
* @return DateTime
|
||||
* @tentative-return-type
|
||||
* @alias date_timestamp_set
|
||||
*/
|
||||
public function setTimestamp(int $timestamp) {}
|
||||
public function setTimestamp(int $timestamp): DateTime {}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @tentative-return-type
|
||||
* @alias date_timestamp_get
|
||||
*/
|
||||
public function getTimestamp() {}
|
||||
public function getTimestamp(): int {}
|
||||
|
||||
/**
|
||||
* @return DateInterval
|
||||
* @tentative-return-type
|
||||
* @alias date_diff
|
||||
*/
|
||||
public function diff(DateTimeInterface $targetObject, bool $absolute = false) {}
|
||||
public function diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval {}
|
||||
}
|
||||
|
||||
class DateTimeImmutable implements DateTimeInterface
|
||||
{
|
||||
public function __construct(string $datetime = "now", ?DateTimeZone $timezone = null) {}
|
||||
|
||||
/** @return void */
|
||||
public function __wakeup() {}
|
||||
/** @tentative-return-type */
|
||||
public function __wakeup(): void {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public static function __set_state(array $array) {}
|
||||
/** @tentative-return-type */
|
||||
public static function __set_state(array $array): DateTimeImmutable {}
|
||||
|
||||
/**
|
||||
* @return DateTimeImmutable|false
|
||||
* @tentative-return-type
|
||||
* @alias date_create_immutable_from_format
|
||||
*/
|
||||
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null) {}
|
||||
public static function createFromFormat(string $format, string $datetime, ?DateTimeZone $timezone = null): DateTimeImmutable|false {}
|
||||
|
||||
/**
|
||||
* @return array|false
|
||||
* @tentative-return-type
|
||||
* @alias date_get_last_errors
|
||||
*/
|
||||
public static function getLastErrors() {}
|
||||
public static function getLastErrors(): array|false {}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @tentative-return-type
|
||||
* @alias date_format
|
||||
*/
|
||||
public function format(string $format) {}
|
||||
public function format(string $format): string {}
|
||||
|
||||
/**
|
||||
* @return DateTimeZone|false
|
||||
* @tentative-return-type
|
||||
* @alias date_timezone_get
|
||||
*/
|
||||
public function getTimezone() {}
|
||||
public function getTimezone(): DateTimeZone|false {}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @tentative-return-type
|
||||
* @alias date_offset_get
|
||||
*/
|
||||
public function getOffset() {}
|
||||
public function getOffset(): int {}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @tentative-return-type
|
||||
* @alias date_timestamp_get
|
||||
*/
|
||||
public function getTimestamp() {}
|
||||
public function getTimestamp(): int {}
|
||||
|
||||
/**
|
||||
* @return DateInterval
|
||||
* @tentative-return-type
|
||||
* @alias date_diff
|
||||
*/
|
||||
public function diff(DateTimeInterface $targetObject, bool $absolute = false) {}
|
||||
public function diff(DateTimeInterface $targetObject, bool $absolute = false): DateInterval {}
|
||||
|
||||
/** @return DateTimeImmutable|false */
|
||||
public function modify(string $modifier) {}
|
||||
/** @tentative-return-type */
|
||||
public function modify(string $modifier): DateTimeImmutable|false {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function add(DateInterval $interval) {}
|
||||
/** @tentative-return-type */
|
||||
public function add(DateInterval $interval): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function sub(DateInterval $interval) {}
|
||||
/** @tentative-return-type */
|
||||
public function sub(DateInterval $interval): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function setTimezone(DateTimeZone $timezone) {}
|
||||
/** @tentative-return-type */
|
||||
public function setTimezone(DateTimeZone $timezone): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0) {}
|
||||
/** @tentative-return-type */
|
||||
public function setTime(int $hour, int $minute, int $second = 0, int $microsecond = 0): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function setDate(int $year, int $month, int $day) {}
|
||||
/** @tentative-return-type */
|
||||
public function setDate(int $year, int $month, int $day): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function setISODate(int $year, int $week, int $dayOfWeek = 1) {}
|
||||
/** @tentative-return-type */
|
||||
public function setISODate(int $year, int $week, int $dayOfWeek = 1): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public function setTimestamp(int $timestamp) {}
|
||||
/** @tentative-return-type */
|
||||
public function setTimestamp(int $timestamp): DateTimeImmutable {}
|
||||
|
||||
/** @return DateTimeImmutable */
|
||||
public static function createFromMutable(DateTime $object) {}
|
||||
/** @tentative-return-type */
|
||||
public static function createFromMutable(DateTime $object): DateTimeImmutable {}
|
||||
|
||||
public static function createFromInterface(DateTimeInterface $object): DateTimeImmutable {}
|
||||
}
|
||||
@@ -331,46 +328,46 @@ class DateTimeZone
|
||||
public function __construct(string $timezone) {}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @tentative-return-type
|
||||
* @alias timezone_name_get
|
||||
*/
|
||||
public function getName() {}
|
||||
public function getName(): string {}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @tentative-return-type
|
||||
* @alias timezone_offset_get
|
||||
*/
|
||||
public function getOffset(DateTimeInterface $datetime) {}
|
||||
public function getOffset(DateTimeInterface $datetime): int {}
|
||||
|
||||
/**
|
||||
* @return array|false
|
||||
* @tentative-return-type
|
||||
* @alias timezone_transitions_get
|
||||
*/
|
||||
public function getTransitions(int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX) {}
|
||||
public function getTransitions(int $timestampBegin = PHP_INT_MIN, int $timestampEnd = PHP_INT_MAX): array|false {}
|
||||
|
||||
/**
|
||||
* @return array|false
|
||||
* @tentative-return-type
|
||||
* @alias timezone_location_get
|
||||
*/
|
||||
public function getLocation() {}
|
||||
public function getLocation(): array|false {}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @tentative-return-type
|
||||
* @alias timezone_abbreviations_list
|
||||
*/
|
||||
public static function listAbbreviations() {}
|
||||
public static function listAbbreviations(): array {}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @tentative-return-type
|
||||
* @alias timezone_identifiers_list
|
||||
*/
|
||||
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null) {}
|
||||
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array {}
|
||||
|
||||
/** @return void */
|
||||
public function __wakeup() {}
|
||||
/** @tentative-return-type */
|
||||
public function __wakeup(): void {}
|
||||
|
||||
/** @return DateTimeZone */
|
||||
public static function __set_state(array $array) {}
|
||||
/** @tentative-return-type */
|
||||
public static function __set_state(array $array): DateTimeZone {}
|
||||
}
|
||||
|
||||
class DateInterval
|
||||
@@ -378,22 +375,22 @@ class DateInterval
|
||||
public function __construct(string $duration) {}
|
||||
|
||||
/**
|
||||
* @return DateInterval|false
|
||||
* @tentative-return-type
|
||||
* @alias date_interval_create_from_date_string
|
||||
*/
|
||||
public static function createFromDateString(string $datetime) {}
|
||||
public static function createFromDateString(string $datetime): DateInterval|false {}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @tentative-return-type
|
||||
* @alias date_interval_format
|
||||
*/
|
||||
public function format(string $format) {}
|
||||
public function format(string $format): string {}
|
||||
|
||||
/** @return void */
|
||||
public function __wakeup() {}
|
||||
/** @tentative-return-type */
|
||||
public function __wakeup(): void {}
|
||||
|
||||
/** @return DateInterval */
|
||||
public static function __set_state(array $array) {}
|
||||
/** @tentative-return-type */
|
||||
public static function __set_state(array $array): DateInterval {}
|
||||
}
|
||||
|
||||
class DatePeriod implements IteratorAggregate
|
||||
@@ -406,23 +403,23 @@ class DatePeriod implements IteratorAggregate
|
||||
*/
|
||||
public function __construct($start, $interval = UNKNOWN, $end = UNKNOWN, $options = UNKNOWN) {}
|
||||
|
||||
/** @return DateTimeInterface */
|
||||
public function getStartDate() {}
|
||||
/** @tentative-return-type */
|
||||
public function getStartDate(): DateTimeInterface {}
|
||||
|
||||
/** @return DateTimeInterface|null */
|
||||
public function getEndDate() {}
|
||||
/** @tentative-return-type */
|
||||
public function getEndDate(): ?DateTimeInterface {}
|
||||
|
||||
/** @return DateInterval */
|
||||
public function getDateInterval() {}
|
||||
/** @tentative-return-type */
|
||||
public function getDateInterval(): DateInterval {}
|
||||
|
||||
/** @return int|null */
|
||||
public function getRecurrences() {}
|
||||
/** @tentative-return-type */
|
||||
public function getRecurrences(): ?int {}
|
||||
|
||||
/** @return void */
|
||||
public function __wakeup() {}
|
||||
/** @tentative-return-type */
|
||||
public function __wakeup(): void {}
|
||||
|
||||
/** @return DatePeriod */
|
||||
public static function __set_state(array $array) {}
|
||||
/** @tentative-return-type */
|
||||
public static function __set_state(array $array): DatePeriod {}
|
||||
|
||||
public function getIterator(): Iterator {}
|
||||
}
|
||||
+96
-53
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 108136459e578cc699cffcb84d3335a11f8d5c9d */
|
||||
* Stub hash: e8bc76a5db3a225746daffe29c0b8404cf971452 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0)
|
||||
@@ -225,36 +225,39 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_date_sun_info, 0, 3, IS_ARRAY, 0
|
||||
ZEND_ARG_TYPE_INFO(0, longitude, IS_DOUBLE, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeInterface_format, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeInterface_format, 0, 1, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeInterface_getTimezone, 0, 0, 0)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeInterface_getTimezone, 0, 0, DateTimeZone, MAY_BE_FALSE)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeInterface_getOffset arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeInterface_getOffset, 0, 0, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeInterface_getTimestamp arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DateTimeInterface_getTimestamp, 0, 0, MAY_BE_LONG|MAY_BE_FALSE)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeInterface_diff, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeInterface_diff, 0, 1, DateInterval, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, targetObject, DateTimeInterface, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, absolute, _IS_BOOL, 0, "false")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeInterface___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeInterface___wakeup, 0, 0, IS_VOID, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime___construct, 0, 0, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, datetime, IS_STRING, 0, "\"now\"")
|
||||
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTime___wakeup arginfo_class_DateTimeInterface___wakeup
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime___set_state, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime___set_state, 0, 1, DateTime, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_createFromImmutable, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_createFromImmutable, 0, 1, DateTime, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, object, DateTimeImmutable, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@@ -262,21 +265,22 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_createFromInterfac
|
||||
ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_createFromFormat, 0, 0, 2)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTime_createFromFormat, 0, 2, DateTime, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_getLastErrors arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DateTime_getLastErrors, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_format arginfo_class_DateTimeInterface_format
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_modify, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTime_modify, 0, 1, DateTime, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, modifier, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_add, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_add, 0, 1, DateTime, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, interval, DateInterval, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@@ -284,76 +288,103 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_getTimezone arginfo_class_DateTimeInterface_getTimezone
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTimezone, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setTimezone, 0, 1, DateTime, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_getOffset arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTime_getOffset arginfo_class_DateTimeInterface_getOffset
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTime, 0, 0, 2)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setTime, 0, 2, DateTime, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, hour, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, minute, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, second, IS_LONG, 0, "0")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, microsecond, IS_LONG, 0, "0")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setDate, 0, 0, 3)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setDate, 0, 3, DateTime, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, year, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, month, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, day, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setISODate, 0, 0, 2)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setISODate, 0, 2, DateTime, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, year, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, week, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dayOfWeek, IS_LONG, 0, "1")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTimestamp, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTime_setTimestamp, 0, 1, DateTime, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_getTimestamp arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTime_getTimestamp arginfo_class_DateTimeInterface_getOffset
|
||||
|
||||
#define arginfo_class_DateTime_diff arginfo_class_DateTimeInterface_diff
|
||||
|
||||
#define arginfo_class_DateTimeImmutable___construct arginfo_class_DateTime___construct
|
||||
|
||||
#define arginfo_class_DateTimeImmutable___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTimeImmutable___wakeup arginfo_class_DateTimeInterface___wakeup
|
||||
|
||||
#define arginfo_class_DateTimeImmutable___set_state arginfo_class_DateTime___set_state
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable___set_state, 0, 1, DateTimeImmutable, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_createFromFormat arginfo_class_DateTime_createFromFormat
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmutable_createFromFormat, 0, 2, DateTimeImmutable, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timezone, DateTimeZone, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTime_getLastErrors
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_format arginfo_class_DateTimeInterface_format
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_getTimezone arginfo_class_DateTimeInterface_getTimezone
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_getOffset arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTimeImmutable_getOffset arginfo_class_DateTimeInterface_getOffset
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_getTimestamp arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTimeImmutable_getTimestamp arginfo_class_DateTimeInterface_getOffset
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_diff arginfo_class_DateTimeInterface_diff
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_modify arginfo_class_DateTime_modify
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateTimeImmutable_modify, 0, 1, DateTimeImmutable, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, modifier, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_add arginfo_class_DateTime_add
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_add, 0, 1, DateTimeImmutable, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, interval, DateInterval, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_sub arginfo_class_DateTime_add
|
||||
#define arginfo_class_DateTimeImmutable_sub arginfo_class_DateTimeImmutable_add
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_setTimezone arginfo_class_DateTime_setTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_setTimezone, 0, 1, DateTimeImmutable, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_setTime arginfo_class_DateTime_setTime
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_setTime, 0, 2, DateTimeImmutable, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, hour, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, minute, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, second, IS_LONG, 0, "0")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, microsecond, IS_LONG, 0, "0")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_setDate arginfo_class_DateTime_setDate
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_setDate, 0, 3, DateTimeImmutable, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, year, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, month, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, day, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_setISODate arginfo_class_DateTime_setISODate
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_setISODate, 0, 2, DateTimeImmutable, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, year, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, week, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, dayOfWeek, IS_LONG, 0, "1")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_setTimestamp arginfo_class_DateTime_setTimestamp
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_setTimestamp, 0, 1, DateTimeImmutable, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 1, DateTimeImmutable, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@@ -365,43 +396,49 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeZone___construct, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, timezone, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeZone_getName arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeZone_getName, 0, 0, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeZone_getOffset, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeZone_getOffset, 0, 1, IS_LONG, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, datetime, DateTimeInterface, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeZone_getTransitions, 0, 0, 0)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_MASK_EX(arginfo_class_DateTimeZone_getTransitions, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestampBegin, IS_LONG, 0, "PHP_INT_MIN")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timestampEnd, IS_LONG, 0, "PHP_INT_MAX")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeZone_getLocation arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTimeZone_getLocation arginfo_class_DateTime_getLastErrors
|
||||
|
||||
#define arginfo_class_DateTimeZone_listAbbreviations arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeZone_listAbbreviations, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeZone_listIdentifiers, 0, 0, 0)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DateTimeZone_listIdentifiers, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timezoneGroup, IS_LONG, 0, "DateTimeZone::ALL")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, countryCode, IS_STRING, 1, "null")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeZone___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateTimeZone___wakeup arginfo_class_DateTimeInterface___wakeup
|
||||
|
||||
#define arginfo_class_DateTimeZone___set_state arginfo_class_DateTime___set_state
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateTimeZone___set_state, 0, 1, DateTimeZone, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateInterval___construct, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, duration, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateInterval_createFromDateString, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_TYPE_MASK_EX(arginfo_class_DateInterval_createFromDateString, 0, 1, DateInterval, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateInterval_format arginfo_class_DateTimeInterface_format
|
||||
|
||||
#define arginfo_class_DateInterval___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DateInterval___wakeup arginfo_class_DateTimeInterface___wakeup
|
||||
|
||||
#define arginfo_class_DateInterval___set_state arginfo_class_DateTime___set_state
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DateInterval___set_state, 0, 1, DateInterval, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DatePeriod___construct, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, start)
|
||||
@@ -410,17 +447,23 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DatePeriod___construct, 0, 0, 1)
|
||||
ZEND_ARG_INFO(0, options)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DatePeriod_getStartDate arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DatePeriod_getStartDate, 0, 0, DateTimeInterface, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DatePeriod_getEndDate arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DatePeriod_getEndDate, 0, 0, DateTimeInterface, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DatePeriod_getDateInterval arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DatePeriod_getDateInterval, 0, 0, DateInterval, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DatePeriod_getRecurrences arginfo_class_DateTimeInterface_getTimezone
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_DatePeriod_getRecurrences, 0, 0, IS_LONG, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DatePeriod___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
#define arginfo_class_DatePeriod___wakeup arginfo_class_DateTimeInterface___wakeup
|
||||
|
||||
#define arginfo_class_DatePeriod___set_state arginfo_class_DateTime___set_state
|
||||
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_DatePeriod___set_state, 0, 1, DatePeriod, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_DatePeriod_getIterator, 0, 0, Iterator, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
@@ -9,7 +9,7 @@ echo "*** Testing new DateTime() : with user format() method ***\n";
|
||||
|
||||
class DateTimeExt extends DateTime
|
||||
{
|
||||
public function format($format = "F j, Y, g:i:s a")
|
||||
public function format($format = "F j, Y, g:i:s a"): string
|
||||
{
|
||||
return parent::format($format);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ error_reporting=-1
|
||||
<?php namespace melt\core;
|
||||
|
||||
class DateTime extends \DateTime {
|
||||
public static function createFromFormat($format, $time, \DateTimeZone $timezone = null) {
|
||||
public static function createFromFormat($format, $time, \DateTimeZone $timezone = null): DateTime|false {
|
||||
return new DateTime(parent::createFromFormat($format, $time, $timezone));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ $s2 = 'O:3:"Foo":3:{s:4:"date";s:20:"10007-06-07 03:51:49";s:13:"timezone_type";
|
||||
global $foo;
|
||||
|
||||
class Foo extends DateTime {
|
||||
function __wakeup() {
|
||||
function __wakeup(): void {
|
||||
global $foo;
|
||||
$foo = $this;
|
||||
parent::__wakeup();
|
||||
|
||||
@@ -9,7 +9,7 @@ $s2 = 'O:3:"Foo":3:{s:4:"date";s:19:"0000-00-00 00:00:00";s:13:"timezone_type";i
|
||||
global $foo;
|
||||
|
||||
class Foo extends DateTime {
|
||||
function __wakeup() {
|
||||
function __wakeup(): void {
|
||||
global $foo;
|
||||
$foo = $this;
|
||||
parent::__wakeup();
|
||||
|
||||
@@ -849,8 +849,8 @@ static void _function_string(smart_str *str, zend_function *fptr, zend_class_ent
|
||||
}
|
||||
_function_parameter_string(str, fptr, ZSTR_VAL(param_indent.s));
|
||||
smart_str_free(¶m_indent);
|
||||
if (fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) {
|
||||
smart_str_append_printf(str, " %s- Return [ ", indent);
|
||||
if ((fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
|
||||
smart_str_append_printf(str, " %s- %s [ ", indent, ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]) ? "Tentative return" : "Return");
|
||||
if (ZEND_TYPE_IS_SET(fptr->common.arg_info[-1].type)) {
|
||||
zend_string *type_str = zend_type_to_string(fptr->common.arg_info[-1].type);
|
||||
smart_str_append_printf(str, "%s ", ZSTR_VAL(type_str));
|
||||
@@ -3449,7 +3449,7 @@ ZEND_METHOD(ReflectionFunctionAbstract, hasReturnType)
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(fptr);
|
||||
|
||||
RETVAL_BOOL(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE);
|
||||
RETVAL_BOOL((fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) && !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@@ -3465,7 +3465,43 @@ ZEND_METHOD(ReflectionFunctionAbstract, getReturnType)
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(fptr);
|
||||
|
||||
if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
|
||||
if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
reflection_type_factory(fptr->common.arg_info[-1].type, return_value, 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Return whether the function has a return type */
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, hasTentativeReturnType)
|
||||
{
|
||||
reflection_object *intern;
|
||||
zend_function *fptr;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(fptr);
|
||||
|
||||
RETVAL_BOOL(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE && ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1]));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ Returns the return type associated with the function */
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType)
|
||||
{
|
||||
reflection_object *intern;
|
||||
zend_function *fptr;
|
||||
|
||||
if (zend_parse_parameters_none() == FAILURE) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
GET_REFLECTION_OBJECT_PTR(fptr);
|
||||
|
||||
if (!(fptr->op_array.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || !ZEND_ARG_TYPE_IS_TENTATIVE(&fptr->common.arg_info[-1])) {
|
||||
RETURN_NULL();
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,10 @@ abstract class ReflectionFunctionAbstract implements Reflector
|
||||
/** @return ReflectionType|null */
|
||||
public function getReturnType() {}
|
||||
|
||||
public function hasTentativeReturnType(): bool {}
|
||||
|
||||
public function getTentativeReturnType(): ?ReflectionType {}
|
||||
|
||||
/** @return ReflectionAttribute[] */
|
||||
public function getAttributes(?string $name = null, int $flags = 0): array {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: 47ac64b027cdeb0e9996147277f79fa9d6b876bd */
|
||||
* Stub hash: 0b2b52d4f891a594ccfcbcc0edeec97a9e0f80e6 */
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0)
|
||||
@@ -59,6 +59,12 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionFunctionAbstract_getReturnType arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType, 0, 0, _IS_BOOL, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionFunctionAbstract_getTentativeReturnType, 0, 0, ReflectionType, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionFunctionAbstract_getAttributes, 0, 0, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, name, IS_STRING, 1, "null")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0")
|
||||
@@ -218,8 +224,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionClass_isTrait arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionClass_isEnum, 0, 0, _IS_BOOL, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
#define arginfo_class_ReflectionClass_isEnum arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionClass_isAbstract arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
@@ -311,7 +316,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionProperty_isDefault arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
#define arginfo_class_ReflectionProperty_isPromoted arginfo_class_ReflectionClass_isEnum
|
||||
#define arginfo_class_ReflectionProperty_isPromoted arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionProperty_getModifiers arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
@@ -325,7 +330,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionProperty_hasType arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
#define arginfo_class_ReflectionProperty_hasDefaultValue arginfo_class_ReflectionClass_isEnum
|
||||
#define arginfo_class_ReflectionProperty_hasDefaultValue arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionProperty_getDefaultValue arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
@@ -358,7 +363,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionClassConstant_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes
|
||||
|
||||
#define arginfo_class_ReflectionClassConstant_isEnumCase arginfo_class_ReflectionClass_isEnum
|
||||
#define arginfo_class_ReflectionClassConstant_isEnumCase arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionParameter___clone arginfo_class_ReflectionFunctionAbstract___clone
|
||||
|
||||
@@ -405,7 +410,7 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionParameter_isVariadic arginfo_class_ReflectionFunctionAbstract_inNamespace
|
||||
|
||||
#define arginfo_class_ReflectionParameter_isPromoted arginfo_class_ReflectionClass_isEnum
|
||||
#define arginfo_class_ReflectionParameter_isPromoted arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionParameter_getAttributes arginfo_class_ReflectionFunctionAbstract_getAttributes
|
||||
|
||||
@@ -482,7 +487,7 @@ ZEND_END_ARG_INFO()
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionAttribute_getTarget, 0, 0, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionAttribute_isRepeated arginfo_class_ReflectionClass_isEnum
|
||||
#define arginfo_class_ReflectionAttribute_isRepeated arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionAttribute_getArguments arginfo_class_ReflectionUnionType_getTypes
|
||||
|
||||
@@ -505,10 +510,9 @@ ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_ReflectionEnum_getCases arginfo_class_ReflectionUnionType_getTypes
|
||||
|
||||
#define arginfo_class_ReflectionEnum_isBacked arginfo_class_ReflectionClass_isEnum
|
||||
#define arginfo_class_ReflectionEnum_isBacked arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionEnum_getBackingType, 0, 0, ReflectionType, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
#define arginfo_class_ReflectionEnum_getBackingType arginfo_class_ReflectionFunctionAbstract_getTentativeReturnType
|
||||
|
||||
#define arginfo_class_ReflectionEnumUnitCase___construct arginfo_class_ReflectionClassConstant___construct
|
||||
|
||||
@@ -569,6 +573,8 @@ ZEND_METHOD(ReflectionFunctionAbstract, getStaticVariables);
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, returnsReference);
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, hasReturnType);
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, getReturnType);
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, hasTentativeReturnType);
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, getTentativeReturnType);
|
||||
ZEND_METHOD(ReflectionFunctionAbstract, getAttributes);
|
||||
ZEND_METHOD(ReflectionFunction, __construct);
|
||||
ZEND_METHOD(ReflectionFunction, __toString);
|
||||
@@ -805,6 +811,8 @@ static const zend_function_entry class_ReflectionFunctionAbstract_methods[] = {
|
||||
ZEND_ME(ReflectionFunctionAbstract, returnsReference, arginfo_class_ReflectionFunctionAbstract_returnsReference, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFunctionAbstract, hasReturnType, arginfo_class_ReflectionFunctionAbstract_hasReturnType, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFunctionAbstract, getReturnType, arginfo_class_ReflectionFunctionAbstract_getReturnType, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFunctionAbstract, hasTentativeReturnType, arginfo_class_ReflectionFunctionAbstract_hasTentativeReturnType, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFunctionAbstract, getTentativeReturnType, arginfo_class_ReflectionFunctionAbstract_getTentativeReturnType, ZEND_ACC_PUBLIC)
|
||||
ZEND_ME(ReflectionFunctionAbstract, getAttributes, arginfo_class_ReflectionFunctionAbstract_getAttributes, ZEND_ACC_PUBLIC)
|
||||
ZEND_FE_END
|
||||
};
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
--TEST--
|
||||
ReflectionMethod returns tentative return type information correctly
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class MyDateTimeZone extends DateTimeZone
|
||||
{
|
||||
#[ReturnTypeWillChange]
|
||||
public static function listIdentifiers(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): string
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
$methodInfo = new ReflectionMethod(DateTimeZone::class, 'listIdentifiers');
|
||||
|
||||
var_dump($methodInfo->hasReturnType());
|
||||
var_dump($methodInfo->hasTentativeReturnType());
|
||||
var_dump($methodInfo->getReturnType());
|
||||
var_dump((string) $methodInfo->getTentativeReturnType());
|
||||
var_dump((string) $methodInfo);
|
||||
echo "\n";
|
||||
|
||||
$methodInfo = new ReflectionMethod(MyDateTimeZone::class, 'listIdentifiers');
|
||||
|
||||
var_dump($methodInfo->hasReturnType());
|
||||
var_dump($methodInfo->hasTentativeReturnType());
|
||||
var_dump((string) $methodInfo->getReturnType());
|
||||
var_dump($methodInfo->getTentativeReturnType());
|
||||
var_dump((string) $methodInfo);
|
||||
echo "\n";
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
bool(false)
|
||||
bool(true)
|
||||
NULL
|
||||
string(5) "array"
|
||||
string(%d) "Method [ <internal:date> static public method listIdentifiers ] {
|
||||
|
||||
- Parameters [2] {
|
||||
Parameter #0 [ <optional> int $timezoneGroup = DateTimeZone::ALL ]
|
||||
Parameter #1 [ <optional> ?string $countryCode = null ]
|
||||
}
|
||||
- Tentative return [ array ]
|
||||
}
|
||||
"
|
||||
|
||||
bool(true)
|
||||
bool(false)
|
||||
string(6) "string"
|
||||
NULL
|
||||
string(%d) "Method [ <user, overwrites DateTimeZone, prototype DateTimeZone> static public method listIdentifiers ] {
|
||||
@@ %s
|
||||
|
||||
- Parameters [2] {
|
||||
Parameter #0 [ <optional> int $timezoneGroup = %d ]
|
||||
Parameter #1 [ <optional> ?string $countryCode = NULL ]
|
||||
}
|
||||
- Return [ string ]
|
||||
}
|
||||
"
|
||||
Reference in new issue
Block a user