From 23543218dcb7090593ccb92441d53dac879c7b77 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Thu, 18 Jan 2024 12:59:56 +0100 Subject: [PATCH 1/2] Fix template, conditional array keys --- src/Psalm/Internal/Type/TypeParser.php | 9 +++- tests/ArrayKeysTest.php | 58 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/Psalm/Internal/Type/TypeParser.php b/src/Psalm/Internal/Type/TypeParser.php index e908c4e3a1d..ecdd5910c86 100644 --- a/src/Psalm/Internal/Type/TypeParser.php +++ b/src/Psalm/Internal/Type/TypeParser.php @@ -672,8 +672,8 @@ private static function getTypeFromGenericTree( // PHP 8 values with whitespace after number are counted as numeric // and filter_var treats them as such too if ($atomic_type instanceof TLiteralString - && trim($atomic_type->value) === $atomic_type->value && ($string_to_int = filter_var($atomic_type->value, FILTER_VALIDATE_INT)) !== false + && trim($atomic_type->value) === $atomic_type->value ) { $builder = $generic_params[0]->getBuilder(); $builder->removeType($key); @@ -688,7 +688,14 @@ private static function getTypeFromGenericTree( || $atomic_type instanceof TMixed || $atomic_type instanceof TNever || $atomic_type instanceof TTemplateParam + || $atomic_type instanceof TTemplateIndexedAccess + || $atomic_type instanceof TTemplateValueOf + || $atomic_type instanceof TTemplateKeyOf + || $atomic_type instanceof TTemplateParamClass + || $atomic_type instanceof TTypeAlias || $atomic_type instanceof TValueOf + || $atomic_type instanceof TConditional + || $atomic_type instanceof TKeyOf || !$from_docblock ) { continue; diff --git a/tests/ArrayKeysTest.php b/tests/ArrayKeysTest.php index e3f9cc897a4..d2c363f940e 100644 --- a/tests/ArrayKeysTest.php +++ b/tests/ArrayKeysTest.php @@ -124,6 +124,64 @@ public function test(): array { } }', ], + 'variousArrayKeys' => [ + 'code' => ' + * @template TT + * @template TBool as bool + */ + class b { + /** + * @var array + */ + private array $a = []; + + /** @var array, int> */ + private array $c = []; + + /** @var array, int> */ + private array $d = []; + + /** @var array */ + private array $e = []; + + /** @var array>, int> */ + private array $f = []; + + /** @var array>, int> */ + private array $g = []; + + /** @var array */ + private array $h = []; + + /** + * @param T $arr + * @param class-string $b + * @param TBool $c + */ + public function __construct( + array $arr, + string $b, + bool $c + ) {} + + /** + * @return array<$v is true ? "a" : 123, 123> + */ + public function test(bool $v): array { + return $v ? ["a" => 123] : [123 => 123]; + } + }', + ], ]; } From 94efd67515026e2998a9b46a03dc52ebab658c27 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Thu, 18 Jan 2024 13:10:32 +0100 Subject: [PATCH 2/2] Improve tests --- tests/ArrayKeysTest.php | 45 +++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/tests/ArrayKeysTest.php b/tests/ArrayKeysTest.php index d2c363f940e..659cd5af5df 100644 --- a/tests/ArrayKeysTest.php +++ b/tests/ArrayKeysTest.php @@ -136,43 +136,35 @@ class a {} * @template TKey as array-key * @template TValue as array-key * @template T as array - * @template TT + * + * @template TOrig as a|b + * @template TT as class-string + * * @template TBool as bool */ class b { /** * @var array */ - private array $a = []; + private array $a = [123 => 123]; /** @var array, int> */ - private array $c = []; + public array $c = []; /** @var array, int> */ - private array $d = []; + public array $d = []; /** @var array */ - private array $e = []; + public array $e = []; - /** @var array>, int> */ - private array $f = []; + /** @var array>, int> */ + private array $f = [123 => 123]; - /** @var array>, int> */ - private array $g = []; + /** @var array>, int> */ + private array $g = ["test" => 123]; /** @var array */ - private array $h = []; - - /** - * @param T $arr - * @param class-string $b - * @param TBool $c - */ - public function __construct( - array $arr, - string $b, - bool $c - ) {} + private array $h = [123 => 123]; /** * @return array<$v is true ? "a" : 123, 123> @@ -180,7 +172,16 @@ public function __construct( 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; + ', ], ]; }