[ 'code' => ' [ '$keys' => 'list', ], ], 'arrayKeysOfKeyedArrayReturnsNonEmptyListOfStrings' => [ 'code' => ' "bar"]); ', 'assertions' => [ '$keys' => 'non-empty-list', ], ], 'arrayKeysOfListReturnsNonEmptyListOfInts' => [ 'code' => ' [ '$keys' => 'non-empty-list>', ], ], 'arrayKeysOfKeyedStringIntArrayReturnsNonEmptyListOfIntsOrStrings' => [ 'code' => ' "bar", 42]); ', 'assertions' => [ '$keys' => 'non-empty-list', ], ], 'arrayKeysOfArrayConformsToArrayKeys' => [ 'code' => ' */ function getKeys(array $array) { return array_keys($array); } ', ], 'arrayKeysOfKeyedArrayConformsToCorrectLiteralStringList' => [ 'code' => ' */ function getKeys() { return array_keys(["foo" => 42, "bar" => 42]); } ', ], 'arrayKeysOfLiteralListConformsToCorrectLiteralOffsets' => [ 'code' => ' */ function getKeys() { return array_keys(["foo", "bar"]); } ', ], 'arrayKeyFirstOfLiteralListConformsToCorrectLiteralOffsets' => [ 'code' => ' [ 'code' => ' [ 'code' => ' [ "from" => "79268724911", "to" => "74950235931", ], "b" => [ "from" => "79313044964", "to" => "78124169167", ], ]; private const SIP_FORMAT = "sip:%s@voip.test.com:9090"; /** @return array */ public function test(): array { $redirects = []; foreach (self::REDIRECTS as $redirect) { $redirects[$redirect["from"]] = sprintf(self::SIP_FORMAT, $redirect["to"]); } return $redirects; } }', ], 'variousArrayKeys' => [ 'code' => ' * * @template TOrig as a|b * @template TT as class-string * * @template TBool as bool */ class b { /** * @var array */ private array $a = [123 => 123]; /** @var array, int> */ public array $c = []; /** @var array, int> */ public array $d = []; /** @var array */ public array $e = []; /** @var array>, int> */ private array $f = [123 => 123]; /** @var array>, int> */ private array $g = ["test" => 123]; /** @var array */ private array $h = [123 => 123]; /** * @return array<$v is true ? "a" : 123, 123> */ public function test(bool $v): array { return $v ? ["a" => 123] : [123 => 123]; } } /** @var b<"testKey", "testValue", array<"testKey", "testValue">, b, class-string, true> */ $b = new b; $b->d["testKey"] = 123; // TODO //$b->c["testValue"] = 123; //$b->e["b"] = 123; ', ], 'intStringKeyAsInt' => [ 'code' => ' "a"]; $b = ["15.7" => "a"]; // since PHP 8 this is_numeric but will not be int key $c = ["15 " => "a"]; $d = ["-15" => "a"]; // see https://github.com/php/php-src/issues/9029#issuecomment-1186226676 $e = ["+15" => "a"]; $f = ["015" => "a"]; $g = ["1e2" => "a"]; $h = ["1_0" => "a"]; ', 'assertions' => [ '$a===' => "array{15: 'a'}", '$b===' => "array{'15.7': 'a'}", '$c===' => "array{'15 ': 'a'}", '$d===' => "array{-15: 'a'}", '$e===' => "array{'+15': 'a'}", '$f===' => "array{'015': 'a'}", '$g===' => "array{'1e2': 'a'}", '$h===' => "array{'1_0': 'a'}", ], ], ]; } public function providerInvalidCodeParse(): iterable { return [ 'arrayKeysOfStringArrayDoesntConformsToIntList' => [ 'code' => ' $array * @return list */ function getKeys(array $array) { return array_keys($array); } ', 'error_message' => 'InvalidReturnStatement', ], 'arrayKeysOfStringKeyedArrayDoesntConformToIntList' => [ 'code' => ' */ function getKeys() { return array_keys(["foo" => 42, "bar" => 42]); } ', 'error_message' => 'InvalidReturnStatement', ], 'literalStringAsIntArrayKey' => [ 'code' => ' [ "from" => "79268724911", "to" => "74950235931", ], "b" => [ "from" => "79313044964", "to" => "78124169167", ], ]; private const SIP_FORMAT = "sip:%s@voip.test.com:9090"; /** @return array */ public function test(): array { $redirects = []; foreach (self::REDIRECTS as $redirect) { $redirects[$redirect["from"]] = sprintf(self::SIP_FORMAT, $redirect["to"]); } return $redirects; } }', 'error_message' => 'InvalidReturnStatement', ], ]; } }