1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Type explode more accurately

This commit is contained in:
Matt Brown 2018-04-16 16:03:04 -04:00
parent 02a5d22449
commit 3cc549384f
5 changed files with 36 additions and 7 deletions

View File

@ -8650,7 +8650,7 @@ return [
'preg_replace' => ['string|array', 'regex'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback' => ['string|array', 'regex'=>'string|array', 'callback'=>'callable(array):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_replace_callback_array' => ['string|array', 'pattern'=>'array<string,callable(array):string>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
'preg_split' => ['array', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'],
'preg_split' => ['array<int, string>|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'],
'prev' => ['mixed', '&rw_array_arg'=>'array'],
'print' => ['int', 'arg'=>'string'],
'print_r' => ['string|true', 'var'=>'mixed', 'return='=>'bool'],

View File

@ -110,8 +110,19 @@ class FunctionChecker extends FunctionLikeChecker
}
}
if ($call_map_key === 'explode' || $call_map_key === 'preg_split') {
return Type::parseString('array<int, string>');
if ($call_map_key === 'explode'
&& $call_args[0]->value instanceof PhpParser\Node\Scalar\String_
) {
if ($call_args[0]->value->value === '') {
return Type::getFalse();
}
return new Type\Union([
new Type\Atomic\TArray([
Type::getInt(),
Type::getString()
])
]);
}
if ($call_map_key === 'abs'

View File

@ -528,6 +528,10 @@ class ArrayFetchChecker
$codebase->analyzer->incrementNonMixedCount($statements_checker->getCheckedFilePath());
if ($type instanceof Type\Atomic\TFalse && $array_type->ignore_falsable_issues) {
continue;
}
if ($type instanceof TNamedObject) {
if (strtolower($type->value) !== 'simplexmlelement'
&& $codebase->classExists($type->value)

View File

@ -244,8 +244,8 @@ class ReturnChecker
if (IssueBuffer::accepts(
new NullableReturnStatement(
'The declared return type \'' . $local_return_type . '\' for '
. $cased_method_id . ' is not nullable, but \'' . $inferred_type
. '\' contains null',
. $cased_method_id . ' is not nullable, but the function returns \''
. $inferred_type . '\'',
new CodeLocation($source, $stmt)
),
$statements_checker->getSuppressedIssues()
@ -262,8 +262,8 @@ class ReturnChecker
if (IssueBuffer::accepts(
new FalsableReturnStatement(
'The declared return type \'' . $local_return_type . '\' for '
. $cased_method_id . ' does not allow false, but \'' . $inferred_type
. '\' contains false',
. $cased_method_id . ' does not allow false, but the function returns \''
. $inferred_type . '\'',
new CodeLocation($source, $stmt)
),
$statements_checker->getSuppressedIssues()

View File

@ -608,6 +608,13 @@ class FunctionCallTest extends TestCase
'$c' => 'int',
],
],
'explodeWithPossiblyFalse' => [
'<?php
/** @return array<int, string> */
function exploder(string $s) : array {
return explode(" ", $s);
}',
],
];
}
@ -840,6 +847,13 @@ class FunctionCallTest extends TestCase
$a = var_export(["a"]);',
'error_message' => 'AssignmentToVoid',
],
'explodeWithEmptyString' => [
'<?php
function exploder(string $s) : array {
return explode("", $s);
}',
'error_message' => 'FalsableReturnStatement',
],
];
}
}