Skip to content

Commit e45b637

Browse files
VincentLangletondrejmirtes
authored andcommitted
Add support for str_repeat and str_pad for lowercase string
1 parent 9fc11f7 commit e45b637

File tree

5 files changed

+67
-17
lines changed

5 files changed

+67
-17
lines changed

src/Type/Php/StrPadFunctionReturnTypeExtension.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\FunctionReflection;
88
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
9+
use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
910
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
1011
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
1112
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
@@ -44,15 +45,17 @@ public function getTypeFromFunctionCall(
4445
$accessoryTypes[] = new AccessoryNonEmptyStringType();
4546
}
4647

47-
if ($inputType->isLiteralString()->yes()) {
48-
if (count($args) < 3) {
49-
$accessoryTypes[] = new AccessoryLiteralStringType();
50-
} else {
51-
$padStringType = $scope->getType($args[2]->value);
52-
if ($padStringType->isLiteralString()->yes()) {
53-
$accessoryTypes[] = new AccessoryLiteralStringType();
54-
}
55-
}
48+
if (count($args) < 3) {
49+
$padStringType = null;
50+
} else {
51+
$padStringType = $scope->getType($args[2]->value);
52+
}
53+
54+
if ($inputType->isLiteralString()->yes() && ($padStringType === null || $padStringType->isLiteralString()->yes())) {
55+
$accessoryTypes[] = new AccessoryLiteralStringType();
56+
}
57+
if ($inputType->isLowercaseString()->yes() && ($padStringType === null || $padStringType->isLowercaseString()->yes())) {
58+
$accessoryTypes[] = new AccessoryLowercaseStringType();
5659
}
5760

5861
if (count($accessoryTypes) > 0) {

src/Type/Php/StrRepeatFunctionReturnTypeExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PHPStan\Analyser\Scope;
88
use PHPStan\Reflection\FunctionReflection;
99
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
10+
use PHPStan\Type\Accessory\AccessoryLowercaseStringType;
1011
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
1112
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
1213
use PHPStan\Type\Accessory\AccessoryNumericStringType;
@@ -93,6 +94,10 @@ public function getTypeFromFunctionCall(
9394
}
9495
}
9596

97+
if ($inputType->isLowercaseString()->yes()) {
98+
$accessoryTypes[] = new AccessoryLowercaseStringType();
99+
}
100+
96101
if (count($accessoryTypes) > 0) {
97102
$accessoryTypes[] = new StringType();
98103
return new IntersectionType($accessoryTypes);

tests/PHPStan/Analyser/nsrt/literal-string.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ public function doFoo($literalString, string $string, $numericString)
3636
"'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'",
3737
str_repeat('a', 99)
3838
);
39-
assertType('literal-string&non-falsy-string', str_repeat('a', 100));
40-
assertType('literal-string&non-empty-string&numeric-string', str_repeat('0', 100)); // could be non-falsy-string
41-
assertType('literal-string&non-falsy-string&numeric-string', str_repeat('1', 100));
39+
assertType('literal-string&lowercase-string&non-falsy-string', str_repeat('a', 100));
40+
assertType('literal-string&lowercase-string&non-empty-string&numeric-string', str_repeat('0', 100)); // could be non-falsy-string
41+
assertType('literal-string&lowercase-string&non-falsy-string&numeric-string', str_repeat('1', 100));
4242
// Repeating a numeric type multiple times can lead to a non-numeric type: 3v4l.org/aRBdZ
4343
assertType('non-empty-string', str_repeat($numericString, 100));
4444

@@ -51,13 +51,13 @@ public function doFoo($literalString, string $string, $numericString)
5151
assertType("non-empty-string", str_repeat($numericString, 2));
5252
assertType("literal-string", str_repeat($literalString, 1));
5353
$x = rand(1,2);
54-
assertType("literal-string&non-falsy-string", str_repeat(' 1 ', $x));
55-
assertType("literal-string&non-falsy-string", str_repeat('+1', $x));
56-
assertType("literal-string&non-falsy-string", str_repeat('1e9', $x));
57-
assertType("literal-string&non-falsy-string&numeric-string", str_repeat('19', $x));
54+
assertType("literal-string&lowercase-string&non-falsy-string", str_repeat(' 1 ', $x));
55+
assertType("literal-string&lowercase-string&non-falsy-string", str_repeat('+1', $x));
56+
assertType("literal-string&lowercase-string&non-falsy-string", str_repeat('1e9', $x));
57+
assertType("literal-string&lowercase-string&non-falsy-string&numeric-string", str_repeat('19', $x));
5858

5959
$x = rand(0,2);
60-
assertType("literal-string", str_repeat('19', $x));
60+
assertType("literal-string&lowercase-string", str_repeat('19', $x));
6161

6262
$x = rand(-10,-1);
6363
assertType("*NEVER*", str_repeat('19', $x));
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace LowercaseStringStrPad;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
/**
11+
* @param lowercase-string $lowercase
12+
*/
13+
public function doRepeat(string $string, string $lowercase): void
14+
{
15+
assertType('non-empty-string', str_pad($string, 5));
16+
assertType('non-empty-string', str_pad($string, 5, $lowercase));
17+
assertType('non-empty-string', str_pad($string, 5, $string));
18+
assertType('lowercase-string&non-empty-string', str_pad($lowercase, 5));
19+
assertType('lowercase-string&non-empty-string', str_pad($lowercase, 5, $lowercase));
20+
assertType('non-empty-string', str_pad($lowercase, 5, $string));
21+
}
22+
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace LowercaseStringStrRepeat;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
10+
/**
11+
* @param lowercase-string $lowercase
12+
*/
13+
public function doRepeat(string $string, string $lowercase): void
14+
{
15+
assertType('lowercase-string', str_repeat($lowercase, 5));
16+
assertType('string', str_repeat($string, 5));
17+
}
18+
19+
}

0 commit comments

Comments
 (0)