diff --git a/resources/functionMap.php b/resources/functionMap.php index 8674d73318..1ace8423df 100644 --- a/resources/functionMap.php +++ b/resources/functionMap.php @@ -8822,6 +8822,13 @@ 'RedisArray::_hosts' => ['array'], 'RedisArray::_rehash' => ['', 'callable='=>'callable'], 'RedisArray::_target' => ['string', 'key'=>'string'], +'RedisArray::hscan' => ['__benevolent|false>', 'key'=>'string', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'int'], +'RedisArray::info' => ['__benevolent>|false>'], +'RedisArray::keys' => ['__benevolent>|false>', 'pattern'=>'string'], +'RedisArray::mget' => ['__benevolent|false>', 'keys'=>'string[]'], +'RedisArray::scan' => ['__benevolent|false>', '&iterator'=>'?int', 'node'=>'string', 'pattern='=>'?string', 'count='=>'?int'], +'RedisArray::sscan' => ['__benevolent|false>', 'key'=>'string', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'int'], +'RedisArray::zscan' => ['__benevolent|false>', 'key'=>'string', '&iterator'=>'?int', 'pattern='=>'?string', 'count='=>'int'], 'RedisCluster::__construct' => ['void', 'name'=>'string|null', 'seeds='=>'string[]|null', 'timeout='=>'int|float', 'read_timeout='=>'int|float', 'persistent='=>'bool', 'auth='=>'mixed', 'context='=>'array|null'], 'RedisCluster::_prefix' => ['string', 'value'=>'mixed'], 'RedisCluster::_serialize' => ['mixed', 'value'=>'mixed'], diff --git a/stubs/Redis.stub b/stubs/Redis.stub index 072475482f..f713d4e5f1 100644 --- a/stubs/Redis.stub +++ b/stubs/Redis.stub @@ -5,6 +5,11 @@ */ class Redis {} +/** + * @phpstan-all-methods-impure + */ +class RedisArray {} + /** * @phpstan-all-methods-impure */ diff --git a/tests/PHPStan/Analyser/nsrt/bug-9748.php b/tests/PHPStan/Analyser/nsrt/bug-9748.php new file mode 100644 index 0000000000..3a061f4ff5 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-9748.php @@ -0,0 +1,60 @@ +keys('*'); + assertType('(array>|false)', $keys); + if ($keys === false) { + return; + } + assertType('array>', $keys); + foreach ($keys as $host => $hostKeys) { + assertType('string', $host); + assertType('list', $hostKeys); + foreach ($hostKeys as $i => $hostKey) { + assertType('int<0, max>', $i); + assertType('string', $hostKey); + } + } +} + +function testInfo(\RedisArray $ra): void { + $info = $ra->info(); + assertType('(array>|false)', $info); + if ($info === false) { + return; + } + assertType('array>', $info); +} + +function testMget(\RedisArray $ra): void { + $values = $ra->mget(['key1', 'key2']); + assertType('(list|false)', $values); +} + +function testScan(\RedisArray $ra): void { + $iterator = null; + $result = $ra->scan($iterator, 'node1'); + assertType('(list|false)', $result); +} + +function testHscan(\RedisArray $ra): void { + $iterator = null; + $result = $ra->hscan('myhash', $iterator); + assertType('(array|false)', $result); +} + +function testSscan(\RedisArray $ra): void { + $iterator = null; + $result = $ra->sscan('myset', $iterator); + assertType('(list|false)', $result); +} + +function testZscan(\RedisArray $ra): void { + $iterator = null; + $result = $ra->zscan('myzset', $iterator); + assertType('(array|false)', $result); +}