diff --git a/src/Type/IntegerRangeType.php b/src/Type/IntegerRangeType.php index 50eac67a04..a931894c08 100644 --- a/src/Type/IntegerRangeType.php +++ b/src/Type/IntegerRangeType.php @@ -10,10 +10,8 @@ use PHPStan\PhpDocParser\Ast\Type\TypeNode; use PHPStan\Reflection\InitializerExprTypeResolver; use PHPStan\TrinaryLogic; -use PHPStan\Type\Accessory\AccessoryLowercaseStringType; +use PHPStan\Type\Accessory\AccessoryDecimalIntegerStringType; use PHPStan\Type\Accessory\AccessoryNonFalsyStringType; -use PHPStan\Type\Accessory\AccessoryNumericStringType; -use PHPStan\Type\Accessory\AccessoryUppercaseStringType; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantIntegerType; use function array_filter; @@ -507,18 +505,14 @@ public function toString(): Type if ($isZero->no()) { return new IntersectionType([ new StringType(), - new AccessoryLowercaseStringType(), - new AccessoryUppercaseStringType(), - new AccessoryNumericStringType(), + new AccessoryDecimalIntegerStringType(), new AccessoryNonFalsyStringType(), ]); } return new IntersectionType([ new StringType(), - new AccessoryLowercaseStringType(), - new AccessoryUppercaseStringType(), - new AccessoryNumericStringType(), + new AccessoryDecimalIntegerStringType(), ]); } diff --git a/src/Type/IntegerType.php b/src/Type/IntegerType.php index a378a7e7bc..45be2ae49f 100644 --- a/src/Type/IntegerType.php +++ b/src/Type/IntegerType.php @@ -6,9 +6,7 @@ use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode; use PHPStan\PhpDocParser\Ast\Type\TypeNode; use PHPStan\TrinaryLogic; -use PHPStan\Type\Accessory\AccessoryLowercaseStringType; -use PHPStan\Type\Accessory\AccessoryNumericStringType; -use PHPStan\Type\Accessory\AccessoryUppercaseStringType; +use PHPStan\Type\Accessory\AccessoryDecimalIntegerStringType; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantIntegerType; @@ -81,9 +79,7 @@ public function toString(): Type { return new IntersectionType([ new StringType(), - new AccessoryLowercaseStringType(), - new AccessoryUppercaseStringType(), - new AccessoryNumericStringType(), + new AccessoryDecimalIntegerStringType(), ]); } diff --git a/tests/PHPStan/Analyser/nsrt/array-key-exists.php b/tests/PHPStan/Analyser/nsrt/array-key-exists.php index 3d0505a9b9..a06bba9ac2 100644 --- a/tests/PHPStan/Analyser/nsrt/array-key-exists.php +++ b/tests/PHPStan/Analyser/nsrt/array-key-exists.php @@ -50,16 +50,16 @@ public function doBar(array $a, array $b, array $c, int $key1, string $key2, int assertType('int', $key1); } if (array_key_exists($key2, $a)) { - assertType('lowercase-string&numeric-string&uppercase-string', $key2); + assertType('decimal-int-string', $key2); } if (array_key_exists($key3, $a)) { - assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key3); + assertType('int|decimal-int-string', $key3); } if (array_key_exists($key4, $a)) { - assertType('(int|(lowercase-string&numeric-string&uppercase-string))', $key4); + assertType('(int|decimal-int-string)', $key4); } if (array_key_exists($key5, $a)) { - assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key5); + assertType('int|decimal-int-string', $key5); } if (array_key_exists($key1, $b)) { diff --git a/tests/PHPStan/Analyser/nsrt/bug-11716.php b/tests/PHPStan/Analyser/nsrt/bug-11716.php index 3dced2a08d..7719f96c0e 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-11716.php +++ b/tests/PHPStan/Analyser/nsrt/bug-11716.php @@ -75,7 +75,7 @@ function narrowKey($mixed, string $s, int $i, array $generalArr, array $intKeyed assertType('int', $i); if (isset($intKeyedArr[$s])) { - assertType("lowercase-string&numeric-string&uppercase-string", $s); + assertType('decimal-int-string', $s); } else { assertType('string', $s); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-12393b.php b/tests/PHPStan/Analyser/nsrt/bug-12393b.php index 944646d365..e39b19fb94 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-12393b.php +++ b/tests/PHPStan/Analyser/nsrt/bug-12393b.php @@ -343,7 +343,7 @@ class FooIntString public function doFoo(int $b): void { $this->foo = $b; - assertType('lowercase-string&numeric-string&uppercase-string', $this->foo); + assertType('decimal-int-string', $this->foo); } public function doBar(): void @@ -418,7 +418,7 @@ class FooNullableIntString public function doFoo(?int $b): void { $this->foo = $b; - assertType('lowercase-string&numeric-string&uppercase-string', $this->foo); + assertType('decimal-int-string', $this->foo); } public function doBar(): void diff --git a/tests/PHPStan/Analyser/nsrt/bug-14525.php b/tests/PHPStan/Analyser/nsrt/bug-14525.php index e478aa44a3..93712dc8c2 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-14525.php +++ b/tests/PHPStan/Analyser/nsrt/bug-14525.php @@ -20,7 +20,7 @@ function arrayWalkGeneric(): void array_walk($array, function (&$value, $key): void { $value = (string) $value; }); - assertType("array", $array); + assertType('array', $array); } function arrayWalkNoModification(): void @@ -63,7 +63,7 @@ function arrayWalkNonEmptyArray(): void array_walk($array, function (&$value): void { $value = (string) $value; }); - assertType("non-empty-array", $array); + assertType('non-empty-array', $array); } function arrayWalkList(): void @@ -73,7 +73,7 @@ function arrayWalkList(): void array_walk($list, function (&$value): void { $value = (string) $value; }); - assertType("list", $list); + assertType('list', $list); } function arrayWalkAlwaysTerminating(): void @@ -84,7 +84,7 @@ function arrayWalkAlwaysTerminating(): void $value = (string) $value; return; }); - assertType("array", $array); + assertType('array', $array); } function arrayWalkNestedArray(): void @@ -106,7 +106,7 @@ function arrayWalkWithNestedClosure(): void }, [1, 2, 3]); $value = (string) $value; }); - assertType("array", $array); + assertType('array', $array); } function arrayWalkWithNestedClosureByRef(): void @@ -121,5 +121,5 @@ function arrayWalkWithNestedClosureByRef(): void $fn(); $value = (string) $value; }); - assertType("array", $array); + assertType('array', $array); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-14753.php b/tests/PHPStan/Analyser/nsrt/bug-14753.php new file mode 100644 index 0000000000..74d45a1bcb --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-14753.php @@ -0,0 +1,37 @@ + $positive + * @param int $negative + * @param int<-10, 10> $withZero + * @param int<0, max> $nonNegative + */ + public function sayHello( + int $int, + int $positive, + int $negative, + int $withZero, + int $nonNegative, + bool $bool, + ): void + { + assertType('decimal-int-string', (string) $int); + assertType('decimal-int-string&non-falsy-string', (string) $positive); + assertType('decimal-int-string&non-falsy-string', (string) $negative); + assertType('decimal-int-string', (string) $nonNegative); + assertType("'-1'|'-10'|'-2'|'-3'|'-4'|'-5'|'-6'|'-7'|'-8'|'-9'|'0'|'1'|'10'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'", (string) $withZero); + assertType("''|'1'", (string) $bool); + assertType("'1'", (string) true); + assertType("''", (string) false); + assertType("'5'", (string) 5); + assertType("'-5'", (string) -5); + assertType('decimal-int-string', $int . ''); + assertType('decimal-int-string', strval($int)); + } +} diff --git a/tests/PHPStan/Analyser/nsrt/bug-4587.php b/tests/PHPStan/Analyser/nsrt/bug-4587.php index 061c953a28..a811193ae3 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-4587.php +++ b/tests/PHPStan/Analyser/nsrt/bug-4587.php @@ -27,11 +27,11 @@ public function b(): void $type = array_map(static function (array $result): array { assertType('array{a: int}', $result); $result['a'] = (string) $result['a']; - assertType('array{a: lowercase-string&numeric-string&uppercase-string}', $result); + assertType('array{a: decimal-int-string}', $result); return $result; }, $results); - assertType('list', $type); + assertType('list', $type); } } diff --git a/tests/PHPStan/Analyser/nsrt/bug-7387.php b/tests/PHPStan/Analyser/nsrt/bug-7387.php index 1b283a7990..c0f518ff43 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-7387.php +++ b/tests/PHPStan/Analyser/nsrt/bug-7387.php @@ -29,7 +29,7 @@ public function inputTypes(int $i, float $f, string $s, int $intRange) { public function specifiers(int $i) { // https://3v4l.org/fmVIg - assertType('lowercase-string&numeric-string&uppercase-string', sprintf('%14s', $i)); + assertType('decimal-int-string', sprintf('%14s', $i)); assertType('lowercase-string&numeric-string', sprintf('%d', $i)); @@ -59,9 +59,9 @@ public function specifiers(int $i) { */ public function positionalArgs($mixed, int $i, float $f, string $s, int $posInt, int $negInt, int $nonZeroIntRange, int $intRange) { // https://3v4l.org/vVL0c - assertType('lowercase-string&numeric-string&uppercase-string', sprintf('%2$6s', $mixed, $i)); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', sprintf('%2$6s', $mixed, $posInt)); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', sprintf('%2$6s', $mixed, $negInt)); + assertType('decimal-int-string', sprintf('%2$6s', $mixed, $i)); + assertType('decimal-int-string&non-falsy-string', sprintf('%2$6s', $mixed, $posInt)); + assertType('decimal-int-string&non-falsy-string', sprintf('%2$6s', $mixed, $negInt)); assertType("' 1'|' 2'|' 3'|' 4'|' 5'", sprintf('%2$6s', $mixed, $nonZeroIntRange)); // https://3v4l.org/1ECIq diff --git a/tests/PHPStan/Analyser/nsrt/bug-8635.php b/tests/PHPStan/Analyser/nsrt/bug-8635.php index 46d5b728b8..45c09fc4e8 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-8635.php +++ b/tests/PHPStan/Analyser/nsrt/bug-8635.php @@ -8,6 +8,6 @@ class HelloWorld { public function EchoInt(int $value): void { - assertType('lowercase-string&numeric-string&uppercase-string', "$value"); + assertType('decimal-int-string', "$value"); } } diff --git a/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php b/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php index dfe47aa39b..6ad4a930e7 100644 --- a/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php +++ b/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php @@ -13,13 +13,13 @@ * @param 1 $constantInt */ function foo(int $a, float $b, $numeric, $numeric2, $number, $positive, $negative, $constantInt): void { - assertType('lowercase-string&numeric-string&uppercase-string', (string)$a); + assertType('decimal-int-string', (string)$a); assertType('numeric-string&uppercase-string', (string)$b); assertType('numeric-string', (string)$numeric); assertType('numeric-string', (string)$numeric2); assertType('numeric-string&uppercase-string', (string)$number); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', (string)$positive); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', (string)$negative); + assertType('decimal-int-string&non-falsy-string', (string)$positive); + assertType('decimal-int-string&non-falsy-string', (string)$negative); assertType("'1'", (string)$constantInt); } @@ -32,28 +32,28 @@ function foo(int $a, float $b, $numeric, $numeric2, $number, $positive, $negativ * @param 1 $constantInt */ function concatEmptyString(int $a, float $b, $numeric, $numeric2, $number, $positive, $negative, $constantInt): void { - assertType('lowercase-string&numeric-string&uppercase-string', '' . $a); + assertType('decimal-int-string', '' . $a); assertType('numeric-string&uppercase-string', '' . $b); assertType('numeric-string', '' . $numeric); assertType('numeric-string', '' . $numeric2); assertType('numeric-string&uppercase-string', '' . $number); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', '' . $positive); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', '' . $negative); + assertType('decimal-int-string&non-falsy-string', '' . $positive); + assertType('decimal-int-string&non-falsy-string', '' . $negative); assertType("'1'", '' . $constantInt); - assertType('lowercase-string&numeric-string&uppercase-string', $a . ''); + assertType('decimal-int-string', $a . ''); assertType('numeric-string&uppercase-string', $b . ''); assertType('numeric-string', $numeric . ''); assertType('numeric-string', $numeric2 . ''); assertType('numeric-string&uppercase-string', $number . ''); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $positive . ''); - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $negative . ''); + assertType('decimal-int-string&non-falsy-string', $positive . ''); + assertType('decimal-int-string&non-falsy-string', $negative . ''); assertType("'1'", $constantInt . ''); } function concatAssignEmptyString(int $i, float $f) { $i .= ''; - assertType('lowercase-string&numeric-string&uppercase-string', $i); + assertType('decimal-int-string', $i); $s = ''; $s .= $f; @@ -66,13 +66,13 @@ function concatAssignEmptyString(int $i, float $f) { */ function integerRangeToString($positive, $negative) { - assertType('lowercase-string&numeric-string&uppercase-string', (string) $positive); - assertType('lowercase-string&numeric-string&uppercase-string', (string) $negative); + assertType('decimal-int-string', (string) $positive); + assertType('decimal-int-string', (string) $negative); if ($positive !== 0) { - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', (string) $positive); + assertType('decimal-int-string&non-falsy-string', (string) $positive); } if ($negative !== 0) { - assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', (string) $negative); + assertType('decimal-int-string&non-falsy-string', (string) $negative); } } diff --git a/tests/PHPStan/Analyser/nsrt/decimal-int-string.php b/tests/PHPStan/Analyser/nsrt/decimal-int-string.php index fe5c5fdd52..b3be8fb66c 100644 --- a/tests/PHPStan/Analyser/nsrt/decimal-int-string.php +++ b/tests/PHPStan/Analyser/nsrt/decimal-int-string.php @@ -14,7 +14,7 @@ public function doFoo(string $s): void { assertType('decimal-int-string' ,$s); $a = [$s => 1]; - assertType('non-empty-array', $a); + assertType('non-empty-array', $a); assertType('bool', (bool) $s); diff --git a/tests/PHPStan/Analyser/nsrt/filter-var.php b/tests/PHPStan/Analyser/nsrt/filter-var.php index 34d23f9c8f..8fc5a852c0 100644 --- a/tests/PHPStan/Analyser/nsrt/filter-var.php +++ b/tests/PHPStan/Analyser/nsrt/filter-var.php @@ -158,7 +158,7 @@ public function scalars(bool $bool, float $float, int $int, string $string, int assertType("'17'", filter_var(17.0)); assertType("'17.1'", filter_var(17.1)); assertType("'1.0E-50'", filter_var(1e-50)); - assertType('lowercase-string&numeric-string&uppercase-string', filter_var($int)); + assertType('decimal-int-string', filter_var($int)); assertType("'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'", filter_var($intRange)); assertType("'17'", filter_var(17)); assertType('string', filter_var($string)); diff --git a/tests/PHPStan/Analyser/nsrt/generics.php b/tests/PHPStan/Analyser/nsrt/generics.php index 77b9a470a6..9a01501f53 100644 --- a/tests/PHPStan/Analyser/nsrt/generics.php +++ b/tests/PHPStan/Analyser/nsrt/generics.php @@ -147,10 +147,10 @@ function f($a, $b) */ function testF($arrayOfInt, $callableOrNull) { - assertType('Closure(int): (lowercase-string&numeric-string&uppercase-string)', function (int $a): string { + assertType('Closure(int): decimal-int-string', function (int $a): string { return (string)$a; }); - assertType('array', f($arrayOfInt, function (int $a): string { + assertType('array', f($arrayOfInt, function (int $a): string { return (string)$a; })); assertType('Closure(mixed): string', function ($a): string { @@ -224,7 +224,7 @@ function testArrayMap(array $listOfIntegers) return (string) $int; }, $listOfIntegers); - assertType('array', $strings); + assertType('array', $strings); } /** diff --git a/tests/PHPStan/Analyser/nsrt/key-exists.php b/tests/PHPStan/Analyser/nsrt/key-exists.php index 67c42f6c14..cf8cd1def4 100644 --- a/tests/PHPStan/Analyser/nsrt/key-exists.php +++ b/tests/PHPStan/Analyser/nsrt/key-exists.php @@ -49,16 +49,16 @@ public function doBar(array $a, array $b, array $c, int $key1, string $key2, int assertType('int', $key1); } if (key_exists($key2, $a)) { - assertType('lowercase-string&numeric-string&uppercase-string', $key2); + assertType('decimal-int-string', $key2); } if (key_exists($key3, $a)) { - assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key3); + assertType('int|decimal-int-string', $key3); } if (key_exists($key4, $a)) { - assertType('(int|(lowercase-string&numeric-string&uppercase-string))', $key4); + assertType('(int|decimal-int-string)', $key4); } if (key_exists($key5, $a)) { - assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key5); + assertType('int|decimal-int-string', $key5); } if (key_exists($key1, $b)) { diff --git a/tests/PHPStan/Analyser/nsrt/range-to-string.php b/tests/PHPStan/Analyser/nsrt/range-to-string.php index 49bb179309..4e4a7a844d 100644 --- a/tests/PHPStan/Analyser/nsrt/range-to-string.php +++ b/tests/PHPStan/Analyser/nsrt/range-to-string.php @@ -17,6 +17,6 @@ public function sayHello($i, $ii, $maxlong, $toolong): void assertType("'10'|'5'|'6'|'7'|'8'|'9'", (string) $i); assertType("'-1'|'-10'|'-2'|'-3'|'-4'|'-5'|'-6'|'-7'|'-8'|'-9'|'0'|'1'|'10'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'", (string) $ii); assertType("'0'|'1'|'10'|'100'|'101'|'102'|'103'|'104'|'105'|'106'|'107'|'108'|'109'|'11'|'110'|'111'|'112'|'113'|'114'|'115'|'116'|'117'|'118'|'119'|'12'|'120'|'121'|'122'|'123'|'124'|'125'|'126'|'127'|'128'|'13'|'14'|'15'|'16'|'17'|'18'|'19'|'2'|'20'|'21'|'22'|'23'|'24'|'25'|'26'|'27'|'28'|'29'|'3'|'30'|'31'|'32'|'33'|'34'|'35'|'36'|'37'|'38'|'39'|'4'|'40'|'41'|'42'|'43'|'44'|'45'|'46'|'47'|'48'|'49'|'5'|'50'|'51'|'52'|'53'|'54'|'55'|'56'|'57'|'58'|'59'|'6'|'60'|'61'|'62'|'63'|'64'|'65'|'66'|'67'|'68'|'69'|'7'|'70'|'71'|'72'|'73'|'74'|'75'|'76'|'77'|'78'|'79'|'8'|'80'|'81'|'82'|'83'|'84'|'85'|'86'|'87'|'88'|'89'|'9'|'90'|'91'|'92'|'93'|'94'|'95'|'96'|'97'|'98'|'99'", (string) $maxlong); - assertType("lowercase-string&numeric-string&uppercase-string", (string) $toolong); + assertType('decimal-int-string', (string) $toolong); } } diff --git a/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php b/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php index ef0f894c63..f90e7dca5a 100644 --- a/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php +++ b/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php @@ -11,7 +11,7 @@ function doString(string $s, int $i, float $f, array $a, object $o) assertType('string', $s); settype($i, 'string'); - assertType('lowercase-string&numeric-string&uppercase-string', $i); + assertType('decimal-int-string', $i); settype($f, 'string'); assertType('numeric-string&uppercase-string', $f); diff --git a/tests/PHPStan/Analyser/nsrt/strval.php b/tests/PHPStan/Analyser/nsrt/strval.php index b28f31549b..11dd7c0082 100644 --- a/tests/PHPStan/Analyser/nsrt/strval.php +++ b/tests/PHPStan/Analyser/nsrt/strval.php @@ -17,9 +17,9 @@ function strvalTest(string $string, string $class): void assertType('\'1\'', strval(true)); assertType('\'\'|\'1\'', strval(rand(0, 1) === 0)); assertType('\'42\'', strval(42)); - assertType('lowercase-string&numeric-string&uppercase-string', strval(rand())); + assertType('decimal-int-string', strval(rand())); assertType('numeric-string&uppercase-string', strval(rand() * 0.1)); - assertType('lowercase-string&numeric-string&uppercase-string', strval(strval(rand()))); + assertType('decimal-int-string', strval(strval(rand()))); assertType('class-string', strval($class)); assertType('string', strval(new \Exception())); assertType('*ERROR*', strval(new \stdClass())); diff --git a/tests/PHPStan/Rules/Generics/data/bug-6301.php b/tests/PHPStan/Rules/Generics/data/bug-6301.php index 8d32598294..e31516c65c 100644 --- a/tests/PHPStan/Rules/Generics/data/bug-6301.php +++ b/tests/PHPStan/Rules/Generics/data/bug-6301.php @@ -22,7 +22,7 @@ public function str($s) * @param literal-string $literalString */ public function foo(int $i, $nonEmpty, $numericString, $literalString):void { - assertType('lowercase-string&numeric-string&uppercase-string', $this->str((string) $i)); + assertType('decimal-int-string', $this->str((string) $i)); assertType('non-empty-string', $this->str($nonEmpty)); assertType('numeric-string', $this->str($numericString)); assertType('literal-string', $this->str($literalString));