From 8cc5af9592d4c22727ece0106f1e703934a3274c Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 25 Jul 2023 10:38:48 +0200 Subject: [PATCH] Fix thread data merging --- src/Psalm/Internal/Codebase/ClassLikes.php | 27 ++++++++++++------- .../Codebase/InternalCallMapHandlerTest.php | 1 + 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Psalm/Internal/Codebase/ClassLikes.php b/src/Psalm/Internal/Codebase/ClassLikes.php index fa92b057d..1092db27c 100644 --- a/src/Psalm/Internal/Codebase/ClassLikes.php +++ b/src/Psalm/Internal/Codebase/ClassLikes.php @@ -2347,15 +2347,24 @@ class ClassLikes $existing_classes, ] = $thread_data; - $this->existing_classlikes_lc = array_merge($existing_classlikes_lc, $this->existing_classlikes_lc); - $this->existing_classes_lc = array_merge($existing_classes_lc, $this->existing_classes_lc); - $this->existing_traits_lc = array_merge($existing_traits_lc, $this->existing_traits_lc); - $this->existing_traits = array_merge($existing_traits, $this->existing_traits); - $this->existing_enums_lc = array_merge($existing_enums_lc, $this->existing_enums_lc); - $this->existing_enums = array_merge($existing_enums, $this->existing_enums); - $this->existing_interfaces_lc = array_merge($existing_interfaces_lc, $this->existing_interfaces_lc); - $this->existing_interfaces = array_merge($existing_interfaces, $this->existing_interfaces); - $this->existing_classes = array_merge($existing_classes, $this->existing_classes); + $this->existing_classlikes_lc = self::mergeThreadData($existing_classlikes_lc, $this->existing_classlikes_lc); + $this->existing_classes_lc = self::mergeThreadData($existing_classes_lc, $this->existing_classes_lc); + $this->existing_traits_lc = self::mergeThreadData($existing_traits_lc, $this->existing_traits_lc); + $this->existing_traits = self::mergeThreadData($existing_traits, $this->existing_traits); + $this->existing_enums_lc = self::mergeThreadData($existing_enums_lc, $this->existing_enums_lc); + $this->existing_enums = self::mergeThreadData($existing_enums, $this->existing_enums); + $this->existing_interfaces_lc = self::mergeThreadData($existing_interfaces_lc, $this->existing_interfaces_lc); + $this->existing_interfaces = self::mergeThreadData($existing_interfaces, $this->existing_interfaces); + $this->existing_classes = self::mergeThreadData($existing_classes, $this->existing_classes); + } + private static function mergeThreadData(array $old, array $new): array + { + foreach ($new as $name => $value) { + if (!isset($old[$name]) || (!$old[$name] && $value)) { + $old[$name] = $value; + } + } + return $old; } public function getStorageFor(string $fq_class_name): ?ClassLikeStorage diff --git a/tests/Internal/Codebase/InternalCallMapHandlerTest.php b/tests/Internal/Codebase/InternalCallMapHandlerTest.php index b21fc991a..9e19fb4d6 100644 --- a/tests/Internal/Codebase/InternalCallMapHandlerTest.php +++ b/tests/Internal/Codebase/InternalCallMapHandlerTest.php @@ -631,6 +631,7 @@ class InternalCallMapHandlerTest extends TestCase } catch (InvalidArgumentException $e) { if (preg_match('/^Could not get class storage for (.*)$/', $e->getMessage(), $matches) && !class_exists($matches[1]) + && !interface_exists($matches[1]) ) { $this->fail("Class used in CallMap does not exist: {$matches[1]}"); }