Skip to content

Commit 3e895a5

Browse files
authored
Support new PHP8.4 mb_lcfirst, mb_ucfirst function variants
1 parent 93d85c4 commit 3e895a5

File tree

5 files changed

+33
-3
lines changed

5 files changed

+33
-3
lines changed

resources/functionMap_php84delta.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
'new' => [
1818
'http_get_last_response_header ' => ['list<string>'],
1919
'http_clear_last_response_header' => ['void'],
20+
'mb_lcfirst' => ['string', 'string'=>'string', 'encoding='=>'string'],
21+
'mb_ucfirst' => ['string', 'string'=>'string', 'encoding='=>'string'],
2022
],
2123
'old' => [
2224

src/Analyser/TypeSpecifier.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,9 +1017,9 @@ private function specifyTypesForConstantStringBinaryExpression(
10171017
&& $exprNode instanceof FuncCall
10181018
&& $exprNode->name instanceof Name
10191019
&& in_array(strtolower($exprNode->name->toString()), [
1020-
'substr', 'strstr', 'stristr', 'strchr', 'strrchr', 'strtolower', 'strtoupper',
1021-
'mb_substr', 'mb_strstr', 'mb_stristr', 'mb_strchr', 'mb_strrchr', 'mb_strtolower', 'mb_strtoupper',
1022-
'ucfirst', 'lcfirst', 'ucwords', 'mb_convert_case', 'mb_convert_kana',
1020+
'substr', 'strstr', 'stristr', 'strchr', 'strrchr', 'strtolower', 'strtoupper', 'ucfirst', 'lcfirst',
1021+
'mb_substr', 'mb_strstr', 'mb_stristr', 'mb_strchr', 'mb_strrchr', 'mb_strtolower', 'mb_strtoupper', 'mb_ucfirst', 'mb_lcfirst',
1022+
'ucwords', 'mb_convert_case', 'mb_convert_kana',
10231023
], true)
10241024
&& isset($exprNode->getArgs()[0])
10251025
&& $constantType->getValue() !== ''

src/Type/Php/StrCaseFunctionsReturnTypeExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class StrCaseFunctionsReturnTypeExtension implements DynamicFunctionReturnTypeEx
3434
'mb_strtolower' => 1,
3535
'lcfirst' => 1,
3636
'ucfirst' => 1,
37+
'mb_lcfirst' => 1,
38+
'mb_ucfirst' => 1,
3739
'ucwords' => 1,
3840
'mb_convert_case' => 2,
3941
'mb_convert_kana' => 1,

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,9 @@ public function dataFileAsserts(): iterable
10821082
if (PHP_VERSION_ID >= 70300) {
10831083
yield from $this->gatherAssertTypes(__DIR__ . '/data/str-casing.php');
10841084
}
1085+
if (PHP_VERSION_ID >= 80400) {
1086+
yield from $this->gatherAssertTypes(__DIR__ . '/data/str-caseing-php84.php');
1087+
}
10851088
yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-substr-specifying.php');
10861089
yield from $this->gatherAssertTypes(__DIR__ . '/data/unset-conditional-expressions.php');
10871090
yield from $this->gatherAssertTypes(__DIR__ . '/data/conditional-types-inference.php');
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace StrCasingReturnTypePhp84;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo {
8+
/**
9+
* @param numeric-string $numericS
10+
* @param non-empty-string $nonE
11+
* @param literal-string $literal
12+
*/
13+
public function bar($numericS, $nonE, $literal) {
14+
assertType("'aBC'", mb_lcfirst('ABC'));
15+
assertType("'Abc'", mb_ucfirst('abc'));
16+
assertType("numeric-string", mb_lcfirst($numericS));
17+
assertType("numeric-string", mb_ucfirst($numericS));
18+
assertType("non-empty-string", mb_lcfirst($nonE));
19+
assertType("non-empty-string", mb_ucfirst($nonE));
20+
assertType("string", mb_lcfirst($literal));
21+
assertType("string", mb_ucfirst($literal));
22+
}
23+
}

0 commit comments

Comments
 (0)