From c728ffa0d19a97dfb39206d127c55b1120b8eb32 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 27 Feb 2024 19:10:35 +0100 Subject: [PATCH] Update --- .../Analyzer/Statements/Block/ForeachAnalyzer.php | 2 +- .../Statements/Expression/Call/ArgumentsAnalyzer.php | 3 ++- .../Expression/Call/ArrayFunctionArgumentsAnalyzer.php | 2 +- .../Expression/Call/FunctionCallReturnTypeFetcher.php | 5 +++-- .../Statements/Expression/Fetch/ArrayFetchAnalyzer.php | 6 +++--- .../Analyzer/Statements/Expression/SimpleTypeInferer.php | 2 +- src/Psalm/Internal/Codebase/ConstantTypeResolver.php | 2 +- .../ReturnTypeProvider/ArrayColumnReturnTypeProvider.php | 2 +- .../ArrayFillKeysReturnTypeProvider.php | 2 +- .../ReturnTypeProvider/ArrayMapReturnTypeProvider.php | 2 +- .../ReturnTypeProvider/ArrayMergeReturnTypeProvider.php | 2 +- src/Psalm/Internal/Type/SimpleAssertionReconciler.php | 4 ++-- .../Internal/Type/SimpleNegatedAssertionReconciler.php | 3 ++- src/Psalm/Internal/Type/TypeCombiner.php | 2 +- .../Internal/TypeVisitor/ContainsLiteralVisitor.php | 3 ++- src/Psalm/Type/Atomic.php | 3 ++- src/Psalm/Type/Atomic/TArray.php | 9 ++------- src/Psalm/Type/Reconciler.php | 2 +- src/Psalm/Type/UnionTrait.php | 4 +--- 19 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php index d71628cdfb9..cbb634ec696 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php @@ -457,7 +457,7 @@ public static function checkIteratorType( } // if it's an empty array, we cannot iterate over it - if ($iterator_atomic_type instanceof TArray && $iterator_atomic_type->isEmptyArray()) { + if ($iterator_atomic_type instanceof TArray && $iterator_atomic_type->isEmpty()) { $always_non_empty_array = false; $has_valid_iterator = true; continue; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php index bbff33c81a5..8b70b6ee084 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php @@ -41,6 +41,7 @@ use Psalm\Storage\FunctionLikeStorage; use Psalm\Storage\MethodStorage; use Psalm\Type; +use Psalm\Type\Atomic\ArrayInterface; use Psalm\Type\Atomic\TArray; use Psalm\Type\Atomic\TCallable; use Psalm\Type\Atomic\TCallableKeyedArray; @@ -1236,7 +1237,7 @@ private static function evaluateArbitraryParam( $t = $context->vars_in_scope[$var_id]->getBuilder(); foreach ($t->getAtomicTypes() as $k => $type) { - if ($type instanceof TArray && $type->isEmptyArray()) { + if ($type instanceof ArrayInterface && $type->isEmpty()) { $t->removeType($k); $t->addType( new TArray( diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php index b6f6c8e0ebe..f7651e807d6 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php @@ -279,7 +279,7 @@ public static function handleAddition( array_unshift($properties, $arg_value_type); $by_ref_type = new Union([$objectlike_list->setProperties($properties)]); - } elseif ($array_type instanceof TArray && $array_type->isEmptyArray()) { + } elseif ($array_type instanceof TArray && $array_type->isEmpty()) { $by_ref_type = new Union([new TKeyedArray([ $arg_value_type, ], null, null, true)]); diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php index 1007b9d8855..e9d312c012b 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallReturnTypeFetcher.php @@ -25,6 +25,7 @@ use Psalm\Plugin\EventHandler\Event\AfterFunctionCallAnalysisEvent; use Psalm\Storage\FunctionLikeStorage; use Psalm\Type; +use Psalm\Type\Atomic\ArrayInterface; use Psalm\Type\Atomic\TArray; use Psalm\Type\Atomic\TCallable; use Psalm\Type\Atomic\TCallableKeyedArray; @@ -383,8 +384,8 @@ private static function getReturnTypeFromCallMapWithArgs( return Type::getIntRange($min, $max); } - if ($atomic_types['array'] instanceof TArray - && $atomic_types['array']->isEmptyArray() + if ($atomic_types['array'] instanceof ArrayInterface + && $atomic_types['array']->isEmpty() ) { return Type::getInt(false, 0); } diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php index 9afcc869afd..6ff280671a4 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php @@ -1120,7 +1120,7 @@ private static function handleArrayAccessOnArray( if ($in_assignment) { if ($type instanceof TArray) { - $from_empty_array = $type->isEmptyArray(); + $from_empty_array = $type->isEmpty(); if (count($key_values) === 1) { $single_atomic = $key_values[0]; @@ -1249,7 +1249,7 @@ private static function handleArrayAccessOnTArray( ): void { // if we're assigning to an empty array with a key offset, refashion that array if ($in_assignment) { - if ($type->isEmptyArray()) { + if ($type->isEmpty()) { $type = $type->setTypeParams([ $offset_type->isMixed() ? Type::getArrayKey() @@ -1257,7 +1257,7 @@ private static function handleArrayAccessOnTArray( $type->type_params[1], ]); } - } elseif (!$type->isEmptyArray()) { + } elseif (!$type->isEmpty()) { $expected_offset_type = $type->type_params[0]->hasMixed() ? new Union([new TArrayKey]) : $type->type_params[0]; diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php index 93b6d68ea48..12cb32af27c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/SimpleTypeInferer.php @@ -823,7 +823,7 @@ private static function handleUnpackedArray( ); } } elseif ($unpacked_atomic_type instanceof TArray) { - if ($unpacked_atomic_type->isEmptyArray()) { + if ($unpacked_atomic_type->isEmpty()) { continue; } $array_creation_info->can_create_objectlike = false; diff --git a/src/Psalm/Internal/Codebase/ConstantTypeResolver.php b/src/Psalm/Internal/Codebase/ConstantTypeResolver.php index 35d0c77058d..0d45f8d71ec 100644 --- a/src/Psalm/Internal/Codebase/ConstantTypeResolver.php +++ b/src/Psalm/Internal/Codebase/ConstantTypeResolver.php @@ -210,7 +210,7 @@ public static function resolve( $visited_constant_ids + [$c_id => true], ); - if ($spread_array instanceof TArray && $spread_array->isEmptyArray()) { + if ($spread_array instanceof TArray && $spread_array->isEmpty()) { continue; } diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php index 4f731d1ea0a..d51714d8cb4 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php @@ -108,7 +108,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev continue; } if (!$row_shape instanceof TKeyedArray) { - if ($row_shape instanceof TArray && $row_shape->isEmptyArray()) { + if ($row_shape instanceof TArray && $row_shape->isEmpty()) { continue; } $ok = false; diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php index 790b37bb298..7d79379030b 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayFillKeysReturnTypeProvider.php @@ -47,7 +47,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev ) { $results = []; foreach ($first_arg_type->getArrays() as $array) { - if ($array instanceof TArray && $array->isEmptyArray()) { + if ($array instanceof TArray && $array->isEmpty()) { $results []= $array; continue; } elseif ($array instanceof TKeyedArray && !$array->fallback_params) { diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php index 431a21e0043..620a035ab3e 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMapReturnTypeProvider.php @@ -98,7 +98,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev } elseif ($call_arg_type && $call_arg_type->isSingle() && ($call_arg_atomic = $call_arg_type->getSingleAtomic()) instanceof TArray - && $call_arg_atomic->isEmptyArray() + && $call_arg_atomic->isEmpty() ) { $array_arg_types []= []; $orig_types []= $call_arg_type; diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php index 4efeda3d5f2..de093518e05 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayMergeReturnTypeProvider.php @@ -202,7 +202,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev } if ($unpacked_type_part instanceof TArray) { - if ($unpacked_type_part->isEmptyArray()) { + if ($unpacked_type_part->isEmpty()) { continue; } diff --git a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php index 70f2b78a9c6..ab7b4009443 100644 --- a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php @@ -637,7 +637,7 @@ private static function reconcileNonEmptyCountable( || ($assertion instanceof HasAtLeastCount && $array_atomic_type->min_count < $assertion->count) ) { - if ($array_atomic_type->isEmptyArray()) { + if ($array_atomic_type->isEmpty()) { $existing_var_type->removeType($k); } else { $non_empty_array = new TNonEmptyArray( @@ -2399,7 +2399,7 @@ private static function reconcileList( } } - if ($type->isEmptyArray()) { + if ($type->isEmpty()) { //we allow an empty array to pass as a list. We keep the type as empty array though (more precise) $array_types[] = $type; } diff --git a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php index 00a8166c5a5..88fb36fb6fd 100644 --- a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php @@ -24,6 +24,7 @@ use Psalm\Storage\Assertion\NotInArray; use Psalm\Storage\Assertion\NotNonEmptyCountable; use Psalm\Type; +use Psalm\Type\Atomic\ArrayInterface; use Psalm\Type\Atomic\Scalar; use Psalm\Type\Atomic\TArray; use Psalm\Type\Atomic\TArrayKey; @@ -630,7 +631,7 @@ private static function reconcileNotNonEmptyCountable( )); } } - } elseif (!$array_atomic_type instanceof TArray || !$array_atomic_type->isEmptyArray()) { + } elseif (!$array_atomic_type instanceof ArrayInterface || !$array_atomic_type->isEmpty()) { $redundant = false; if (!$count) { diff --git a/src/Psalm/Internal/Type/TypeCombiner.php b/src/Psalm/Internal/Type/TypeCombiner.php index 2abaedef7b7..95a47ecf1ba 100644 --- a/src/Psalm/Internal/Type/TypeCombiner.php +++ b/src/Psalm/Internal/Type/TypeCombiner.php @@ -588,7 +588,7 @@ private static function scrapeTypeProperties( $combination->array_always_filled = false; } - if (!$type->isEmptyArray()) { + if (!$type->isEmpty()) { $combination->all_arrays_lists = false; $combination->all_arrays_class_string_maps = false; } diff --git a/src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php b/src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php index dfea8289159..ae546885675 100644 --- a/src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php +++ b/src/Psalm/Internal/TypeVisitor/ContainsLiteralVisitor.php @@ -4,6 +4,7 @@ namespace Psalm\Internal\TypeVisitor; +use Psalm\Type\Atomic\ArrayInterface; use Psalm\Type\Atomic\TArray; use Psalm\Type\Atomic\TFalse; use Psalm\Type\Atomic\TLiteralFloat; @@ -32,7 +33,7 @@ protected function enterNode(TypeNode $type): ?int return self::STOP_TRAVERSAL; } - if ($type instanceof TArray && $type->isEmptyArray()) { + if ($type instanceof ArrayInterface && $type->isEmpty()) { $this->contains_literal = true; return self::STOP_TRAVERSAL; } diff --git a/src/Psalm/Type/Atomic.php b/src/Psalm/Type/Atomic.php index d8e284bc346..ecc92269155 100644 --- a/src/Psalm/Type/Atomic.php +++ b/src/Psalm/Type/Atomic.php @@ -15,6 +15,7 @@ use Psalm\Internal\TypeVisitor\ClasslikeReplacer; use Psalm\Storage\UnserializeMemoryUsageSuppressionTrait; use Psalm\Type; +use Psalm\Type\Atomic\ArrayInterface; use Psalm\Type\Atomic\TArray; use Psalm\Type\Atomic\TArrayKey; use Psalm\Type\Atomic\TBool; @@ -908,7 +909,7 @@ public function isFalsy(): bool return true; } - if ($this instanceof TArray && $this->isEmptyArray()) { + if ($this instanceof ArrayInterface && $this->isEmpty()) { return true; } diff --git a/src/Psalm/Type/Atomic/TArray.php b/src/Psalm/Type/Atomic/TArray.php index f3587ae47cc..6c8cfb8243e 100644 --- a/src/Psalm/Type/Atomic/TArray.php +++ b/src/Psalm/Type/Atomic/TArray.php @@ -63,11 +63,11 @@ public function getMaxCount(): ?int } public function getCount(): ?int { - return $this->isEmptyArray() ? 0 : null; + return $this->isEmpty() ? 0 : null; } public function isEmpty(): bool { - return $this->isEmptyArray(); + return $this->type_params[1]->isNever(); } public function isNonEmpty(): bool { @@ -134,11 +134,6 @@ public function getAssertionString(): string return $this->getId(); } - public function isEmptyArray(): bool - { - return $this->type_params[1]->isNever(); - } - /** * @return static */ diff --git a/src/Psalm/Type/Reconciler.php b/src/Psalm/Type/Reconciler.php index 1e1bd54c8b9..2466bce4027 100644 --- a/src/Psalm/Type/Reconciler.php +++ b/src/Psalm/Type/Reconciler.php @@ -1153,7 +1153,7 @@ private static function adjustTKeyedArrayType( foreach ($existing_types[$base_key]->getAtomicTypes() as $base_atomic_type) { if ($base_atomic_type instanceof TKeyedArray || ($base_atomic_type instanceof TArray - && !$base_atomic_type->isEmptyArray()) + && !$base_atomic_type->isEmpty()) || $base_atomic_type instanceof TClassStringMap ) { $new_base_type = $existing_types[$base_key]; diff --git a/src/Psalm/Type/UnionTrait.php b/src/Psalm/Type/UnionTrait.php index 51f7f7fc18f..b257ede806e 100644 --- a/src/Psalm/Type/UnionTrait.php +++ b/src/Psalm/Type/UnionTrait.php @@ -483,7 +483,6 @@ public function areArraysAllNonEmpty(): bool public function areArraysAllEmpty(): bool { - $result = true; foreach ($this->types as $t) { if ($t instanceof ArrayInterface && !$t->isEmpty() @@ -1670,8 +1669,7 @@ public function getSingleAtomic(): Atomic */ public function isEmptyArray(): bool { - return count($this->types) === 1 - && isset($this->types['array']); + return $this->isArray() && $this->areArraysAllEmpty(); } /**