Skip to content
Permalink
Browse files

Improve array function types (#2566)

* Improve sorting function out types

* Improve return types of array_diff_assoc(), array_intersect_assoc()

* Fix versionCompareAsCallable test
  • Loading branch information
ShiraNai7 authored and muglug committed Jan 7, 2020
1 parent 90d6b73 commit 702ca34c412b20e0e93a8b62275df4d0bb1f3374
@@ -729,10 +729,8 @@ private static function handleByRefFunctionArg(
);

$builtin_array_functions = [
'shuffle', 'sort', 'rsort', 'usort', 'ksort', 'asort',
'uasort',
'krsort', 'arsort', 'natcasesort', 'natsort', 'reset',
'end', 'next', 'prev', 'array_pop', 'array_shift',
'ksort', 'asort', 'krsort', 'arsort', 'natcasesort', 'natsort',
'reset', 'end', 'next', 'prev', 'array_pop', 'array_shift',
];

if (($var_id && isset($context->vars_in_scope[$var_id]))
@@ -791,12 +789,7 @@ private static function handleByRefFunctionArg(
$array_type = new TArray([Type::getInt(), $array_type->type_param]);
}

if (in_array($method_id, ['shuffle', 'sort', 'rsort', 'usort'], true)) {
$tvalue = $array_type->type_params[1];
$by_ref_type = new Type\Union([new TArray([Type::getInt(), clone $tvalue])]);
} else {
$by_ref_type = new Type\Union([clone $array_type]);
}
$by_ref_type = new Type\Union([clone $array_type]);

ExpressionAnalyzer::assignByRefParam(
$statements_analyzer,
@@ -1630,9 +1623,8 @@ private static function handlePossiblyMatchingByRefParam(
if (!in_array(
$method_id,
[
'shuffle', 'sort', 'rsort', 'usort', 'ksort', 'asort',
'krsort', 'arsort', 'natcasesort', 'natsort', 'reset',
'end', 'next', 'prev', 'array_pop', 'array_shift',
'ksort', 'asort', 'krsort', 'arsort', 'natcasesort', 'natsort',
'reset', 'end', 'next', 'prev', 'array_pop', 'array_shift',
'array_push', 'array_unshift', 'socket_select', 'array_splice',
],
true
@@ -43,6 +43,19 @@ function array_intersect_key(array $arr, array $arr2, array ...$arr3)
{
}

/**
* @psalm-template TKey as array-key
* @psalm-template TValue
*
* @param array<TKey, TValue> $arr
*
* @return array<TKey, TValue>
* @psalm-pure
*/
function array_intersect_assoc(array $arr, array $arr2, array ...$arr3)
{
}

/**
* @psalm-template TKey as array-key
* @psalm-template TValue
@@ -88,6 +101,21 @@ function array_diff_key(array $arr, array $arr2, array ...$arr3)
{
}

/**
* @psalm-template TKey as array-key
* @psalm-template TValue
*
* @param array<TKey, TValue> $arr
* @param array $arr2
* @param array ...$arr3
*
* @return array<TKey, TValue>
* @psalm-pure
*/
function array_diff_assoc(array $arr, array $arr2, array ...$arr3)
{
}

/**
* @psalm-template TKey as array-key
* @psalm-template TValue
@@ -155,29 +183,49 @@ function array_search($needle, array $haystack, bool $strict = false)
}

/**
* @template T
* @psalm-template T
*
* @param array<mixed,T> $arr
* @param T[] $arr
* @param-out list<T> $arr
*/
function sort(array &$arr, int $sort_flags = \SORT_REGULAR): bool
function shuffle(array &$arr): bool
{
}

/**
* @template T
* @psalm-template T
*
* @param array<mixed,T> $arr
* @param T[] $arr
* @param-out list<T> $arr
*/
function sort(array &$arr, int $sort_flags = SORT_REGULAR): bool
{
}

/**
* @psalm-template T
*
* @param T[] $arr
* @param-out list<T> $arr
*/
function rsort(array &$arr, int $sort_flags = SORT_REGULAR): bool
{
}

/**
* @psalm-template T
*
* @param T[] $arr
* @param callable(T,T):int $callback
* @param-out array<int,T> $arr
* @param-out list<T> $arr
*/
function usort(array &$arr, callable $callback): bool
{
}

/**
* @template TKey
* @template T
* @psalm-template TKey
* @psalm-template T
*
* @param array<TKey,T> $arr
* @param callable(T,T):int $callback
@@ -187,6 +235,18 @@ function uasort(array &$arr, callable $callback): bool
{
}

/**
* @psalm-template TKey
* @psalm-template T
*
* @param array<TKey,T> $arr
* @param callable(TKey,TKey):int $callback
* @param-out array<TKey,T> $arr
*/
function uksort(array &$arr, callable $callback): bool
{
}

/**
* @psalm-template T
*
@@ -241,7 +301,7 @@ function array_fill_keys(array $keys, $value): array
}

/**
* @template TKey
* @psalm-template TKey
*
* @param string $pattern
* @param array<TKey,string> $input
@@ -26,7 +26,7 @@ public function providerValidCodeParse()
',
'assertions' => [
'$a' => 'array{a: int, b: int}',
'$b' => 'array<int, int>',
'$b' => 'list<int>',
],
],
'arrayModificationFunctions' => [
@@ -307,6 +307,18 @@ function bar(array $list) : array {
array_diff_key([], [], [], [], []);',
'assertions' => [],
],
'arrayDiffAssoc' => [
'<?php
/**
* @var array<string, int> $a
* @var array $b
* @var array $c
*/
$r = array_diff_assoc($a, $b, $c);',
'assertions' => [
'$r' => 'array<string, int>',
],
],
'arrayPopMixed' => [
'<?php
/** @var mixed */
@@ -572,6 +584,19 @@ function (int $a, int $b) {
'$manifest' => 'array<string, int>'
],
],
'uksort' => [
'<?php
$array = ["b" => 1, "a" => 2];
uksort(
$array,
function (string $a, string $b) {
return $a <=> $b;
}
);',
'assertions' => [
'$array' => 'array<string, int>',
],
],
'byRefAfterCallable' => [
'<?php
/**
@@ -1309,6 +1334,18 @@ function sdn(array $s) : void {
if (empty($r)) {}
}',
],
'arrayIntersectAssoc' => [
'<?php
/**
* @var array<string, int> $a
* @var array $b
* @var array $c
*/
$r = array_intersect_assoc($a, $b, $c);',
'assertions' => [
'$r' => 'array<string, int>',
],
],
'arrayReduce' => [
'<?php
$arr = [2, 3, 4, 5];
@@ -2054,7 +2091,7 @@ function getObject() : iterable{
'versionCompareAsCallable' => [
'<?php
$a = ["1.0", "2.0"];
uksort($a, "version_compare");',
usort($a, "version_compare");',
],
'coerceToObjectAfterBeingCalled' => [
'<?php
@@ -2353,6 +2390,38 @@ function getCharPairs(string $line) : array {
'$result' => 'array<int, true>',
],
],
'shuffle' => [
'<?php
$array = ["foo" => 123, "bar" => 456];
shuffle($array);',
'assertions' => [
'$array' => 'list<int>',
],
],
'sort' => [
'<?php
$array = ["foo" => 123, "bar" => 456];
sort($array);',
'assertions' => [
'$array' => 'list<int>',
],
],
'rsort' => [
'<?php
$array = ["foo" => 123, "bar" => 456];
sort($array);',
'assertions' => [
'$array' => 'list<int>',
],
],
'usort' => [
'<?php
$array = ["foo" => 123, "bar" => 456];
usort($array, function (int $a, int $b) { return $a <=> $b; });',
'assertions' => [
'$array' => 'list<int>',
],
],
];
}

0 comments on commit 702ca34

Please sign in to comment.
You can’t perform that action at this time.