From 9162f2383ca71add7a84b017d6f58706ead27ee4 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Wed, 20 Nov 2024 09:33:24 +0100 Subject: [PATCH 1/2] Update Integer::toString() --- src/Type/IntegerRangeType.php | 3 ++ src/Type/IntegerType.php | 2 + .../Analyser/nsrt/array-key-exists.php | 8 ++-- tests/PHPStan/Analyser/nsrt/bug-10863.php | 4 +- tests/PHPStan/Analyser/nsrt/bug-11129.php | 44 +++++++++---------- tests/PHPStan/Analyser/nsrt/bug-11716.php | 2 +- tests/PHPStan/Analyser/nsrt/bug-4587.php | 4 +- tests/PHPStan/Analyser/nsrt/bug-7387.php | 8 ++-- tests/PHPStan/Analyser/nsrt/bug-8635.php | 2 +- .../Analyser/nsrt/cast-to-numeric-string.php | 28 ++++++------ tests/PHPStan/Analyser/nsrt/filter-var.php | 2 +- tests/PHPStan/Analyser/nsrt/generics.php | 6 +-- tests/PHPStan/Analyser/nsrt/key-exists.php | 8 ++-- .../PHPStan/Analyser/nsrt/range-to-string.php | 2 +- .../nsrt/set-type-type-specifying.php | 2 +- tests/PHPStan/Analyser/nsrt/strval.php | 4 +- .../PHPStan/Rules/Generics/data/bug-6301.php | 2 +- 17 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/Type/IntegerRangeType.php b/src/Type/IntegerRangeType.php index 248d994266..9d8e735f35 100644 --- a/src/Type/IntegerRangeType.php +++ b/src/Type/IntegerRangeType.php @@ -13,6 +13,7 @@ use PHPStan\Type\Accessory\AccessoryLowercaseStringType; 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; @@ -487,6 +488,7 @@ public function toString(): Type return new IntersectionType([ new StringType(), new AccessoryLowercaseStringType(), + new AccessoryUppercaseStringType(), new AccessoryNumericStringType(), new AccessoryNonFalsyStringType(), ]); @@ -495,6 +497,7 @@ public function toString(): Type return new IntersectionType([ new StringType(), new AccessoryLowercaseStringType(), + new AccessoryUppercaseStringType(), new AccessoryNumericStringType(), ]); } diff --git a/src/Type/IntegerType.php b/src/Type/IntegerType.php index 354067f0a9..535928c045 100644 --- a/src/Type/IntegerType.php +++ b/src/Type/IntegerType.php @@ -8,6 +8,7 @@ use PHPStan\TrinaryLogic; use PHPStan\Type\Accessory\AccessoryLowercaseStringType; use PHPStan\Type\Accessory\AccessoryNumericStringType; +use PHPStan\Type\Accessory\AccessoryUppercaseStringType; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\Traits\NonArrayTypeTrait; @@ -83,6 +84,7 @@ public function toString(): Type return new IntersectionType([ new StringType(), new AccessoryLowercaseStringType(), + new AccessoryUppercaseStringType(), new AccessoryNumericStringType(), ]); } diff --git a/tests/PHPStan/Analyser/nsrt/array-key-exists.php b/tests/PHPStan/Analyser/nsrt/array-key-exists.php index 3ae615b2d9..a7246dd043 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', $key2); + assertType('lowercase-string&numeric-string&uppercase-string', $key2); } if (array_key_exists($key3, $a)) { - assertType('int|(lowercase-string&numeric-string)', $key3); + assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key3); } if (array_key_exists($key4, $a)) { - assertType('(int|(lowercase-string&numeric-string))', $key4); + assertType('(int|(lowercase-string&numeric-string&uppercase-string))', $key4); } if (array_key_exists($key5, $a)) { - assertType('int|(lowercase-string&numeric-string)', $key5); + assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key5); } if (array_key_exists($key1, $b)) { diff --git a/tests/PHPStan/Analyser/nsrt/bug-10863.php b/tests/PHPStan/Analyser/nsrt/bug-10863.php index 275bc3774e..c88d354382 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-10863.php +++ b/tests/PHPStan/Analyser/nsrt/bug-10863.php @@ -12,7 +12,7 @@ class Foo */ public function doFoo($b): void { - assertType('lowercase-string&non-falsy-string', '@' . $b); + assertType('lowercase-string&non-falsy-string&uppercase-string', '@' . $b); } /** @@ -20,7 +20,7 @@ public function doFoo($b): void */ public function doFoo2($b): void { - assertType('lowercase-string&non-falsy-string', '@' . $b); + assertType('lowercase-string&non-falsy-string&uppercase-string', '@' . $b); } } diff --git a/tests/PHPStan/Analyser/nsrt/bug-11129.php b/tests/PHPStan/Analyser/nsrt/bug-11129.php index 1f60b4089f..4d0a3ff546 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-11129.php +++ b/tests/PHPStan/Analyser/nsrt/bug-11129.php @@ -21,14 +21,14 @@ public function foo( $maybeNegativeConstStrings, $maybeNonNumericConstStrings, $maybeFloatConstStrings, bool $bool, float $float ): void { - assertType('lowercase-string&non-falsy-string', '0'.$i); - assertType('lowercase-string&non-falsy-string&numeric-string', $i.'0'); + assertType('lowercase-string&non-falsy-string&uppercase-string', '0'.$i); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $i.'0'); - assertType('lowercase-string&non-falsy-string&numeric-string', '0'.$positiveInt); - assertType('lowercase-string&non-falsy-string&numeric-string', $positiveInt.'0'); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', '0'.$positiveInt); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $positiveInt.'0'); - assertType('lowercase-string&non-falsy-string', '0'.$negativeInt); - assertType('lowercase-string&non-falsy-string&numeric-string', $negativeInt.'0'); + assertType('lowercase-string&non-falsy-string&uppercase-string', '0'.$negativeInt); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $negativeInt.'0'); assertType("'00'|'01'|'02'", '0'.$positiveConstStrings); assertType( "'00'|'10'|'20'", $positiveConstStrings.'0'); @@ -39,29 +39,29 @@ public function foo( assertType("'00'|'01'|'0a'", '0'.$maybeNonNumericConstStrings); assertType("'00'|'10'|'a0'", $maybeNonNumericConstStrings.'0'); - assertType('lowercase-string&non-falsy-string&numeric-string', $i.$positiveConstStrings); - assertType('lowercase-string&non-falsy-string', $positiveConstStrings.$i); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $i.$positiveConstStrings); + assertType('lowercase-string&non-falsy-string&uppercase-string', $positiveConstStrings.$i); - assertType('lowercase-string&non-falsy-string', $i.$maybeNegativeConstStrings); - assertType('lowercase-string&non-falsy-string', $maybeNegativeConstStrings.$i); + assertType('lowercase-string&non-falsy-string&uppercase-string', $i.$maybeNegativeConstStrings); + assertType('lowercase-string&non-falsy-string&uppercase-string', $maybeNegativeConstStrings.$i); assertType('lowercase-string&non-falsy-string', $i.$maybeNonNumericConstStrings); assertType('lowercase-string&non-falsy-string', $maybeNonNumericConstStrings.$i); - assertType('lowercase-string&non-falsy-string', $i.$maybeFloatConstStrings); // could be 'lowercase-string&non-falsy-string&numeric-string' - assertType('lowercase-string&non-falsy-string', $maybeFloatConstStrings.$i); + assertType('lowercase-string&non-falsy-string&uppercase-string', $i.$maybeFloatConstStrings); // could be 'lowercase-string&non-falsy-string&numeric-string' + assertType('lowercase-string&non-falsy-string&uppercase-string', $maybeFloatConstStrings.$i); - assertType('lowercase-string&non-empty-string&numeric-string', $i.$bool); - assertType('lowercase-string&non-empty-string', $bool.$i); - assertType('lowercase-string&non-falsy-string&numeric-string', $positiveInt.$bool); - assertType('lowercase-string&non-falsy-string&numeric-string', $bool.$positiveInt); - assertType('lowercase-string&non-falsy-string&numeric-string', $negativeInt.$bool); - assertType('lowercase-string&non-falsy-string', $bool.$negativeInt); + assertType('lowercase-string&non-empty-string&numeric-string&uppercase-string', $i.$bool); + assertType('lowercase-string&non-empty-string&uppercase-string', $bool.$i); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $positiveInt.$bool); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $bool.$positiveInt); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $negativeInt.$bool); + assertType('lowercase-string&non-falsy-string&uppercase-string', $bool.$negativeInt); - assertType('lowercase-string&non-falsy-string', $i.$i); - assertType('lowercase-string&non-falsy-string', $negativeInt.$negativeInt); - assertType('lowercase-string&non-falsy-string', $maybeNegativeConstStrings.$negativeInt); - assertType('lowercase-string&non-falsy-string', $negativeInt.$maybeNegativeConstStrings); + assertType('lowercase-string&non-falsy-string&uppercase-string', $i.$i); + assertType('lowercase-string&non-falsy-string&uppercase-string', $negativeInt.$negativeInt); + assertType('lowercase-string&non-falsy-string&uppercase-string', $maybeNegativeConstStrings.$negativeInt); + assertType('lowercase-string&non-falsy-string&uppercase-string', $negativeInt.$maybeNegativeConstStrings); // https://3v4l.org/BCS2K assertType('non-falsy-string', $float.$float); diff --git a/tests/PHPStan/Analyser/nsrt/bug-11716.php b/tests/PHPStan/Analyser/nsrt/bug-11716.php index 83c10f3225..a2e86ffbec 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", $s); + assertType("lowercase-string&numeric-string&uppercase-string", $s); } else { assertType('string', $s); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-4587.php b/tests/PHPStan/Analyser/nsrt/bug-4587.php index 623fea93af..061c953a28 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}', $result); + assertType('array{a: lowercase-string&numeric-string&uppercase-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 4f28696fb9..1b283a7990 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', sprintf('%14s', $i)); + assertType('lowercase-string&numeric-string&uppercase-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', sprintf('%2$6s', $mixed, $i)); - assertType('lowercase-string&non-falsy-string&numeric-string', sprintf('%2$6s', $mixed, $posInt)); - assertType('lowercase-string&non-falsy-string&numeric-string', sprintf('%2$6s', $mixed, $negInt)); + 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("' 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 fe49aa8a2d..46d5b728b8 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', "$value"); + assertType('lowercase-string&numeric-string&uppercase-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 7c13500af2..5d59e2085e 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', (string)$a); + assertType('lowercase-string&numeric-string&uppercase-string', (string)$a); assertType('numeric-string', (string)$b); assertType('numeric-string', (string)$numeric); assertType('numeric-string', (string)$numeric2); assertType('numeric-string', (string)$number); - assertType('lowercase-string&non-falsy-string&numeric-string', (string)$positive); - assertType('lowercase-string&non-falsy-string&numeric-string', (string)$negative); + 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("'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', '' . $a); + assertType('lowercase-string&numeric-string&uppercase-string', '' . $a); assertType('numeric-string', '' . $b); assertType('numeric-string', '' . $numeric); assertType('numeric-string', '' . $numeric2); assertType('numeric-string', '' . $number); - assertType('lowercase-string&non-falsy-string&numeric-string', '' . $positive); - assertType('lowercase-string&non-falsy-string&numeric-string', '' . $negative); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', '' . $positive); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', '' . $negative); assertType("'1'", '' . $constantInt); - assertType('lowercase-string&numeric-string', $a . ''); + assertType('lowercase-string&numeric-string&uppercase-string', $a . ''); assertType('numeric-string', $b . ''); assertType('numeric-string', $numeric . ''); assertType('numeric-string', $numeric2 . ''); assertType('numeric-string', $number . ''); - assertType('lowercase-string&non-falsy-string&numeric-string', $positive . ''); - assertType('lowercase-string&non-falsy-string&numeric-string', $negative . ''); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $positive . ''); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', $negative . ''); assertType("'1'", $constantInt . ''); } function concatAssignEmptyString(int $i, float $f) { $i .= ''; - assertType('lowercase-string&numeric-string', $i); + assertType('lowercase-string&numeric-string&uppercase-string', $i); $s = ''; $s .= $f; @@ -66,13 +66,13 @@ function concatAssignEmptyString(int $i, float $f) { */ function integerRangeToString($positive, $negative) { - assertType('lowercase-string&numeric-string', (string) $positive); - assertType('lowercase-string&numeric-string', (string) $negative); + assertType('lowercase-string&numeric-string&uppercase-string', (string) $positive); + assertType('lowercase-string&numeric-string&uppercase-string', (string) $negative); if ($positive !== 0) { - assertType('lowercase-string&non-falsy-string&numeric-string', (string) $positive); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', (string) $positive); } if ($negative !== 0) { - assertType('lowercase-string&non-falsy-string&numeric-string', (string) $negative); + assertType('lowercase-string&non-falsy-string&numeric-string&uppercase-string', (string) $negative); } } diff --git a/tests/PHPStan/Analyser/nsrt/filter-var.php b/tests/PHPStan/Analyser/nsrt/filter-var.php index 28580c448c..e6fe1b87ee 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', filter_var($int)); + assertType('lowercase-string&numeric-string&uppercase-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 873ad66b6d..80f10030e8 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)', function (int $a): string { + assertType('Closure(int): (lowercase-string&numeric-string&uppercase-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 3c85802e73..23a2d0930d 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', $key2); + assertType('lowercase-string&numeric-string&uppercase-string', $key2); } if (key_exists($key3, $a)) { - assertType('int|(lowercase-string&numeric-string)', $key3); + assertType('int|(lowercase-string&numeric-string&uppercase-string)', $key3); } if (key_exists($key4, $a)) { - assertType('(int|(lowercase-string&numeric-string))', $key4); + assertType('(int|(lowercase-string&numeric-string&uppercase-string))', $key4); } if (key_exists($key5, $a)) { - assertType('int|(lowercase-string&numeric-string)', $key5); + assertType('int|(lowercase-string&numeric-string&uppercase-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 2d70eb4bab..49bb179309 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", (string) $toolong); + assertType("lowercase-string&numeric-string&uppercase-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 1ab4badbe5..05d0766dd8 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', $i); + assertType('lowercase-string&numeric-string&uppercase-string', $i); settype($f, 'string'); assertType('numeric-string', $f); diff --git a/tests/PHPStan/Analyser/nsrt/strval.php b/tests/PHPStan/Analyser/nsrt/strval.php index a6c4397893..41217e7c6c 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', strval(rand())); + assertType('lowercase-string&numeric-string&uppercase-string', strval(rand())); assertType('numeric-string', strval(rand() * 0.1)); - assertType('lowercase-string&numeric-string', strval(strval(rand()))); + assertType('lowercase-string&numeric-string&uppercase-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 73dff935f2..8d32598294 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', $this->str((string) $i)); + assertType('lowercase-string&numeric-string&uppercase-string', $this->str((string) $i)); assertType('non-empty-string', $this->str($nonEmpty)); assertType('numeric-string', $this->str($numericString)); assertType('literal-string', $this->str($literalString)); From 7d845813c576ddae83553c2b9efa9687e779929d Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Wed, 20 Nov 2024 12:31:17 +0100 Subject: [PATCH 2/2] Add float support --- src/Type/FloatType.php | 2 ++ tests/PHPStan/Analyser/nsrt/array-fill-keys.php | 2 +- tests/PHPStan/Analyser/nsrt/bug-11129.php | 10 +++++----- .../Analyser/nsrt/cast-to-numeric-string.php | 14 +++++++------- tests/PHPStan/Analyser/nsrt/filter-var.php | 2 +- .../nsrt/non-empty-string-replace-functions.php | 4 ++-- .../Analyser/nsrt/set-type-type-specifying.php | 2 +- tests/PHPStan/Analyser/nsrt/strval.php | 2 +- 8 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Type/FloatType.php b/src/Type/FloatType.php index 40ea01b5db..d086024868 100644 --- a/src/Type/FloatType.php +++ b/src/Type/FloatType.php @@ -7,6 +7,7 @@ use PHPStan\PhpDocParser\Ast\Type\TypeNode; use PHPStan\TrinaryLogic; use PHPStan\Type\Accessory\AccessoryNumericStringType; +use PHPStan\Type\Accessory\AccessoryUppercaseStringType; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantIntegerType; use PHPStan\Type\Traits\NonArrayTypeTrait; @@ -134,6 +135,7 @@ public function toString(): Type { return new IntersectionType([ new StringType(), + new AccessoryUppercaseStringType(), new AccessoryNumericStringType(), ]); } diff --git a/tests/PHPStan/Analyser/nsrt/array-fill-keys.php b/tests/PHPStan/Analyser/nsrt/array-fill-keys.php index 5054186320..00aa87fc69 100644 --- a/tests/PHPStan/Analyser/nsrt/array-fill-keys.php +++ b/tests/PHPStan/Analyser/nsrt/array-fill-keys.php @@ -91,7 +91,7 @@ function withNotConstantArray(array $foo, array $bar, array $baz, array $floats, assertType("array", array_fill_keys($foo, null)); assertType("array", array_fill_keys($bar, null)); assertType("array<'foo', null>", array_fill_keys($baz, null)); - assertType("array", array_fill_keys($floats, null)); + assertType("array", array_fill_keys($floats, null)); assertType("array", array_fill_keys($mixed, null)); assertType('array', array_fill_keys($list, null)); assertType('*ERROR*', array_fill_keys($objectsWithoutToString, null)); diff --git a/tests/PHPStan/Analyser/nsrt/bug-11129.php b/tests/PHPStan/Analyser/nsrt/bug-11129.php index 4d0a3ff546..a845bf1d2a 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-11129.php +++ b/tests/PHPStan/Analyser/nsrt/bug-11129.php @@ -64,11 +64,11 @@ public function foo( assertType('lowercase-string&non-falsy-string&uppercase-string', $negativeInt.$maybeNegativeConstStrings); // https://3v4l.org/BCS2K - assertType('non-falsy-string', $float.$float); - assertType('non-falsy-string&numeric-string', $float.$positiveInt); - assertType('non-falsy-string', $float.$negativeInt); - assertType('non-falsy-string', $float.$i); - assertType('non-falsy-string', $i.$float); // could be 'non-falsy-string&numeric-string' + assertType('non-falsy-string&uppercase-string', $float.$float); + assertType('non-falsy-string&numeric-string&uppercase-string', $float.$positiveInt); + assertType('non-falsy-string&uppercase-string', $float.$negativeInt); + assertType('non-falsy-string&uppercase-string', $float.$i); + assertType('non-falsy-string&uppercase-string', $i.$float); // could be 'non-falsy-string&numeric-string&uppercase-string' assertType('non-falsy-string', $numericString.$float); assertType('non-falsy-string', $numericString.$maybeFloatConstStrings); diff --git a/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php b/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php index 5d59e2085e..dfe47aa39b 100644 --- a/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php +++ b/tests/PHPStan/Analyser/nsrt/cast-to-numeric-string.php @@ -14,10 +14,10 @@ */ function foo(int $a, float $b, $numeric, $numeric2, $number, $positive, $negative, $constantInt): void { assertType('lowercase-string&numeric-string&uppercase-string', (string)$a); - assertType('numeric-string', (string)$b); + assertType('numeric-string&uppercase-string', (string)$b); assertType('numeric-string', (string)$numeric); assertType('numeric-string', (string)$numeric2); - assertType('numeric-string', (string)$number); + 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("'1'", (string)$constantInt); @@ -33,19 +33,19 @@ function foo(int $a, float $b, $numeric, $numeric2, $number, $positive, $negativ */ function concatEmptyString(int $a, float $b, $numeric, $numeric2, $number, $positive, $negative, $constantInt): void { assertType('lowercase-string&numeric-string&uppercase-string', '' . $a); - assertType('numeric-string', '' . $b); + assertType('numeric-string&uppercase-string', '' . $b); assertType('numeric-string', '' . $numeric); assertType('numeric-string', '' . $numeric2); - assertType('numeric-string', '' . $number); + 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("'1'", '' . $constantInt); assertType('lowercase-string&numeric-string&uppercase-string', $a . ''); - assertType('numeric-string', $b . ''); + assertType('numeric-string&uppercase-string', $b . ''); assertType('numeric-string', $numeric . ''); assertType('numeric-string', $numeric2 . ''); - assertType('numeric-string', $number . ''); + 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("'1'", $constantInt . ''); @@ -57,7 +57,7 @@ function concatAssignEmptyString(int $i, float $f) { $s = ''; $s .= $f; - assertType('numeric-string', $s); + assertType('numeric-string&uppercase-string', $s); } /** diff --git a/tests/PHPStan/Analyser/nsrt/filter-var.php b/tests/PHPStan/Analyser/nsrt/filter-var.php index e6fe1b87ee..abe5331fc6 100644 --- a/tests/PHPStan/Analyser/nsrt/filter-var.php +++ b/tests/PHPStan/Analyser/nsrt/filter-var.php @@ -154,7 +154,7 @@ public function scalars(bool $bool, float $float, int $int, string $string, int assertType("''|'1'", filter_var($bool)); assertType("'1'", filter_var(true)); assertType("''", filter_var(false)); - assertType('numeric-string', filter_var($float)); + assertType('numeric-string&uppercase-string', filter_var($float)); assertType("'17'", filter_var(17.0)); assertType("'17.1'", filter_var(17.1)); assertType("'1.0E-50'", filter_var(1e-50)); diff --git a/tests/PHPStan/Analyser/nsrt/non-empty-string-replace-functions.php b/tests/PHPStan/Analyser/nsrt/non-empty-string-replace-functions.php index 3627b8a409..a774b4eba4 100644 --- a/tests/PHPStan/Analyser/nsrt/non-empty-string-replace-functions.php +++ b/tests/PHPStan/Analyser/nsrt/non-empty-string-replace-functions.php @@ -26,9 +26,9 @@ public function replace(string $search, string $replacement, string $subject){ function foo(float $f) { $s = (string) $f; - assertType('numeric-string', $s); + assertType('numeric-string&uppercase-string', $s); $price = str_replace(',', '.', $s); - assertType('non-empty-string', $price); + assertType('non-empty-string&uppercase-string', $price); } } diff --git a/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php b/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php index 05d0766dd8..f7513c6045 100644 --- a/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php +++ b/tests/PHPStan/Analyser/nsrt/set-type-type-specifying.php @@ -14,7 +14,7 @@ function doString(string $s, int $i, float $f, array $a, object $o) assertType('lowercase-string&numeric-string&uppercase-string', $i); settype($f, 'string'); - assertType('numeric-string', $f); + assertType('numeric-string&uppercase-string', $f); settype($a, 'string'); assertType('*ERROR*', $a); diff --git a/tests/PHPStan/Analyser/nsrt/strval.php b/tests/PHPStan/Analyser/nsrt/strval.php index 41217e7c6c..b28f31549b 100644 --- a/tests/PHPStan/Analyser/nsrt/strval.php +++ b/tests/PHPStan/Analyser/nsrt/strval.php @@ -18,7 +18,7 @@ function strvalTest(string $string, string $class): void assertType('\'\'|\'1\'', strval(rand(0, 1) === 0)); assertType('\'42\'', strval(42)); assertType('lowercase-string&numeric-string&uppercase-string', strval(rand())); - assertType('numeric-string', strval(rand() * 0.1)); + assertType('numeric-string&uppercase-string', strval(rand() * 0.1)); assertType('lowercase-string&numeric-string&uppercase-string', strval(strval(rand()))); assertType('class-string', strval($class)); assertType('string', strval(new \Exception()));