1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Narrow the type of haystack when strpos != false

This commit is contained in:
RobChett 2023-05-14 17:52:55 +01:00
parent 5370492f97
commit bd0ba6ee95
3 changed files with 46 additions and 9 deletions

View File

@ -627,12 +627,23 @@ function substr_replace($string, $replace, $offset, $length = null) {}
/**
* @psalm-pure
*
* @param string $haystack
*
* @param string $needle
* @param int $offset
* @psalm-assert-if-true =non-empty-string $haystack
* @psalm-return positive-int|0|false
*/
function strpos($haystack, $needle, int $offset = 0) : int|false {}
function strpos(string $haystack, string $needle, int $offset = 0) {}
/**
* @psalm-pure
* @param string $haystack
* @param string $needle
* @param int $offset
* @psalm-assert-if-true =non-empty-string $haystack
* @psalm-return positive-int|0|false
*/
function stripos(string $haystack, string $needle, int $offset = 0) {}
/**
* @psalm-pure

View File

@ -211,14 +211,39 @@ class CoreStubsTest extends TestCase
}
throw new RuntimeException();
}
/** @return non-empty-string */
function after_strpos(): string
{
$string = uniqid();
if (strpos($string, "foo") !== false) {
return $string;
}
throw new RuntimeException();
}
/** @return non-empty-string */
function after_stripos(): string
{
$string = uniqid();
if (stripos($string, "foo") !== false) {
return $string;
}
throw new RuntimeException();
}
$a = after_str_contains();
$b = after_str_starts_with();
$c = after_str_ends_with();
$d = after_strpos();
$e = after_stripos();
',
'assertions' => [
'$a===' => 'non-empty-string',
'$b===' => 'non-empty-string',
'$c===' => 'non-empty-string',
'$d===' => 'non-empty-string',
'$e===' => 'non-empty-string',
],
];
yield "PHP8 str_* function doesn't subtract string after assertion" => [

View File

@ -598,12 +598,6 @@ class FunctionCallTest extends TestCase
return $aTime - $bTime;
}',
],
'strposIntSecondParam' => [
'code' => '<?php
function hasZeroByteOffset(string $s) : bool {
return strpos($s, 0) !== false;
}',
],
'functionCallInGlobalScope' => [
'code' => '<?php
$a = function() use ($argv) : void {};',
@ -3019,6 +3013,13 @@ class FunctionCallTest extends TestCase
',
'error_message' => 'InvalidParamDefault',
],
'disallowStrposIntSecondParam' => [
'code' => '<?php
function hasZeroByteOffset(string $s) : bool {
return strpos($s, 0) !== false;
}',
'error_message' => 'InvalidScalarArgument',
],
];
}