Skip to content

Commit

Permalink
Merge pull request #10499 from kkmuffme/fix-empty-string-becomes-non-…
Browse files Browse the repository at this point in the history
…empty-string-when-literal-strings-disabled

Fix empty literal string becomes non-empty-string
  • Loading branch information
orklah committed Jan 14, 2024
2 parents c04eb4c + 4c54b68 commit b958349
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
Expand Up @@ -258,16 +258,30 @@ public static function analyze(

$has_numeric_and_non_empty = $has_numeric_type && $has_non_empty;

$non_falsy_string = $numeric_type->getBuilder()->addType(new TNonFalsyString())->freeze();
$left_non_falsy = UnionTypeComparator::isContainedBy(
$codebase,
$left_type,
$non_falsy_string,
);

$right_non_falsy = UnionTypeComparator::isContainedBy(
$codebase,
$right_type,
$non_falsy_string,
);

$all_literals = $left_type->allLiterals() && $right_type->allLiterals();

if ($has_non_empty) {
if ($all_literals) {
$result_type = new Union([new TNonEmptyNonspecificLiteralString]);
} elseif ($all_lowercase) {
$result_type = Type::getNonEmptyLowercaseString();
} elseif ($all_non_empty || $has_numeric_and_non_empty || $left_non_falsy || $right_non_falsy) {
$result_type = Type::getNonFalsyString();
} else {
$result_type = $all_non_empty || $has_numeric_and_non_empty ?
Type::getNonFalsyString() : Type::getNonEmptyString();
$result_type = Type::getNonEmptyString();
}
} else {
if ($all_literals) {
Expand Down
8 changes: 5 additions & 3 deletions src/Psalm/Type.php
Expand Up @@ -277,7 +277,7 @@ public static function getString(?string $value = null): Union
return new Union([$value === null ? new TString() : self::getAtomicStringFromLiteral($value)]);
}

/** @return TLiteralString|TNonEmptyString */
/** @return TLiteralString|TNonEmptyString|TNonFalsyString */
public static function getAtomicStringFromLiteral(string $value, bool $from_docblock = false): TString
{
$config = Config::getInstance();
Expand All @@ -287,10 +287,12 @@ public static function getAtomicStringFromLiteral(string $value, bool $from_docb
$type = $config->eventDispatcher->dispatchStringInterpreter($event);

if (!$type) {
if (strlen($value) < $config->max_string_length) {
if ($value === '' || strlen($value) < $config->max_string_length) {
$type = new TLiteralString($value, $from_docblock);
} else {
} elseif ($value === '0') {
$type = new TNonEmptyString($from_docblock);
} else {
$type = new TNonFalsyString($from_docblock);
}
}

Expand Down
9 changes: 9 additions & 0 deletions tests/BinaryOperationTest.php
Expand Up @@ -357,6 +357,15 @@ public function providerValidCodeParse(): iterable
'code' => '<?php
$a = "Hey " . "Jude,";',
],
'concatenationNonFalsyLiteralStringWithString' => [
'code' => '<?php
function foo(): string {}
$a = "Hey " . foo();',
'assertions' => [
'$a===' => 'non-falsy-string',
],
'ignored_issues' => ['InvalidReturnType'],
],
'concatenationWithNumberInWeakMode' => [
'code' => '<?php
$a = "hi" . 5;',
Expand Down
7 changes: 7 additions & 0 deletions tests/TypeCombinationTest.php
Expand Up @@ -120,6 +120,13 @@ function takesLiteralString($arg) {}
takesLiteralString($c);
}',
],
'tooLongLiteralShouldBeNonFalsyString' => [
'code' => '<?php
$x = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";',
'assertions' => [
'$x===' => 'non-falsy-string',
],
],
];
}

Expand Down

0 comments on commit b958349

Please sign in to comment.