From a4ecbce469de343c65ef4f88816a113448038ef7 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Thu, 15 Aug 2019 15:10:46 -0500 Subject: [PATCH 01/10] Convert remaining array function arginfo to PHP stubs --- ext/standard/basic_functions.c | 348 ------------------------- ext/standard/basic_functions.stub.php | 155 +++++++++++ ext/standard/basic_functions_arginfo.h | 270 +++++++++++++++++++ 3 files changed, 425 insertions(+), 348 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 7935657bf8d2a..ccbbb31a5e0d4 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -122,354 +122,6 @@ static void user_tick_function_dtor(user_tick_function_entry *tick_function_entr /* {{{ arginfo */ -/* {{{ array.c */ - -ZEND_BEGIN_ARG_INFO(arginfo_usort, 0) - ZEND_ARG_INFO(1, arg) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, cmp_function) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_uasort, 0) - ZEND_ARG_INFO(1, arg) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, cmp_function) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_uksort, 0) - ZEND_ARG_INFO(1, arg) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, cmp_function) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_end, 0) - ZEND_ARG_INFO(1, arg) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_prev, 0) - ZEND_ARG_INFO(1, arg) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_next, 0) - ZEND_ARG_INFO(1, arg) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_reset, 0) - ZEND_ARG_INFO(1, arg) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_current, 0) - ZEND_ARG_INFO(0, arg) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_key, 0) - ZEND_ARG_INFO(0, arg) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 1) - ZEND_ARG_VARIADIC_INFO(0, args) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_max, 0, 0, 1) - ZEND_ARG_VARIADIC_INFO(0, args) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(1, input) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, funcname) - ZEND_ARG_INFO(0, userdata) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk_recursive, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(1, input) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, funcname) - ZEND_ARG_INFO(0, userdata) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_in_array, 0, 2, _IS_BOOL, 0) - ZEND_ARG_INFO(0, needle) - ZEND_ARG_INFO(0, haystack) /* ARRAY_INFO(0, haystack, 0) */ - ZEND_ARG_INFO(0, strict) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_search, 0, 0, 2) - ZEND_ARG_INFO(0, needle) - ZEND_ARG_INFO(0, haystack) /* ARRAY_INFO(0, haystack, 0) */ - ZEND_ARG_INFO(0, strict) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_extract, 0, 0, 1) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, extract_type) - ZEND_ARG_INFO(0, prefix) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_compact, 0, 0, 1) - ZEND_ARG_VARIADIC_INFO(0, var_names) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_fill, 0) - ZEND_ARG_INFO(0, start_key) - ZEND_ARG_INFO(0, num) - ZEND_ARG_INFO(0, val) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_array_fill_keys, IS_ARRAY, 0) - ZEND_ARG_INFO(0, keys) /* ARRAY_INFO(0, keys, 0) */ - ZEND_ARG_INFO(0, val) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_range, 0, 0, 2) - ZEND_ARG_INFO(0, low) - ZEND_ARG_INFO(0, high) - ZEND_ARG_INFO(0, step) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_shuffle, 0) - ZEND_ARG_INFO(1, arg) /* ARRAY_INFO(1, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_pop, 0) - ZEND_ARG_INFO(1, stack) /* ARRAY_INFO(1, stack, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_shift, 0) - ZEND_ARG_INFO(1, stack) /* ARRAY_INFO(1, stack, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_unshift, 0, 1, IS_LONG, 0) - ZEND_ARG_INFO(1, stack) /* ARRAY_INFO(1, stack, 0) */ - ZEND_ARG_VARIADIC_INFO(0, vars) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_splice, 0, 2, IS_ARRAY, 0) - ZEND_ARG_INFO(1, arg) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, length) - ZEND_ARG_INFO(0, replacement) /* ARRAY_INFO(0, arg, 1) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_slice, 0, 2, IS_ARRAY, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(1, arg, 0) */ - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, length) - ZEND_ARG_INFO(0, preserve_keys) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_merge, 0, 0, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_merge_recursive, 0, 0, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_replace, 0, 0, 1) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_replace_recursive, 0, 0, 1) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_keys, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, search_value) - ZEND_ARG_INFO(0, strict) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_key_first, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_key_last, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_array_values, IS_ARRAY, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_count_values, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_column, 0, 0, 2) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, column_key) - ZEND_ARG_INFO(0, index_key) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_reverse, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, input) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, preserve_keys) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_pad, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, pad_size) - ZEND_ARG_INFO(0, pad_value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_array_flip, IS_ARRAY, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_change_key_case, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, input) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, case) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_unique, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_intersect_key, 0, 0, 2) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_intersect_ukey, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_key_compare_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_intersect, 0, 0, 2) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_uintersect, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_data_compare_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_intersect_assoc, 0, 0, 2) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_uintersect_assoc, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_data_compare_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_intersect_uassoc, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_key_compare_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_uintersect_uassoc, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_data_compare_func) - ZEND_ARG_INFO(0, callback_key_compare_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_diff_key, 0, 0, 2) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_diff_ukey, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_key_comp_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_diff, 0, 0, 2) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_udiff, 0) - ZEND_ARG_INFO(0, arr1) - ZEND_ARG_INFO(0, arr2) - ZEND_ARG_INFO(0, callback_data_comp_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_diff_assoc, 0, 0, 2) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_diff_uassoc, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_data_comp_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_udiff_assoc, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_key_comp_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_udiff_uassoc, 0) - ZEND_ARG_INFO(0, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(0, arr2) /* ARRAY_INFO(0, arg2, 0) */ - ZEND_ARG_INFO(0, callback_data_comp_func) - ZEND_ARG_INFO(0, callback_key_comp_func) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_multisort, 0, 0, 1) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr1) /* ARRAY_INFO(0, arg1, 0) */ - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_order) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_flags) - ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, arr2) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand, 0, 0, 1) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, num_req) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_sum, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_product, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_reduce, 0, 0, 2) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, callback) - ZEND_ARG_INFO(0, initial) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_filter, 0, 1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, callback) - ZEND_ARG_INFO(0, use_keys) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_map, 0, 0, 2) - ZEND_ARG_INFO(0, callback) - ZEND_ARG_VARIADIC_INFO(0, arrays) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO(arginfo_array_key_exists, _IS_BOOL, 0) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, search) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_chunk, 0, 0, 2) - ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */ - ZEND_ARG_INFO(0, size) - ZEND_ARG_INFO(0, preserve_keys) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_array_combine, 0) - ZEND_ARG_INFO(0, keys) /* ARRAY_INFO(0, keys, 0) */ - ZEND_ARG_INFO(0, values) /* ARRAY_INFO(0, values, 0) */ -ZEND_END_ARG_INFO() -/* }}} */ /* {{{ basic_functions.c */ ZEND_BEGIN_ARG_INFO(arginfo_get_magic_quotes_gpc, 0) ZEND_END_ARG_INFO() diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 51095d7457cfb..bb73cd745d971 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -79,6 +79,161 @@ function sort(array &$arg, int $sort_flags = SORT_REGULAR): bool {} function rsort(array &$arg, int $sort_flags = SORT_REGULAR): bool {} +function usort(array &$arg, callable $cmp_function): bool {} + +function uasort(array &$arg, callable $cmp_function): bool {} + +function uksort(array &$arg, callable $cmp_function): bool {} + +function end(array &$arg) {} + +function prev(array &$arg) {} + +function next(array &$arg) {} + +function reset(array &$arg) {} + +function current(array $arg) {} + +/** @return int|string|null */ +function key(array $arg) {} + +function min(...$args) {} + +function max(...$args) {} + +function array_walk(array &$input, callable $funcname, $userdata = null): bool {} + +function array_walk_recursive(array &$input, callable $funcname, $userdata = null): bool {} + +function in_array($needle, array $haystack, bool $strict = false): bool {} + +/** @return int|string|false */ +function array_search($needle, array $haystack, bool $strict = false) {} + +function extract(array &$arg, int $extract_type = EXTR_OVERWRITE, string $prefix = null): int {} + +function compact(...$var_names): array {} + +/** @return array|false */ +function array_fill(int $start_key, int $num, $val) {} + +function array_fill_keys(array $keys, $val): array {} + +/** + * @param int|float|string $low + * @param int|float|string $high + * @param int|float $step + * @return array|false + */ +function range($low, $high, $step = 1) {} + +function shuffle(array &$arg): bool {} + +function array_pop(array &$stack) {} + +function array_shift(array &$stack) {} + +function array_unshift(array &$stack, ...$vars): int {} + +function array_splice(array &$arg, int $offset, int $length = UNKNOWN, $replacement = []): array {} + +function array_slice(array $arg, int $offset, ?int $length = null, bool $preserve_keys = false): array {} + +function array_merge(array ...$arrays): array {} + +function array_merge_recursive(array ...$arrays): array {} + +function array_replace(array $arr1, array ...$arrays): array {} + +function array_replace_recursive(array $arr1, array ...$arrays): array {} + +function array_keys(array $arg, $search_value = UNKNOWN, bool $strict = false): array {} + +/** @return int|string|null */ +function array_key_first(array $arg) {} + +/** @return int|string|null */ +function array_key_last(array $arg) {} + +function array_values(array $arg): array {} + +function array_count_values(array $arg): array {} + +/** + * @param int|string|null $column_key + * @param int|string $index_key + * @return array|false + */ +function array_column(array $arg, $column_key, $index_key = null) {} + +function array_reverse(array $input, bool $preserve_keys = false): array {} + +/** @return array|false */ +function array_pad(array $arg, int $pad_size, $pad_value) {} + +function array_flip(array $arg): array {} + +function array_change_key_case(array $input, int $case = CASE_LOWER): array {} + +function array_unique(array $arg, int $flags = SORT_STRING): array {} + +function array_intersect_key(array $arr1, array ...$arrays): array {} + +function array_intersect_ukey(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} + +function array_intersect(array $arr1, array ...$arrays): array {} + +function array_uintersect(array $arr1, array ...$arr2, callable $callback_data_compare_func): array {} + +function array_intersect_assoc(array $arr1, array ...$arrays): array {} + +function array_uintersect_assoc(array $arr1, array ...$arr2, callable $callback_data_compare_func): array {} + +function array_intersect_uassoc(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} + +function array_uintersect_uassoc(array $arr1, array ...$arr2, callable $callback_data_compare_func, callable $callback_key_compare_func): array {} + +function array_diff_key(array $arr1, array ...$arrays): array {} + +function array_diff_ukey(array $arr1, array ...$arr2, callable $callback_key_comp_func): array {} + +function array_diff(array $arr1, array ...$arrays): array {} + +function array_udiff(array $arr1, array ...$arr2, callable $callback_data_comp_func): array {} + +function array_diff_assoc(array $arr1, array ...$arrays): array {} + +function array_diff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func): array {} + +function array_udiff_assoc(array $arr1, array ...$arr2, callable $callback_key_comp_func): array {} + +function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func, callable $callback_key_comp_func): array {} + +function array_multisort(array &$arr1, $sort_order = SORT_ASC, $sort_flags = SORT_REGULAR, &...$arr2): bool {} + +function array_rand(array $arg, int $num_req = 1): ?array {} + +/** @return int|float */ +function array_sum(array $arg) {} + +/** @return int|float */ +function array_product(array $arg) {} + +function array_reduce(array $arg, callable $callback, $initial = null) {} + +function array_filter(array $arg, callable $callback, int $use_keys = 0): array {} + +function array_map(callable $callback, array ...$arrays): array {} + +/** @param int|string $key */ +function array_key_exists($key, array $search): bool {} + +function array_chunk(array $arg, int $size, bool $preserve_keys = false): ?array {} + +/** @return array|false */ +function array_combine(array $keys, array $values) {} + /* base64.c */ function base64_encode(string $str): string {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index b9ce39ad1c820..0829e4d99610a 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -96,6 +96,276 @@ ZEND_END_ARG_INFO() #define arginfo_rsort arginfo_krsort +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_usort, 0, 2, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, cmp_function, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +#define arginfo_uasort arginfo_usort + +#define arginfo_uksort arginfo_usort + +ZEND_BEGIN_ARG_INFO_EX(arginfo_end, 0, 0, 1) + ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_prev arginfo_end + +#define arginfo_next arginfo_end + +#define arginfo_reset arginfo_end + +ZEND_BEGIN_ARG_INFO_EX(arginfo_current, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_key arginfo_current + +ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 0) + ZEND_ARG_VARIADIC_INFO(0, args) +ZEND_END_ARG_INFO() + +#define arginfo_max arginfo_min + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk, 0, 2, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(1, input, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, funcname, IS_CALLABLE, 0) + ZEND_ARG_INFO(0, userdata) +ZEND_END_ARG_INFO() + +#define arginfo_array_walk_recursive arginfo_array_walk + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_in_array, 0, 2, _IS_BOOL, 0) + ZEND_ARG_INFO(0, needle) + ZEND_ARG_TYPE_INFO(0, haystack, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_search, 0, 0, 2) + ZEND_ARG_INFO(0, needle) + ZEND_ARG_TYPE_INFO(0, haystack, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, extract_type, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_compact, 0, 0, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_INFO(0, var_names) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_fill, 0, 0, 3) + ZEND_ARG_TYPE_INFO(0, start_key, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, num, IS_LONG, 0) + ZEND_ARG_INFO(0, val) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_fill_keys, 0, 2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) + ZEND_ARG_INFO(0, val) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_range, 0, 0, 2) + ZEND_ARG_INFO(0, low) + ZEND_ARG_INFO(0, high) + ZEND_ARG_INFO(0, step) +ZEND_END_ARG_INFO() + +#define arginfo_shuffle arginfo_natsort + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_pop, 0, 0, 1) + ZEND_ARG_TYPE_INFO(1, stack, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_shift arginfo_array_pop + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_unshift, 0, 1, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(1, stack, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_INFO(0, vars) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_splice, 0, 2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) + ZEND_ARG_INFO(0, replacement) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_slice, 0, 2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 1) + ZEND_ARG_TYPE_INFO(0, preserve_keys, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_merge, 0, 0, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_merge_recursive arginfo_array_merge + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_replace, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_replace_recursive arginfo_array_replace + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_keys, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_INFO(0, search_value) + ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_key_first arginfo_current + +#define arginfo_array_key_last arginfo_current + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_values, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_count_values arginfo_array_values + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_column, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_INFO(0, column_key) + ZEND_ARG_INFO(0, index_key) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_reverse, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, input, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, preserve_keys, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_pad, 0, 0, 3) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, pad_size, IS_LONG, 0) + ZEND_ARG_INFO(0, pad_value) +ZEND_END_ARG_INFO() + +#define arginfo_array_flip arginfo_array_values + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_change_key_case, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, input, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, case, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_unique, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_intersect_key arginfo_array_replace + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_ukey, 0, 3, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_key_compare_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_intersect arginfo_array_replace + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect, 0, 3, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_data_compare_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_intersect_assoc arginfo_array_replace + +#define arginfo_array_uintersect_assoc arginfo_array_uintersect + +#define arginfo_array_intersect_uassoc arginfo_array_intersect_ukey + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_uassoc, 0, 4, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_data_compare_func, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, callback_key_compare_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_diff_key arginfo_array_replace + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_diff_ukey, 0, 3, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_key_comp_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_diff arginfo_array_replace + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_udiff, 0, 3, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_data_comp_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_diff_assoc arginfo_array_replace + +#define arginfo_array_diff_uassoc arginfo_array_udiff + +#define arginfo_array_udiff_assoc arginfo_array_diff_ukey + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_udiff_uassoc, 0, 4, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_data_comp_func, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, callback_key_comp_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_multisort, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(1, arr1, IS_ARRAY, 0) + ZEND_ARG_INFO(0, sort_order) + ZEND_ARG_INFO(0, sort_flags) + ZEND_ARG_VARIADIC_INFO(1, arr2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_rand, 0, 1, IS_ARRAY, 1) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, num_req, IS_LONG, 0) +ZEND_END_ARG_INFO() + +#define arginfo_array_sum arginfo_current + +#define arginfo_array_product arginfo_current + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_reduce, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) + ZEND_ARG_INFO(0, initial) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_filter, 0, 2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, use_keys, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_map, 0, 1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_key_exists, 0, 2, _IS_BOOL, 0) + ZEND_ARG_INFO(0, key) + ZEND_ARG_TYPE_INFO(0, search, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 1) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, preserve_keys, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_combine, 0, 0, 2) + ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_base64_encode, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_END_ARG_INFO() From 402b41ddeff17c52a4df0fcba6b719e3c3588f00 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Thu, 15 Aug 2019 21:50:56 -0500 Subject: [PATCH 02/10] Support ZEND_SEND_PREFER_REF arguments generated from stubs --- ext/standard/basic_functions.stub.php | 5 ++ ext/standard/basic_functions_arginfo.h | 10 ++-- scripts/dev/gen_stub.php | 65 ++++++++++++++++++++------ 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index bb73cd745d971..fabcd68101ea5 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -111,6 +111,7 @@ function in_array($needle, array $haystack, bool $strict = false): bool {} /** @return int|string|false */ function array_search($needle, array $haystack, bool $strict = false) {} +#prefref arg function extract(array &$arg, int $extract_type = EXTR_OVERWRITE, string $prefix = null): int {} function compact(...$var_names): array {} @@ -210,6 +211,10 @@ function array_udiff_assoc(array $arr1, array ...$arr2, callable $callback_key_c function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func, callable $callback_key_comp_func): array {} +#prefref arr1 +#prefref sort_order +#prefref sort_flags +#prefref arr2 function array_multisort(array &$arr1, $sort_order = SORT_ASC, $sort_flags = SORT_REGULAR, &...$arr2): bool {} function array_rand(array $arg, int $num_req = 1): ?array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 0829e4d99610a..a010f77b6da2e 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -148,7 +148,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_search, 0, 0, 2) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(ZEND_SEND_PREFER_REF, arg, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, extract_type, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -318,10 +318,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_udiff_uassoc, 0, 4, IS_ARR ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_multisort, 0, 1, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(1, arr1, IS_ARRAY, 0) - ZEND_ARG_INFO(0, sort_order) - ZEND_ARG_INFO(0, sort_flags) - ZEND_ARG_VARIADIC_INFO(1, arr2) + ZEND_ARG_TYPE_INFO(ZEND_SEND_PREFER_REF, arr1, IS_ARRAY, 0) + ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_order) + ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_flags) + ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, arr2) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_rand, 0, 1, IS_ARRAY, 1) diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php index 6146009df31b4..3d89e51cf3a92 100755 --- a/scripts/dev/gen_stub.php +++ b/scripts/dev/gen_stub.php @@ -113,13 +113,16 @@ class ArgInfo { /** @var bool */ public $byRef; /** @var bool */ + public $preferRef; + /** @var bool */ public $isVariadic; /** @var Type|null */ public $type; - public function __construct(string $name, bool $byRef, bool $isVariadic, ?Type $type) { + public function __construct(string $name, bool $byRef, bool $preferRef, bool $isVariadic, ?Type $type) { $this->name = $name; $this->byRef = $byRef; + $this->preferRef = $preferRef; $this->isVariadic = $isVariadic; $this->type = $type; } @@ -127,6 +130,7 @@ public function __construct(string $name, bool $byRef, bool $isVariadic, ?Type $ public function equals(ArgInfo $other): bool { return $this->name === $other->name && $this->byRef === $other->byRef + && $this->preferRef === $other->preferRef && $this->isVariadic === $other->isVariadic && Type::equals($this->type, $other->type); } @@ -188,13 +192,27 @@ public function equalsApartFromName(FuncInfo $other): bool { } } -function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond): FuncInfo { +function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond, array &$paramMeta): FuncInfo { $args = []; $numRequiredArgs = 0; foreach ($func->getParams() as $i => $param) { + $varName = $param->var->name; + $preferRef = !empty($paramMeta[$varName]['prefRef']); + + if ($preferRef) { + unset($paramMeta[$varName]['prefRef']); + + foreach (array_keys($paramMeta[$varName]) as $key) { + throw new Exception("Unexpected metadata key $key for param $varName of function $name"); + } + + unset($paramMeta[$varName]); + } + $args[] = new ArgInfo( - $param->var->name, + $varName, $param->byRef, + $preferRef, $param->variadic, $param->type ? Type::fromNode($param->type) : null ); @@ -203,6 +221,10 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond) } } + foreach (array_keys($paramMeta) as $var) { + throw new Exception("Found metadata for invalid param $var of function $name"); + } + $returnType = $func->getReturnType(); $return = new ReturnInfo( $func->returnsByRef(), @@ -210,7 +232,7 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond) return new FuncInfo($name, $args, $return, $numRequiredArgs, $cond); } -function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string { +function handlePreprocessorConditions(array &$conds, array &$paramMeta, Stmt $stmt): ?string { foreach ($stmt->getComments() as $comment) { $text = trim($comment->getText()); if (preg_match('/^#\s*if\s+(.+)$/', $text, $matches)) { @@ -230,6 +252,12 @@ function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string { throw new Exception("Encountered #endif without corresponding #if"); } array_pop($conds); + } else if (preg_match('/^#\s*prefref\s+(.+)$/', $text, $matches)) { + $name = $matches[1]; + if (!isset($paramMeta[$name])) { + $paramMeta[$name] = []; + } + $paramMeta[$name]['prefRef'] = true; } else if ($text[0] === '#') { throw new Exception("Unrecognized preprocessor directive \"$text\""); } @@ -256,21 +284,22 @@ function parseStubFile(string $fileName) { $funcInfos = []; $conds = []; + $paramMeta = []; foreach ($stmts as $stmt) { - $cond = handlePreprocessorConditions($conds, $stmt); + $cond = handlePreprocessorConditions($conds, $paramMeta, $stmt); if ($stmt instanceof Stmt\Nop) { continue; } if ($stmt instanceof Stmt\Function_) { - $funcInfos[] = parseFunctionLike($stmt->name->toString(), $stmt, $cond); + $funcInfos[] = parseFunctionLike($stmt->name->toString(), $stmt, $cond, $paramMeta); continue; } if ($stmt instanceof Stmt\ClassLike) { $className = $stmt->name->toString(); foreach ($stmt->stmts as $classStmt) { - $cond = handlePreprocessorConditions($conds, $classStmt); + $cond = handlePreprocessorConditions($conds, $paramMeta, $classStmt); if ($classStmt instanceof Stmt\Nop) { continue; } @@ -280,7 +309,7 @@ function parseStubFile(string $fileName) { } $funcInfos[] = parseFunctionLike( - 'class_' . $className . '_' . $classStmt->name->toString(), $classStmt, $cond); + 'class_' . $className . '_' . $classStmt->name->toString(), $classStmt, $cond, $paramMeta); } continue; } @@ -320,20 +349,20 @@ function funcInfoToCode(FuncInfo $funcInfo): string { if ($argInfo->type) { if ($argInfo->type->isBuiltin) { $code .= sprintf( - "\tZEND_%s_TYPE_INFO(%d, %s, %s, %d)\n", - $argKind, $argInfo->byRef, $argInfo->name, + "\tZEND_%s_TYPE_INFO(%s, %s, %s, %d)\n", + $argKind, send_by($argInfo), $argInfo->name, $argInfo->type->toTypeCode(), $argInfo->type->isNullable ); } else { $code .= sprintf( - "\tZEND_%s_OBJ_INFO(%d, %s, %s, %d)\n", - $argKind, $argInfo->byRef, $argInfo->name, + "\tZEND_%s_OBJ_INFO(%s, %s, %s, %d)\n", + $argKind, send_by($argInfo), $argInfo->name, $argInfo->type->name, $argInfo->type->isNullable ); } } else { $code .= sprintf( - "\tZEND_%s_INFO(%d, %s)\n", $argKind, $argInfo->byRef, $argInfo->name); + "\tZEND_%s_INFO(%s, %s)\n", $argKind, send_by($argInfo), $argInfo->name); } } @@ -341,6 +370,16 @@ function funcInfoToCode(FuncInfo $funcInfo): string { return $code; } +function send_by(ArgInfo $arg): string { + if ($arg->preferRef) { + return 'ZEND_SEND_PREFER_REF'; + } else if ($arg->byRef) { + return '1'; + } else { + return '0'; + } +} + function findEquivalentFuncInfo(array $generatedFuncInfos, $funcInfo): ?FuncInfo { foreach ($generatedFuncInfos as $generatedFuncInfo) { if ($generatedFuncInfo->equalsApartFromName($funcInfo)) { From 2fb29be62f060ea23504cf8e1ef58331dc8c8363 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Fri, 16 Aug 2019 00:34:02 -0500 Subject: [PATCH 03/10] Fix additional test failures --- ext/standard/basic_functions.stub.php | 26 +++++++++------- ext/standard/basic_functions_arginfo.h | 42 +++++++++++++++++--------- 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index fabcd68101ea5..953d83bdc2278 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -93,7 +93,8 @@ function next(array &$arg) {} function reset(array &$arg) {} -function current(array $arg) {} +/** @param array|object $arg */ +function current($arg) {} /** @return int|string|null */ function key(array $arg) {} @@ -102,9 +103,11 @@ function min(...$args) {} function max(...$args) {} -function array_walk(array &$input, callable $funcname, $userdata = null): bool {} +/** @param array|object $input */ +function array_walk(&$input, callable $funcname, $userdata = null): bool {} -function array_walk_recursive(array &$input, callable $funcname, $userdata = null): bool {} +/** @param array|object $input */ +function array_walk_recursive(&$input, callable $funcname, $userdata = null): bool {} function in_array($needle, array $haystack, bool $strict = false): bool {} @@ -112,7 +115,7 @@ function in_array($needle, array $haystack, bool $strict = false): bool {} function array_search($needle, array $haystack, bool $strict = false) {} #prefref arg -function extract(array &$arg, int $extract_type = EXTR_OVERWRITE, string $prefix = null): int {} +function extract(array &$arg, int $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} function compact(...$var_names): array {} @@ -179,7 +182,7 @@ function array_change_key_case(array $input, int $case = CASE_LOWER): array {} function array_unique(array $arg, int $flags = SORT_STRING): array {} -function array_intersect_key(array $arr1, array ...$arrays): array {} +function array_intersect_key(array $arr1, array $arr2, array ...$arrays): array {} function array_intersect_ukey(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} @@ -189,7 +192,7 @@ function array_uintersect(array $arr1, array ...$arr2, callable $callback_data_c function array_intersect_assoc(array $arr1, array ...$arrays): array {} -function array_uintersect_assoc(array $arr1, array ...$arr2, callable $callback_data_compare_func): array {} +function array_uintersect_assoc(array $arr1, array $arr2, array ...$arrays, callable $callback_data_compare_func): array {} function array_intersect_uassoc(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} @@ -197,7 +200,7 @@ function array_uintersect_uassoc(array $arr1, array ...$arr2, callable $callback function array_diff_key(array $arr1, array ...$arrays): array {} -function array_diff_ukey(array $arr1, array ...$arr2, callable $callback_key_comp_func): array {} +function array_diff_ukey(array $arr1, array $arr2, array ...$arrays, callable $callback_key_comp_func): array {} function array_diff(array $arr1, array ...$arrays): array {} @@ -207,7 +210,7 @@ function array_diff_assoc(array $arr1, array ...$arrays): array {} function array_diff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func): array {} -function array_udiff_assoc(array $arr1, array ...$arr2, callable $callback_key_comp_func): array {} +function array_udiff_assoc(array $arr1, array $arr2, array ...$arrays, callable $callback_key_comp_func): array {} function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func, callable $callback_key_comp_func): array {} @@ -215,9 +218,10 @@ function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data #prefref sort_order #prefref sort_flags #prefref arr2 -function array_multisort(array &$arr1, $sort_order = SORT_ASC, $sort_flags = SORT_REGULAR, &...$arr2): bool {} +function array_multisort(&$arr1, $sort_order = SORT_ASC, $sort_flags = SORT_REGULAR, &...$arr2): bool {} -function array_rand(array $arg, int $num_req = 1): ?array {} +/** @return int|string|array|null */ +function array_rand(array $arg, int $num_req = 1) {} /** @return int|float */ function array_sum(array $arg) {} @@ -229,7 +233,7 @@ function array_reduce(array $arg, callable $callback, $initial = null) {} function array_filter(array $arg, callable $callback, int $use_keys = 0): array {} -function array_map(callable $callback, array ...$arrays): array {} +function array_map(?callable $callback, array ...$arrays): array {} /** @param int|string $key */ function array_key_exists($key, array $search): bool {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index a010f77b6da2e..49e3282ddcb7f 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -116,10 +116,12 @@ ZEND_END_ARG_INFO() #define arginfo_reset arginfo_end ZEND_BEGIN_ARG_INFO_EX(arginfo_current, 0, 0, 1) - ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) + ZEND_ARG_INFO(0, arg) ZEND_END_ARG_INFO() -#define arginfo_key arginfo_current +ZEND_BEGIN_ARG_INFO_EX(arginfo_key, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 0) ZEND_ARG_VARIADIC_INFO(0, args) @@ -128,7 +130,7 @@ ZEND_END_ARG_INFO() #define arginfo_max arginfo_min ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk, 0, 2, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(1, input, IS_ARRAY, 0) + ZEND_ARG_INFO(1, input) ZEND_ARG_TYPE_INFO(0, funcname, IS_CALLABLE, 0) ZEND_ARG_INFO(0, userdata) ZEND_END_ARG_INFO() @@ -147,7 +149,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_search, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 1) ZEND_ARG_TYPE_INFO(ZEND_SEND_PREFER_REF, arg, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, extract_type, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0) @@ -220,9 +222,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_keys, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0) ZEND_END_ARG_INFO() -#define arginfo_array_key_first arginfo_current +#define arginfo_array_key_first arginfo_key -#define arginfo_array_key_last arginfo_current +#define arginfo_array_key_last arginfo_key ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_values, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) @@ -259,7 +261,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_unique, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) ZEND_END_ARG_INFO() -#define arginfo_array_intersect_key arginfo_array_replace +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_key, 0, 2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_ukey, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) @@ -277,7 +283,12 @@ ZEND_END_ARG_INFO() #define arginfo_array_intersect_assoc arginfo_array_replace -#define arginfo_array_uintersect_assoc arginfo_array_uintersect +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_assoc, 0, 4, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_data_compare_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() #define arginfo_array_intersect_uassoc arginfo_array_intersect_ukey @@ -290,9 +301,10 @@ ZEND_END_ARG_INFO() #define arginfo_array_diff_key arginfo_array_replace -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_diff_ukey, 0, 3, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_diff_ukey, 0, 4, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, callback_key_comp_func, IS_CALLABLE, 0) ZEND_END_ARG_INFO() @@ -318,20 +330,20 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_udiff_uassoc, 0, 4, IS_ARR ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_multisort, 0, 1, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(ZEND_SEND_PREFER_REF, arr1, IS_ARRAY, 0) + ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr1) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_order) ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_flags) ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, arr2) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_rand, 0, 1, IS_ARRAY, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, num_req, IS_LONG, 0) ZEND_END_ARG_INFO() -#define arginfo_array_sum arginfo_current +#define arginfo_array_sum arginfo_key -#define arginfo_array_product arginfo_current +#define arginfo_array_product arginfo_key ZEND_BEGIN_ARG_INFO_EX(arginfo_array_reduce, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) @@ -346,7 +358,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_filter, 0, 2, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_map, 0, 1, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 1) ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) ZEND_END_ARG_INFO() From 6ce294ac90299a728215eae352a8a14be7986790 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Fri, 16 Aug 2019 09:19:10 -0500 Subject: [PATCH 04/10] Use PHPDoc instead of preprocessor directive for prefer-ref params --- ext/standard/basic_functions.stub.php | 14 +++++--- scripts/dev/gen_stub.php | 47 +++++++++++++-------------- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 953d83bdc2278..843447565556b 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -114,7 +114,9 @@ function in_array($needle, array $haystack, bool $strict = false): bool {} /** @return int|string|false */ function array_search($needle, array $haystack, bool $strict = false) {} -#prefref arg +/** + * @prefer-ref $arg + */ function extract(array &$arg, int $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} function compact(...$var_names): array {} @@ -214,10 +216,12 @@ function array_udiff_assoc(array $arr1, array $arr2, array ...$arrays, callable function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func, callable $callback_key_comp_func): array {} -#prefref arr1 -#prefref sort_order -#prefref sort_flags -#prefref arr2 +/** + * @prefer-ref $arr1 + * @prefer-ref $sort_order + * @prefer-ref $sort_flags + * @prefer-ref $arr2 + */ function array_multisort(&$arr1, $sort_order = SORT_ASC, $sort_flags = SORT_REGULAR, &...$arr2): bool {} /** @return int|string|array|null */ diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php index 3d89e51cf3a92..e6cf1c5758aa4 100755 --- a/scripts/dev/gen_stub.php +++ b/scripts/dev/gen_stub.php @@ -192,22 +192,28 @@ public function equalsApartFromName(FuncInfo $other): bool { } } -function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond, array &$paramMeta): FuncInfo { +function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond): FuncInfo { + $comment = $func->getDocComment(); + $paramMeta = []; + + if ($comment) { + foreach (explode("\n", $comment->getText()) as $commentLine) { + if (preg_match('/^\*\s*@prefer-ref\s+\$(.+)$/', trim($commentLine), $matches)) { + $varName = $matches[1]; + if (!isset($paramMeta[$varName])) { + $paramMeta[$varName] = []; + } + $paramMeta[$varName]['preferRef'] = true; + } + } + } + $args = []; $numRequiredArgs = 0; foreach ($func->getParams() as $i => $param) { $varName = $param->var->name; - $preferRef = !empty($paramMeta[$varName]['prefRef']); - - if ($preferRef) { - unset($paramMeta[$varName]['prefRef']); - - foreach (array_keys($paramMeta[$varName]) as $key) { - throw new Exception("Unexpected metadata key $key for param $varName of function $name"); - } - - unset($paramMeta[$varName]); - } + $preferRef = !empty($paramMeta[$varName]['preferRef']); + unset($paramMeta[$varName]); $args[] = new ArgInfo( $varName, @@ -232,7 +238,7 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond, return new FuncInfo($name, $args, $return, $numRequiredArgs, $cond); } -function handlePreprocessorConditions(array &$conds, array &$paramMeta, Stmt $stmt): ?string { +function handlePreprocessorConditions(array &$conds, Stmt $stmt): ?string { foreach ($stmt->getComments() as $comment) { $text = trim($comment->getText()); if (preg_match('/^#\s*if\s+(.+)$/', $text, $matches)) { @@ -252,12 +258,6 @@ function handlePreprocessorConditions(array &$conds, array &$paramMeta, Stmt $st throw new Exception("Encountered #endif without corresponding #if"); } array_pop($conds); - } else if (preg_match('/^#\s*prefref\s+(.+)$/', $text, $matches)) { - $name = $matches[1]; - if (!isset($paramMeta[$name])) { - $paramMeta[$name] = []; - } - $paramMeta[$name]['prefRef'] = true; } else if ($text[0] === '#') { throw new Exception("Unrecognized preprocessor directive \"$text\""); } @@ -284,22 +284,21 @@ function parseStubFile(string $fileName) { $funcInfos = []; $conds = []; - $paramMeta = []; foreach ($stmts as $stmt) { - $cond = handlePreprocessorConditions($conds, $paramMeta, $stmt); + $cond = handlePreprocessorConditions($conds, $stmt); if ($stmt instanceof Stmt\Nop) { continue; } if ($stmt instanceof Stmt\Function_) { - $funcInfos[] = parseFunctionLike($stmt->name->toString(), $stmt, $cond, $paramMeta); + $funcInfos[] = parseFunctionLike($stmt->name->toString(), $stmt, $cond); continue; } if ($stmt instanceof Stmt\ClassLike) { $className = $stmt->name->toString(); foreach ($stmt->stmts as $classStmt) { - $cond = handlePreprocessorConditions($conds, $paramMeta, $classStmt); + $cond = handlePreprocessorConditions($conds, $classStmt); if ($classStmt instanceof Stmt\Nop) { continue; } @@ -309,7 +308,7 @@ function parseStubFile(string $fileName) { } $funcInfos[] = parseFunctionLike( - 'class_' . $className . '_' . $classStmt->name->toString(), $classStmt, $cond, $paramMeta); + 'class_' . $className . '_' . $classStmt->name->toString(), $classStmt, $cond); } continue; } From 105e8a49e7d8ad5254ec841df6fbba4af489ac99 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Fri, 16 Aug 2019 10:04:07 -0500 Subject: [PATCH 05/10] Fix more test failures --- ext/standard/basic_functions.stub.php | 22 ++++++++++++------- ext/standard/basic_functions_arginfo.h | 30 +++++++++++++++----------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 843447565556b..6e640013f2930 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -87,9 +87,11 @@ function uksort(array &$arg, callable $cmp_function): bool {} function end(array &$arg) {} -function prev(array &$arg) {} +/** @param array|object $arg */ +function prev(&$arg) {} -function next(array &$arg) {} +/** @param array|object $arg */ +function next(&$arg) {} function reset(array &$arg) {} @@ -117,9 +119,9 @@ function array_search($needle, array $haystack, bool $strict = false) {} /** * @prefer-ref $arg */ -function extract(array &$arg, int $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} +function extract(array &$arg, $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} -function compact(...$var_names): array {} +function compact(...$var_names): ?array {} /** @return array|false */ function array_fill(int $start_key, int $num, $val) {} @@ -186,7 +188,8 @@ function array_unique(array $arg, int $flags = SORT_STRING): array {} function array_intersect_key(array $arr1, array $arr2, array ...$arrays): array {} -function array_intersect_ukey(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} +// tests break if $arr2 is variadic +function array_intersect_ukey(array $arr1, array $arr2, $callback_key_compare_func): array {} function array_intersect(array $arr1, array ...$arrays): array {} @@ -194,7 +197,8 @@ function array_uintersect(array $arr1, array ...$arr2, callable $callback_data_c function array_intersect_assoc(array $arr1, array ...$arrays): array {} -function array_uintersect_assoc(array $arr1, array $arr2, array ...$arrays, callable $callback_data_compare_func): array {} +// tests break if $arr2 is variadic +function array_uintersect_assoc(array $arr1, array $arr2, $callback_data_compare_func): array {} function array_intersect_uassoc(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} @@ -202,7 +206,8 @@ function array_uintersect_uassoc(array $arr1, array ...$arr2, callable $callback function array_diff_key(array $arr1, array ...$arrays): array {} -function array_diff_ukey(array $arr1, array $arr2, array ...$arrays, callable $callback_key_comp_func): array {} +// tests break if $arr2 is variadic +function array_diff_ukey(array $arr1, array $arr2, $callback_key_comp_func): array {} function array_diff(array $arr1, array ...$arrays): array {} @@ -212,7 +217,8 @@ function array_diff_assoc(array $arr1, array ...$arrays): array {} function array_diff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func): array {} -function array_udiff_assoc(array $arr1, array $arr2, array ...$arrays, callable $callback_key_comp_func): array {} +// tests break if $arr2 is variadic +function array_udiff_assoc(array $arr1, array $arr2, $callback_key_comp_func): array {} function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func, callable $callback_key_comp_func): array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 49e3282ddcb7f..356cd11302eb7 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -109,9 +109,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_end, 0, 0, 1) ZEND_ARG_TYPE_INFO(1, arg, IS_ARRAY, 0) ZEND_END_ARG_INFO() -#define arginfo_prev arginfo_end +ZEND_BEGIN_ARG_INFO_EX(arginfo_prev, 0, 0, 1) + ZEND_ARG_INFO(1, arg) +ZEND_END_ARG_INFO() -#define arginfo_next arginfo_end +#define arginfo_next arginfo_prev #define arginfo_reset arginfo_end @@ -151,11 +153,11 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 1) ZEND_ARG_TYPE_INFO(ZEND_SEND_PREFER_REF, arg, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, extract_type, IS_LONG, 0) + ZEND_ARG_INFO(0, extract_type) ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_compact, 0, 0, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_compact, 0, 0, IS_ARRAY, 1) ZEND_ARG_VARIADIC_INFO(0, var_names) ZEND_END_ARG_INFO() @@ -269,8 +271,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_ukey, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_key_compare_func, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_INFO(0, callback_key_compare_func) ZEND_END_ARG_INFO() #define arginfo_array_intersect arginfo_array_replace @@ -283,14 +285,17 @@ ZEND_END_ARG_INFO() #define arginfo_array_intersect_assoc arginfo_array_replace -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_assoc, 0, 4, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_assoc, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_data_compare_func, IS_CALLABLE, 0) + ZEND_ARG_INFO(0, callback_data_compare_func) ZEND_END_ARG_INFO() -#define arginfo_array_intersect_uassoc arginfo_array_intersect_ukey +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_uassoc, 0, 3, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, callback_key_compare_func, IS_CALLABLE, 0) +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_uassoc, 0, 4, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) @@ -301,11 +306,10 @@ ZEND_END_ARG_INFO() #define arginfo_array_diff_key arginfo_array_replace -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_diff_ukey, 0, 4, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_diff_ukey, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_key_comp_func, IS_CALLABLE, 0) + ZEND_ARG_INFO(0, callback_key_comp_func) ZEND_END_ARG_INFO() #define arginfo_array_diff arginfo_array_replace From 5b016446215280fdbf3cd63665711fdc9ba00178 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Fri, 16 Aug 2019 10:46:24 -0500 Subject: [PATCH 06/10] Fix last failing test --- ext/standard/basic_functions.stub.php | 7 +++---- ext/standard/basic_functions_arginfo.h | 10 +++------- scripts/dev/gen_stub.php | 4 +++- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index a290b6279d129..26ded103c9a15 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -116,9 +116,7 @@ function in_array($needle, array $haystack, bool $strict = false): bool {} /** @return int|string|false */ function array_search($needle, array $haystack, bool $strict = false) {} -/** - * @prefer-ref $arg - */ +/** @prefer-ref $arg */ function extract(array &$arg, $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} function compact(...$var_names): ?array {} @@ -193,7 +191,8 @@ function array_intersect_ukey(array $arr1, array $arr2, $callback_key_compare_fu function array_intersect(array $arr1, array ...$arrays): array {} -function array_uintersect(array $arr1, array ...$arr2, callable $callback_data_compare_func): array {} +// tests break if $arr2 is variadic +function array_uintersect(array $arr1, array $arr2, $callback_data_compare_func): array {} function array_intersect_assoc(array $arr1, array ...$arrays): array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 80145478f9e5c..a80888d8ec8a7 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -279,17 +279,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_data_compare_func, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) + ZEND_ARG_INFO(0, callback_data_compare_func) ZEND_END_ARG_INFO() #define arginfo_array_intersect_assoc arginfo_array_replace -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_assoc, 0, 3, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_INFO(0, callback_data_compare_func) -ZEND_END_ARG_INFO() +#define arginfo_array_uintersect_assoc arginfo_array_uintersect ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_uassoc, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php index e6cf1c5758aa4..2c084d5007f87 100755 --- a/scripts/dev/gen_stub.php +++ b/scripts/dev/gen_stub.php @@ -197,7 +197,9 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond) $paramMeta = []; if ($comment) { - foreach (explode("\n", $comment->getText()) as $commentLine) { + $commentText = substr($comment->getText(), 2, -2); + + foreach (explode("\n", $commentText) as $commentLine) { if (preg_match('/^\*\s*@prefer-ref\s+\$(.+)$/', trim($commentLine), $matches)) { $varName = $matches[1]; if (!isset($paramMeta[$varName])) { From a39d0fe3e4a3a8ea0cd87fe87814ea704ae18caf Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Fri, 16 Aug 2019 11:20:41 -0500 Subject: [PATCH 07/10] min, max, and compact require at least 1 argument --- ext/standard/basic_functions.stub.php | 6 +++--- ext/standard/basic_functions_arginfo.h | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 26ded103c9a15..79faa6f83001a 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -101,9 +101,9 @@ function current($arg) {} /** @return int|string|null */ function key(array $arg) {} -function min(...$args) {} +function min($arg, ...$args) {} -function max(...$args) {} +function max($arg, ...$args) {} /** @param array|object $input */ function array_walk(&$input, callable $funcname, $userdata = null): bool {} @@ -119,7 +119,7 @@ function array_search($needle, array $haystack, bool $strict = false) {} /** @prefer-ref $arg */ function extract(array &$arg, $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} -function compact(...$var_names): ?array {} +function compact($var_name, ...$var_names): ?array {} /** @return array|false */ function array_fill(int $start_key, int $num, $val) {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index a80888d8ec8a7..3362a0c4776c4 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -125,7 +125,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_key, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 1) + ZEND_ARG_INFO(0, arg) ZEND_ARG_VARIADIC_INFO(0, args) ZEND_END_ARG_INFO() @@ -157,7 +158,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 1) ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_compact, 0, 0, IS_ARRAY, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_compact, 0, 1, IS_ARRAY, 1) + ZEND_ARG_INFO(0, var_name) ZEND_ARG_VARIADIC_INFO(0, var_names) ZEND_END_ARG_INFO() From 56476a6155716001bf4495027eb07695423dfd49 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Tue, 20 Aug 2019 18:17:58 -0500 Subject: [PATCH 08/10] Address review comments --- ext/standard/basic_functions.stub.php | 84 +++++++++++++++--------- ext/standard/basic_functions_arginfo.h | 89 +++++++++----------------- scripts/dev/gen_stub.php | 56 ++++++++-------- 3 files changed, 115 insertions(+), 114 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 79faa6f83001a..7b3412168c539 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -85,24 +85,46 @@ function uasort(array &$arg, callable $cmp_function): bool {} function uksort(array &$arg, callable $cmp_function): bool {} +/** + * @param array|object $arg + * @return mixed + */ function end(array &$arg) {} -/** @param array|object $arg */ +/** + * @param array|object $arg + * @return mixed + */ function prev(&$arg) {} -/** @param array|object $arg */ +/** + * @param array|object $arg + * @return mixed + */ function next(&$arg) {} -function reset(array &$arg) {} +/** + * @param array|object $arg + * @return mixed + */ +function reset(&$arg) {} -/** @param array|object $arg */ +/** + * @param array|object $arg + * @return mixed + */ function current($arg) {} -/** @return int|string|null */ -function key(array $arg) {} +/** + * @param array|object $arg + * @return int|string|null + */ +function key($arg) {} +/** @return mixed */ function min($arg, ...$args) {} +/** @return mixed */ function max($arg, ...$args) {} /** @param array|object $input */ @@ -117,7 +139,7 @@ function in_array($needle, array $haystack, bool $strict = false): bool {} function array_search($needle, array $haystack, bool $strict = false) {} /** @prefer-ref $arg */ -function extract(array &$arg, $extract_type = EXTR_OVERWRITE, string $prefix = null): ?int {} +function extract(array &$arg, $extract_type = EXTR_OVERWRITE, string $prefix = ""): ?int {} function compact($var_name, ...$var_names): ?array {} @@ -136,8 +158,10 @@ function range($low, $high, $step = 1) {} function shuffle(array &$arg): bool {} +/** @return mixed */ function array_pop(array &$stack) {} +/** @return mixed */ function array_shift(array &$stack) {} function array_unshift(array &$stack, ...$vars): int {} @@ -168,7 +192,7 @@ function array_count_values(array $arg): array {} /** * @param int|string|null $column_key - * @param int|string $index_key + * @param int|string|null $index_key * @return array|false */ function array_column(array $arg, $column_key, $index_key = null) {} @@ -186,40 +210,35 @@ function array_unique(array $arg, int $flags = SORT_STRING): array {} function array_intersect_key(array $arr1, array $arr2, array ...$arrays): array {} -// tests break if $arr2 is variadic -function array_intersect_ukey(array $arr1, array $arr2, $callback_key_compare_func): array {} +function array_intersect_ukey(array $arr1, array $arr2, ...$rest): array {} -function array_intersect(array $arr1, array ...$arrays): array {} +function array_intersect(array $arr1, array $arr2, array ...$arrays): array {} -// tests break if $arr2 is variadic -function array_uintersect(array $arr1, array $arr2, $callback_data_compare_func): array {} +function array_uintersect(array $arr1, array $arr2, ...$rest): array {} -function array_intersect_assoc(array $arr1, array ...$arrays): array {} +function array_intersect_assoc(array $arr1, array $arr2, array ...$arrays): array {} -// tests break if $arr2 is variadic -function array_uintersect_assoc(array $arr1, array $arr2, $callback_data_compare_func): array {} +function array_uintersect_assoc(array $arr1, array $arr2, ...$rest): array {} -function array_intersect_uassoc(array $arr1, array ...$arr2, callable $callback_key_compare_func): array {} +function array_intersect_uassoc(array $arr1, array $arr2, ...$rest): array {} -function array_uintersect_uassoc(array $arr1, array ...$arr2, callable $callback_data_compare_func, callable $callback_key_compare_func): array {} +function array_uintersect_uassoc(array $arr1, array $arr2, ...$rest): array {} -function array_diff_key(array $arr1, array ...$arrays): array {} +function array_diff_key(array $arr1, array $arr2, array ...$arrays): array {} -// tests break if $arr2 is variadic -function array_diff_ukey(array $arr1, array $arr2, $callback_key_comp_func): array {} +function array_diff_ukey(array $arr1, array $arr2, ...$rest): array {} -function array_diff(array $arr1, array ...$arrays): array {} +function array_diff(array $arr1, array $arr2, array ...$arrays): array {} -function array_udiff(array $arr1, array ...$arr2, callable $callback_data_comp_func): array {} +function array_udiff(array $arr1, array $arr2, ...$rest): array {} -function array_diff_assoc(array $arr1, array ...$arrays): array {} +function array_diff_assoc(array $arr1, array $arr2, array ...$arrays): array {} -function array_diff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func): array {} +function array_diff_uassoc(array $arr1, array $arr2, ...$rest): array {} -// tests break if $arr2 is variadic -function array_udiff_assoc(array $arr1, array $arr2, $callback_key_comp_func): array {} +function array_udiff_assoc(array $arr1, array $arr2, ...$rest): array {} -function array_udiff_uassoc(array $arr1, array ...$arr2, callable $callback_data_comp_func, callable $callback_key_comp_func): array {} +function array_udiff_uassoc(array $arr1, array $arr2, ...$rest): array {} /** * @prefer-ref $arr1 @@ -242,10 +261,13 @@ function array_reduce(array $arg, callable $callback, $initial = null) {} function array_filter(array $arg, callable $callback, int $use_keys = 0): array {} -function array_map(?callable $callback, array ...$arrays): array {} +function array_map(?callable $callback, array $arr1, array ...$arrays): array {} -/** @param int|string $key */ -function array_key_exists($key, array $search): bool {} +/** + * @param int|string $key + * @param array|object $search + */ +function array_key_exists($key, $search): bool {} function array_chunk(array $arg, int $size, bool $preserve_keys = false): ?array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 3362a0c4776c4..7679e510e292d 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -115,15 +115,13 @@ ZEND_END_ARG_INFO() #define arginfo_next arginfo_prev -#define arginfo_reset arginfo_end +#define arginfo_reset arginfo_prev ZEND_BEGIN_ARG_INFO_EX(arginfo_current, 0, 0, 1) ZEND_ARG_INFO(0, arg) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_key, 0, 0, 1) - ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) -ZEND_END_ARG_INFO() +#define arginfo_key arginfo_current ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 1) ZEND_ARG_INFO(0, arg) @@ -153,7 +151,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_search, 0, 0, 2) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_extract, 0, 1, IS_LONG, 1) - ZEND_ARG_TYPE_INFO(ZEND_SEND_PREFER_REF, arg, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(2, arg, IS_ARRAY, 0) ZEND_ARG_INFO(0, extract_type) ZEND_ARG_TYPE_INFO(0, prefix, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -226,9 +224,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_keys, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, strict, _IS_BOOL, 0) ZEND_END_ARG_INFO() -#define arginfo_array_key_first arginfo_key +ZEND_BEGIN_ARG_INFO_EX(arginfo_array_key_first, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) +ZEND_END_ARG_INFO() -#define arginfo_array_key_last arginfo_key +#define arginfo_array_key_last arginfo_array_key_first ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_values, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) @@ -271,71 +271,45 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_key, 0, 2, IS_AR ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_ukey, 0, 3, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_ukey, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_INFO(0, callback_key_compare_func) + ZEND_ARG_VARIADIC_INFO(0, rest) ZEND_END_ARG_INFO() -#define arginfo_array_intersect arginfo_array_replace +#define arginfo_array_intersect arginfo_array_intersect_key -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect, 0, 3, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_INFO(0, callback_data_compare_func) -ZEND_END_ARG_INFO() +#define arginfo_array_uintersect arginfo_array_intersect_ukey -#define arginfo_array_intersect_assoc arginfo_array_replace +#define arginfo_array_intersect_assoc arginfo_array_intersect_key -#define arginfo_array_uintersect_assoc arginfo_array_uintersect +#define arginfo_array_uintersect_assoc arginfo_array_intersect_ukey -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_intersect_uassoc, 0, 3, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_key_compare_func, IS_CALLABLE, 0) -ZEND_END_ARG_INFO() +#define arginfo_array_intersect_uassoc arginfo_array_intersect_ukey -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_uintersect_uassoc, 0, 4, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_data_compare_func, IS_CALLABLE, 0) - ZEND_ARG_TYPE_INFO(0, callback_key_compare_func, IS_CALLABLE, 0) -ZEND_END_ARG_INFO() +#define arginfo_array_uintersect_uassoc arginfo_array_intersect_ukey -#define arginfo_array_diff_key arginfo_array_replace +#define arginfo_array_diff_key arginfo_array_intersect_key -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_diff_ukey, 0, 3, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_INFO(0, callback_key_comp_func) -ZEND_END_ARG_INFO() +#define arginfo_array_diff_ukey arginfo_array_intersect_ukey -#define arginfo_array_diff arginfo_array_replace +#define arginfo_array_diff arginfo_array_intersect_key -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_udiff, 0, 3, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_data_comp_func, IS_CALLABLE, 0) -ZEND_END_ARG_INFO() +#define arginfo_array_udiff arginfo_array_intersect_ukey -#define arginfo_array_diff_assoc arginfo_array_replace +#define arginfo_array_diff_assoc arginfo_array_intersect_key -#define arginfo_array_diff_uassoc arginfo_array_udiff +#define arginfo_array_diff_uassoc arginfo_array_intersect_ukey -#define arginfo_array_udiff_assoc arginfo_array_diff_ukey +#define arginfo_array_udiff_assoc arginfo_array_intersect_ukey -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_udiff_uassoc, 0, 4, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arr2, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, callback_data_comp_func, IS_CALLABLE, 0) - ZEND_ARG_TYPE_INFO(0, callback_key_comp_func, IS_CALLABLE, 0) -ZEND_END_ARG_INFO() +#define arginfo_array_udiff_uassoc arginfo_array_intersect_ukey ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_multisort, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arr1) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_order) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, sort_flags) - ZEND_ARG_VARIADIC_INFO(ZEND_SEND_PREFER_REF, arr2) + ZEND_ARG_INFO(2, arr1) + ZEND_ARG_INFO(2, sort_order) + ZEND_ARG_INFO(2, sort_flags) + ZEND_ARG_VARIADIC_INFO(2, arr2) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand, 0, 0, 1) @@ -343,9 +317,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_array_rand, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, num_req, IS_LONG, 0) ZEND_END_ARG_INFO() -#define arginfo_array_sum arginfo_key +#define arginfo_array_sum arginfo_array_key_first -#define arginfo_array_product arginfo_key +#define arginfo_array_product arginfo_array_key_first ZEND_BEGIN_ARG_INFO_EX(arginfo_array_reduce, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) @@ -359,14 +333,15 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_filter, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, use_keys, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_map, 0, 1, IS_ARRAY, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_map, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 1) + ZEND_ARG_TYPE_INFO(0, arr1, IS_ARRAY, 0) ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_key_exists, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, key) - ZEND_ARG_TYPE_INFO(0, search, IS_ARRAY, 0) + ZEND_ARG_INFO(0, search) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 1) diff --git a/scripts/dev/gen_stub.php b/scripts/dev/gen_stub.php index 2c084d5007f87..a4c02564700ab 100755 --- a/scripts/dev/gen_stub.php +++ b/scripts/dev/gen_stub.php @@ -108,29 +108,29 @@ public static function equals(?Type $a, ?Type $b): bool { } class ArgInfo { + const SEND_BY_VAL = 0; + const SEND_BY_REF = 1; + const SEND_PREFER_REF = 2; + /** @var string */ public $name; - /** @var bool */ - public $byRef; - /** @var bool */ - public $preferRef; + /** @var int */ + public $sendBy; /** @var bool */ public $isVariadic; /** @var Type|null */ public $type; - public function __construct(string $name, bool $byRef, bool $preferRef, bool $isVariadic, ?Type $type) { + public function __construct(string $name, int $sendBy, bool $isVariadic, ?Type $type) { $this->name = $name; - $this->byRef = $byRef; - $this->preferRef = $preferRef; + $this->sendBy = $sendBy; $this->isVariadic = $isVariadic; $this->type = $type; } public function equals(ArgInfo $other): bool { return $this->name === $other->name - && $this->byRef === $other->byRef - && $this->preferRef === $other->preferRef + && $this->sendBy === $other->sendBy && $this->isVariadic === $other->isVariadic && Type::equals($this->type, $other->type); } @@ -212,15 +212,29 @@ function parseFunctionLike(string $name, Node\FunctionLike $func, ?string $cond) $args = []; $numRequiredArgs = 0; + $foundVariadic = false; foreach ($func->getParams() as $i => $param) { $varName = $param->var->name; $preferRef = !empty($paramMeta[$varName]['preferRef']); unset($paramMeta[$varName]); + if ($preferRef) { + $sendBy = ArgInfo::SEND_PREFER_REF; + } else if ($param->byRef) { + $sendBy = ArgInfo::SEND_BY_REF; + } else { + $sendBy = ArgInfo::SEND_BY_VAL; + } + + if ($foundVariadic) { + throw new Exception("Error in function $name: only the last parameter can be variadic"); + } + + $foundVariadic = $param->variadic; + $args[] = new ArgInfo( $varName, - $param->byRef, - $preferRef, + $sendBy, $param->variadic, $param->type ? Type::fromNode($param->type) : null ); @@ -350,20 +364,20 @@ function funcInfoToCode(FuncInfo $funcInfo): string { if ($argInfo->type) { if ($argInfo->type->isBuiltin) { $code .= sprintf( - "\tZEND_%s_TYPE_INFO(%s, %s, %s, %d)\n", - $argKind, send_by($argInfo), $argInfo->name, + "\tZEND_%s_TYPE_INFO(%d, %s, %s, %d)\n", + $argKind, $argInfo->sendBy, $argInfo->name, $argInfo->type->toTypeCode(), $argInfo->type->isNullable ); } else { $code .= sprintf( - "\tZEND_%s_OBJ_INFO(%s, %s, %s, %d)\n", - $argKind, send_by($argInfo), $argInfo->name, + "\tZEND_%s_OBJ_INFO(%d, %s, %s, %d)\n", + $argKind, $argInfo->sendBy, $argInfo->name, $argInfo->type->name, $argInfo->type->isNullable ); } } else { $code .= sprintf( - "\tZEND_%s_INFO(%s, %s)\n", $argKind, send_by($argInfo), $argInfo->name); + "\tZEND_%s_INFO(%d, %s)\n", $argKind, $argInfo->sendBy, $argInfo->name); } } @@ -371,16 +385,6 @@ function funcInfoToCode(FuncInfo $funcInfo): string { return $code; } -function send_by(ArgInfo $arg): string { - if ($arg->preferRef) { - return 'ZEND_SEND_PREFER_REF'; - } else if ($arg->byRef) { - return '1'; - } else { - return '0'; - } -} - function findEquivalentFuncInfo(array $generatedFuncInfos, $funcInfo): ?FuncInfo { foreach ($generatedFuncInfos as $generatedFuncInfo) { if ($generatedFuncInfo->equalsApartFromName($funcInfo)) { From cc1873aefd8d1b7783334071db337fcc681b8c81 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Wed, 21 Aug 2019 18:41:15 -0500 Subject: [PATCH 09/10] Update return type for range, array_chunk, and array_combine --- ext/standard/array.c | 2 +- ext/standard/basic_functions.stub.php | 8 +++----- ext/standard/basic_functions_arginfo.h | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 164b7da046993..5f4286d772fff 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -6334,7 +6334,7 @@ PHP_FUNCTION(array_key_exists) } /* }}} */ -/* {{{ proto array|null array_chunk(array input, int size [, bool preserve_keys]) +/* {{{ proto array array_chunk(array input, int size [, bool preserve_keys]) Split array into chunks */ PHP_FUNCTION(array_chunk) { diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 050811d1d94a7..d4bdd3ad095bb 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -152,9 +152,8 @@ function array_fill_keys(array $keys, $val): array {} * @param int|float|string $low * @param int|float|string $high * @param int|float $step - * @return array|false */ -function range($low, $high, $step = 1) {} +function range($low, $high, $step = 1): array {} function shuffle(array &$arg): bool {} @@ -269,10 +268,9 @@ function array_map(?callable $callback, array $arr1, array ...$arrays): array {} */ function array_key_exists($key, $search): bool {} -function array_chunk(array $arg, int $size, bool $preserve_keys = false): ?array {} +function array_chunk(array $arg, int $size, bool $preserve_keys = false): array {} -/** @return array|false */ -function array_combine(array $keys, array $values) {} +function array_combine(array $keys, array $values): array {} /* base64.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 63f1c316652dc..8a01e0ff817d1 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -172,7 +172,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_fill_keys, 0, 2, IS_ARRAY, ZEND_ARG_INFO(0, val) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_range, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_range, 0, 2, IS_ARRAY, 0) ZEND_ARG_INFO(0, low) ZEND_ARG_INFO(0, high) ZEND_ARG_INFO(0, step) @@ -344,13 +344,13 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_key_exists, 0, 2, _IS_BOOL ZEND_ARG_INFO(0, search) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_chunk, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, size, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, preserve_keys, _IS_BOOL, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_combine, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_combine, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, values, IS_ARRAY, 0) ZEND_END_ARG_INFO() From ae1dfe51dca9c5f53d0692cf91f6d0a4465cae15 Mon Sep 17 00:00:00 2001 From: Theodore Brown Date: Thu, 22 Aug 2019 13:55:59 -0500 Subject: [PATCH 10/10] Update return types for array_column and array_pad --- ext/standard/array.c | 2 +- ext/standard/basic_functions.stub.php | 6 ++---- ext/standard/basic_functions_arginfo.h | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 01d19e6691dd1..e1b9a78e38c6f 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4176,7 +4176,7 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /* } /* }}} */ -/* {{{ proto array|false array_column(array input, mixed column_key[, mixed index_key]) +/* {{{ proto array array_column(array input, mixed column_key[, mixed index_key]) Return the values from a single column in the input array, identified by the value_key and optionally indexed by the index_key */ PHP_FUNCTION(array_column) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index d4bdd3ad095bb..7d979601fe124 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -192,14 +192,12 @@ function array_count_values(array $arg): array {} /** * @param int|string|null $column_key * @param int|string|null $index_key - * @return array|false */ -function array_column(array $arg, $column_key, $index_key = null) {} +function array_column(array $arg, $column_key, $index_key = null): array {} function array_reverse(array $input, bool $preserve_keys = false): array {} -/** @return array|false */ -function array_pad(array $arg, int $pad_size, $pad_value) {} +function array_pad(array $arg, int $pad_size, $pad_value): array {} function array_flip(array $arg): array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 8a01e0ff817d1..2967bfa61cf68 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -236,7 +236,7 @@ ZEND_END_ARG_INFO() #define arginfo_array_count_values arginfo_array_values -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_column, 0, 0, 2) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_column, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) ZEND_ARG_INFO(0, column_key) ZEND_ARG_INFO(0, index_key) @@ -247,7 +247,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_reverse, 0, 1, IS_ARRAY, 0 ZEND_ARG_TYPE_INFO(0, preserve_keys, _IS_BOOL, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_array_pad, 0, 0, 3) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_pad, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, arg, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, pad_size, IS_LONG, 0) ZEND_ARG_INFO(0, pad_value)