Skip to content

Commit

Permalink
Provide more specific explode() return type (#5350)
Browse files Browse the repository at this point in the history
Fixes #5347

`explode()` now omits `false` from the return type  when separator is a
definitely non-empty string.
  • Loading branch information
weirdan authored Mar 11, 2021
1 parent 8be77aa commit 4f8ba04
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,36 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
} elseif (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value))
&& $first_arg_type->hasString()
) {
$falsable_array = new Type\Union([
$can_return_empty
? new Type\Atomic\TList($inner_type)
: new Type\Atomic\TNonEmptyList($inner_type),
new Type\Atomic\TFalse
]);
$can_be_false = true;
if ($first_arg_type->isString()) {
$can_be_false = false;
foreach ($first_arg_type->getAtomicTypes() as $string_type) {
if (!($string_type instanceof Type\Atomic\TNonEmptyString)) {
$can_be_false = true;
break;
}
}
}
if ($can_be_false) {
$array_type = new Type\Union([
$can_return_empty
? new Type\Atomic\TList($inner_type)
: new Type\Atomic\TNonEmptyList($inner_type),
new Type\Atomic\TFalse
]);

if ($statements_source->getCodebase()->config->ignore_internal_falsable_issues) {
$falsable_array->ignore_falsable_issues = true;
if ($statements_source->getCodebase()->config->ignore_internal_falsable_issues) {
$array_type->ignore_falsable_issues = true;
}
} else {
$array_type = new Type\Union([
$can_return_empty
? new Type\Atomic\TList($inner_type)
: new Type\Atomic\TNonEmptyList($inner_type),
]);
}

return $falsable_array;
return $array_type;
}
}

Expand Down
31 changes: 31 additions & 0 deletions tests/FunctionCallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,37 @@ public static function Baz($mixed) : string {
'$elements' => 'false|list<string>',
],
],
'explodeWithDynamicNonEmptyDelimiter' => [
'<?php
/**
* @var non-empty-string $delim
* @var string $string
*/
$elements = explode($delim, $string);',
'assertions' => [
'$elements' => 'non-empty-list<string>',
],
],
'explodeWithLiteralNonEmptyDelimiter' => [
'<?php
/**
* @var string $string
*/
$elements = explode(" ", $string);',
'assertions' => [
'$elements' => 'non-empty-list<string>',
],
],
'explodeWithLiteralEmptyDelimiter' => [
'<?php
/**
* @var string $string
*/
$elements = explode("", $string);',
'assertions' => [
'$elements' => 'false',
],
],
'explodeWithPossiblyFalse' => [
'<?php
/** @return non-empty-list<string> */
Expand Down

0 comments on commit 4f8ba04

Please sign in to comment.