Skip to content

Commit

Permalink
Support new PHP8.4 mb_lcfirst, mb_ucfirst function variants
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed May 31, 2024
1 parent 93d85c4 commit 3e895a5
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 3 deletions.
2 changes: 2 additions & 0 deletions resources/functionMap_php84delta.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
'new' => [
'http_get_last_response_header ' => ['list<string>'],
'http_clear_last_response_header' => ['void'],
'mb_lcfirst' => ['string', 'string'=>'string', 'encoding='=>'string'],
'mb_ucfirst' => ['string', 'string'=>'string', 'encoding='=>'string'],
],
'old' => [

Expand Down
6 changes: 3 additions & 3 deletions src/Analyser/TypeSpecifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -1017,9 +1017,9 @@ private function specifyTypesForConstantStringBinaryExpression(
&& $exprNode instanceof FuncCall
&& $exprNode->name instanceof Name
&& in_array(strtolower($exprNode->name->toString()), [
'substr', 'strstr', 'stristr', 'strchr', 'strrchr', 'strtolower', 'strtoupper',
'mb_substr', 'mb_strstr', 'mb_stristr', 'mb_strchr', 'mb_strrchr', 'mb_strtolower', 'mb_strtoupper',
'ucfirst', 'lcfirst', 'ucwords', 'mb_convert_case', 'mb_convert_kana',
'substr', 'strstr', 'stristr', 'strchr', 'strrchr', 'strtolower', 'strtoupper', 'ucfirst', 'lcfirst',
'mb_substr', 'mb_strstr', 'mb_stristr', 'mb_strchr', 'mb_strrchr', 'mb_strtolower', 'mb_strtoupper', 'mb_ucfirst', 'mb_lcfirst',
'ucwords', 'mb_convert_case', 'mb_convert_kana',
], true)
&& isset($exprNode->getArgs()[0])
&& $constantType->getValue() !== ''
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Php/StrCaseFunctionsReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ class StrCaseFunctionsReturnTypeExtension implements DynamicFunctionReturnTypeEx
'mb_strtolower' => 1,
'lcfirst' => 1,
'ucfirst' => 1,
'mb_lcfirst' => 1,
'mb_ucfirst' => 1,
'ucwords' => 1,
'mb_convert_case' => 2,
'mb_convert_kana' => 1,
Expand Down
3 changes: 3 additions & 0 deletions tests/PHPStan/Analyser/NodeScopeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,9 @@ public function dataFileAsserts(): iterable
if (PHP_VERSION_ID >= 70300) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/str-casing.php');
}
if (PHP_VERSION_ID >= 80400) {
yield from $this->gatherAssertTypes(__DIR__ . '/data/str-caseing-php84.php');
}
yield from $this->gatherAssertTypes(__DIR__ . '/data/non-empty-string-substr-specifying.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/unset-conditional-expressions.php');
yield from $this->gatherAssertTypes(__DIR__ . '/data/conditional-types-inference.php');
Expand Down
23 changes: 23 additions & 0 deletions tests/PHPStan/Analyser/data/str-caseing-php84.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace StrCasingReturnTypePhp84;

use function PHPStan\Testing\assertType;

class Foo {
/**
* @param numeric-string $numericS
* @param non-empty-string $nonE
* @param literal-string $literal
*/
public function bar($numericS, $nonE, $literal) {
assertType("'aBC'", mb_lcfirst('ABC'));
assertType("'Abc'", mb_ucfirst('abc'));
assertType("numeric-string", mb_lcfirst($numericS));
assertType("numeric-string", mb_ucfirst($numericS));
assertType("non-empty-string", mb_lcfirst($nonE));
assertType("non-empty-string", mb_ucfirst($nonE));
assertType("string", mb_lcfirst($literal));
assertType("string", mb_ucfirst($literal));
}
}

0 comments on commit 3e895a5

Please sign in to comment.