From 75d1f79a3d76fbef35bb89e5b0f5f1662b72293d Mon Sep 17 00:00:00 2001 From: Matt Brown Date: Sun, 17 Jan 2021 12:22:29 -0500 Subject: [PATCH] Fix #5017 - handle combining literal and non-empty strings --- src/Psalm/Internal/Type/TypeCombiner.php | 22 ++++++++++++++++++++++ tests/TypeCombinationTest.php | 14 ++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/Psalm/Internal/Type/TypeCombiner.php b/src/Psalm/Internal/Type/TypeCombiner.php index 48da6f5c8..151824d0c 100644 --- a/src/Psalm/Internal/Type/TypeCombiner.php +++ b/src/Psalm/Internal/Type/TypeCombiner.php @@ -931,6 +931,11 @@ class TypeCombiner && \strtolower($type->value) === $type->value ) { // do nothing + } elseif (isset($combination->value_types['string']) + && $combination->value_types['string'] instanceof Type\Atomic\TNonEmptyString + && $type->value + ) { + // do nothing } else { $combination->value_types['string'] = new TString(); } @@ -974,6 +979,23 @@ class TypeCombiner $combination->value_types['string'] = $type; } + $combination->strings = null; + } elseif ($type instanceof Type\Atomic\TNonEmptyString) { + $has_empty_string = false; + + foreach ($combination->strings as $string_type) { + if (!$string_type->value) { + $has_empty_string = true; + break; + } + } + + if ($has_empty_string) { + $combination->value_types['string'] = new TString(); + } else { + $combination->value_types['string'] = $type; + } + $combination->strings = null; } else { $has_non_literal_class_string = false; diff --git a/tests/TypeCombinationTest.php b/tests/TypeCombinationTest.php index a5a30ce0b..5f97c45a0 100644 --- a/tests/TypeCombinationTest.php +++ b/tests/TypeCombinationTest.php @@ -644,6 +644,20 @@ class TypeCombinationTest extends TestCase 'array{0?:int}', ] ], + 'combinNonEmptyStringAndLiteral' => [ + 'non-empty-string', + [ + 'non-empty-string', + '"foo"', + ] + ], + 'combinLiteralAndNonEmptyString' => [ + 'non-empty-string', + [ + '"foo"', + 'non-empty-string' + ] + ], ]; }