mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Support single class unions in gen stubs
This commit is contained in:
parent
468ecf295d
commit
0cec268d15
7 changed files with 112 additions and 57 deletions
|
@ -128,6 +128,10 @@ typedef struct _zend_fcall_info_cache {
|
|||
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)) },
|
||||
|
||||
#define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, 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)) },
|
||||
|
||||
#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)) },
|
||||
|
|
|
@ -12,6 +12,9 @@ Class Closure
|
|||
|
||||
function call(object $newthis, ...$parameters) {}
|
||||
|
||||
/** @return Closure */
|
||||
function fromCallable(callable $callable) {}
|
||||
/**
|
||||
* @param callable $callable Not a proper type annotation due to bug #78770
|
||||
* @return Closure
|
||||
*/
|
||||
function fromCallable($callable) {}
|
||||
}
|
||||
|
|
|
@ -269,6 +269,9 @@ typedef struct {
|
|||
{ (void *) (ptr), \
|
||||
(type_kind) | ((allow_null) ? _ZEND_TYPE_NULLABLE_BIT : 0) | (extra_flags) }
|
||||
|
||||
#define ZEND_TYPE_INIT_PTR_MASK(ptr, type_mask) \
|
||||
{ (void *) (ptr), (type_mask) }
|
||||
|
||||
#define ZEND_TYPE_INIT_CE(_ce, allow_null, extra_flags) \
|
||||
ZEND_TYPE_INIT_PTR(_ce, _ZEND_TYPE_CE_BIT, allow_null, extra_flags)
|
||||
|
||||
|
@ -278,6 +281,9 @@ typedef struct {
|
|||
#define ZEND_TYPE_INIT_CLASS_CONST(class_name, allow_null, extra_flags) \
|
||||
ZEND_TYPE_INIT_PTR(class_name, _ZEND_TYPE_NAME_BIT, allow_null, extra_flags)
|
||||
|
||||
#define ZEND_TYPE_INIT_CLASS_CONST_MASK(class_name, type_mask) \
|
||||
ZEND_TYPE_INIT_PTR_MASK(class_name, _ZEND_TYPE_NAME_BIT | (type_mask))
|
||||
|
||||
typedef union _zend_value {
|
||||
zend_long lval; /* long value */
|
||||
double dval; /* double value */
|
||||
|
|
|
@ -93,9 +93,9 @@ static const zend_function_entry date_functions[] = {
|
|||
|
||||
/* Advanced Interface */
|
||||
PHP_FE(date_create, arginfo_date_create)
|
||||
PHP_FE(date_create_immutable, arginfo_date_create)
|
||||
PHP_FE(date_create_immutable, arginfo_date_create_immutable)
|
||||
PHP_FE(date_create_from_format, arginfo_date_create_from_format)
|
||||
PHP_FE(date_create_immutable_from_format, arginfo_date_create_from_format)
|
||||
PHP_FE(date_create_immutable_from_format, arginfo_date_create_immutable_from_format)
|
||||
PHP_FE(date_parse, arginfo_date_parse)
|
||||
PHP_FE(date_parse_from_format, arginfo_date_parse_from_format)
|
||||
PHP_FE(date_get_last_errors, arginfo_date_get_last_errors)
|
||||
|
|
|
@ -31,18 +31,16 @@ function localtime(int $timestamp = UNKNOWN, bool $associative = false): array {
|
|||
|
||||
function getdate(int $timestamp = UNKNOWN): array {}
|
||||
|
||||
/** @return DateTime|false */
|
||||
function date_create(string $time = "now", ?DateTimeZone $timezone = null) {}
|
||||
function date_create(string $time = "now", ?DateTimeZone $timezone = null): DateTime|false {}
|
||||
|
||||
/** @return DateTime|false */
|
||||
function date_create_immutable(string $time = "now", ?DateTimeZone $timezone = null) {}
|
||||
function date_create_immutable(
|
||||
string $time = "now", ?DateTimeZone $timezone = null): DateTimeImmutable|false {}
|
||||
|
||||
/** @return DateTime|false */
|
||||
function date_create_from_format(string $format, string $time, ?DateTimeZone $timezone = null) {}
|
||||
function date_create_from_format(
|
||||
string $format, string $time, ?DateTimeZone $timezone = null): DateTime|false {}
|
||||
|
||||
/** @return DateTimeImmutable|false */
|
||||
function date_create_immutable_from_format(
|
||||
string $format, string $time, ?DateTimeZone $timezone = null) {}
|
||||
string $format, string $time, ?DateTimeZone $timezone = null): DateTimeImmutable|false {}
|
||||
|
||||
function date_parse(string $date): array {}
|
||||
|
||||
|
@ -52,15 +50,13 @@ function date_get_last_errors(): array|false {}
|
|||
|
||||
function date_format(DateTimeInterface $object, string $format): string {}
|
||||
|
||||
/** @return DateTime|false */
|
||||
function date_modify(DateTime $object, string $modify) {}
|
||||
function date_modify(DateTime $object, string $modify): DateTime|false {}
|
||||
|
||||
function date_add(DateTime $object, DateInterval $interval): DateTime {}
|
||||
|
||||
function date_sub(DateTime $object, DateInterval $interval): DateTime {}
|
||||
|
||||
/** @return DateTimeZone|false */
|
||||
function date_timezone_get(DateTimeInterface $object) {}
|
||||
function date_timezone_get(DateTimeInterface $object): DateTimeZone|false {}
|
||||
|
||||
function date_timezone_set(DateTimeInterface $object, DateTimeZone $timezone): DateTime {}
|
||||
|
||||
|
@ -80,8 +76,7 @@ function date_timestamp_set(DateTime $object, int $timestamp): DateTime {}
|
|||
|
||||
function date_timestamp_get(DateTimeInterface $object): int|false {}
|
||||
|
||||
/** @return DateTimeZone|false */
|
||||
function timezone_open(string $timezone) {}
|
||||
function timezone_open(string $timezone): DateTimeZone|false {}
|
||||
|
||||
function timezone_name_get(DateTimeZone $object): string {}
|
||||
|
||||
|
@ -100,8 +95,7 @@ function timezone_abbreviations_list(): array {}
|
|||
|
||||
function timezone_version_get(): string {}
|
||||
|
||||
/** @return DateInterval|false */
|
||||
function date_interval_create_from_date_string(string $time) {}
|
||||
function date_interval_create_from_date_string(string $time): DateInterval|false {}
|
||||
|
||||
function date_interval_format(DateInterval $object, string $format): string {}
|
||||
|
||||
|
|
|
@ -53,20 +53,27 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_getdate, 0, 0, IS_ARRAY, 0)
|
|||
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_date_create, 0, 0, 0)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create, 0, 0, DateTime, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_date_create_immutable arginfo_date_create
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable, 0, 0, DateTimeImmutable, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_date_create_from_format, 0, 0, 2)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_from_format, 0, 2, DateTime, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_date_create_immutable_from_format arginfo_date_create_from_format
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_create_immutable_from_format, 0, 2, DateTimeImmutable, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_date_parse, 0, 1, IS_ARRAY, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, date, IS_STRING, 0)
|
||||
|
@ -85,7 +92,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_date_format, 0, 2, IS_STRING, 0)
|
|||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_date_modify, 0, 0, 2)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_modify, 0, 2, DateTime, MAY_BE_FALSE)
|
||||
ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, modify, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
@ -97,7 +104,7 @@ ZEND_END_ARG_INFO()
|
|||
|
||||
#define arginfo_date_sub arginfo_date_add
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_date_timezone_get, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_timezone_get, 0, 1, DateTimeZone, MAY_BE_FALSE)
|
||||
ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
@ -147,7 +154,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_date_timestamp_get, 0, 1, MAY_BE
|
|||
ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_timezone_open, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_timezone_open, 0, 1, DateTimeZone, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, timezone, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
@ -187,7 +194,7 @@ ZEND_END_ARG_INFO()
|
|||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_timezone_version_get, 0, 0, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_date_interval_create_from_date_string, 0, 0, 1)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_date_interval_create_from_date_string, 0, 1, DateInterval, MAY_BE_FALSE)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
|
@ -237,7 +244,10 @@ ZEND_END_ARG_INFO()
|
|||
|
||||
#define arginfo_class_DateTimeInterface___wakeup arginfo_class_DateTimeInterface_getTimezone
|
||||
|
||||
#define arginfo_class_DateTime___construct arginfo_date_create
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime___construct, 0, 0, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime___set_state, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0)
|
||||
|
@ -247,7 +257,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_createFromImmutable, 0, 0, 1)
|
|||
ZEND_ARG_OBJ_INFO(0, object, DateTimeImmutable, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_createFromFormat arginfo_date_create_from_format
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_createFromFormat, 0, 0, 2)
|
||||
ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_ARG_OBJ_INFO(0, timezone, DateTimeZone, 1)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTime_getLastErrors arginfo_class_DateTimeInterface_getTimezone
|
||||
|
||||
|
@ -288,7 +302,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTime_setTimestamp, 0, 0, 1)
|
|||
ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable___construct arginfo_date_create
|
||||
#define arginfo_class_DateTimeImmutable___construct arginfo_class_DateTime___construct
|
||||
|
||||
#define arginfo_class_DateTimeImmutable___set_state arginfo_class_DateTime___set_state
|
||||
|
||||
|
@ -296,7 +310,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateTimeImmutable_createFromMutable, 0, 0,
|
|||
ZEND_ARG_OBJ_INFO(0, object, DateTime, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_createFromFormat arginfo_date_create_from_format
|
||||
#define arginfo_class_DateTimeImmutable_createFromFormat arginfo_class_DateTime_createFromFormat
|
||||
|
||||
#define arginfo_class_DateTimeImmutable_getLastErrors arginfo_class_DateTimeInterface_getTimezone
|
||||
|
||||
|
@ -316,7 +330,9 @@ ZEND_END_ARG_INFO()
|
|||
|
||||
#define arginfo_class_DateTimeImmutable_setTimestamp arginfo_class_DateTime_setTimestamp
|
||||
|
||||
#define arginfo_class_DateTimeZone___construct arginfo_timezone_open
|
||||
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
|
||||
|
||||
|
@ -346,7 +362,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateInterval___construct, 0, 0, 1)
|
|||
ZEND_ARG_TYPE_INFO(0, interval_spec, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateInterval_createFromDateString arginfo_date_interval_create_from_date_string
|
||||
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DateInterval_createFromDateString, 0, 0, 1)
|
||||
ZEND_ARG_TYPE_INFO(0, time, IS_STRING, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_class_DateInterval_format arginfo_class_DateTimeInterface_format
|
||||
|
||||
|
|
|
@ -131,6 +131,10 @@ class SimpleType {
|
|||
}
|
||||
}
|
||||
|
||||
public function toEscapedName(): string {
|
||||
return str_replace('\\', '\\\\', $this->name);
|
||||
}
|
||||
|
||||
public function equals(SimpleType $other) {
|
||||
return $this->name === $other->name
|
||||
&& $this->isBuiltin === $other->isBuiltin;
|
||||
|
@ -167,15 +171,6 @@ class Type {
|
|||
return false;
|
||||
}
|
||||
|
||||
public function isBuiltinOnly(): bool {
|
||||
foreach ($this->types as $type) {
|
||||
if (!$type->isBuiltin) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getWithoutNull(): Type {
|
||||
return new Type(array_filter($this->types, function(SimpleType $type) {
|
||||
return !$type->isNull();
|
||||
|
@ -190,10 +185,20 @@ class Type {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function toTypeMask(): string {
|
||||
return implode('|', array_map(function(SimpleType $type) {
|
||||
return $type->toTypeMask();
|
||||
}, $this->types));
|
||||
public function tryToRepresentableType(): ?RepresentableType {
|
||||
$classType = null;
|
||||
$builtinTypes = [];
|
||||
foreach ($this->types as $type) {
|
||||
if ($type->isBuiltin) {
|
||||
$builtinTypes[] = $type;
|
||||
} else if ($classType === null) {
|
||||
$classType = $type;
|
||||
} else {
|
||||
// We can only represent a single class type.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return new RepresentableType($classType, $builtinTypes);
|
||||
}
|
||||
|
||||
public static function equals(?Type $a, ?Type $b): bool {
|
||||
|
@ -215,6 +220,24 @@ class Type {
|
|||
}
|
||||
}
|
||||
|
||||
class RepresentableType {
|
||||
/** @var ?SimpleType $classType */
|
||||
public $classType;
|
||||
/** @var SimpleType[] $builtinTypes */
|
||||
public $builtinTypes;
|
||||
|
||||
public function __construct(?SimpleType $classType, array $builtinTypes) {
|
||||
$this->classType = $classType;
|
||||
$this->builtinTypes = $builtinTypes;
|
||||
}
|
||||
|
||||
public function toTypeMask(): string {
|
||||
return implode('|', array_map(function(SimpleType $type) {
|
||||
return $type->toTypeMask();
|
||||
}, $this->builtinTypes));
|
||||
}
|
||||
}
|
||||
|
||||
class ArgInfo {
|
||||
const SEND_BY_VAL = 0;
|
||||
const SEND_BY_REF = 1;
|
||||
|
@ -467,8 +490,7 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
|
|||
$code = '';
|
||||
$returnType = $funcInfo->return->type;
|
||||
if ($returnType !== null) {
|
||||
$simpleReturnType = $returnType->tryToSimpleType();
|
||||
if ($simpleReturnType !== null) {
|
||||
if (null !== $simpleReturnType = $returnType->tryToSimpleType()) {
|
||||
if ($simpleReturnType->isBuiltin) {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_%s, %d, %d, %s, %d)\n",
|
||||
|
@ -479,15 +501,23 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
|
|||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_%s, %d, %d, %s, %d)\n",
|
||||
$funcInfo->name, $funcInfo->return->byRef, $funcInfo->numRequiredArgs,
|
||||
str_replace('\\', '\\\\', $simpleReturnType->name), $returnType->isNullable()
|
||||
$simpleReturnType->toEscapedName(), $returnType->isNullable()
|
||||
);
|
||||
}
|
||||
} else if ($returnType->isBuiltinOnly()) {
|
||||
} else if (null !== $representableType = $returnType->tryToRepresentableType()) {
|
||||
if ($representableType->classType !== null) {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_%s, %d, %d, %s, %s)\n",
|
||||
$funcInfo->name, $funcInfo->return->byRef, $funcInfo->numRequiredArgs,
|
||||
$representableType->classType->toEscapedName(), $representableType->toTypeMask()
|
||||
);
|
||||
} else {
|
||||
$code .= sprintf(
|
||||
"ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_%s, %d, %d, %s)\n",
|
||||
$funcInfo->name, $funcInfo->return->byRef, $funcInfo->numRequiredArgs,
|
||||
$returnType->toTypeMask()
|
||||
$representableType->toTypeMask()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
throw new Exception('Unimplemented');
|
||||
}
|
||||
|
@ -514,7 +544,7 @@ function funcInfoToCode(FuncInfo $funcInfo): string {
|
|||
$code .= sprintf(
|
||||
"\tZEND_%s_OBJ_INFO(%s, %s, %s, %d)\n",
|
||||
$argKind, $argInfo->getSendByString(), $argInfo->name,
|
||||
str_replace('\\', '\\\\', $simpleArgType->name), $argType->isNullable()
|
||||
$simpleArgType->toEscapedName(), $argType->isNullable()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue