Skip to content

Commit ca2c937

Browse files
authored
Introduce uppercase-string
1 parent cb9be91 commit ca2c937

File tree

79 files changed

+1321
-66
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1321
-66
lines changed

conf/config.neon

+10
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,11 @@ services:
15641564
tags:
15651565
- phpstan.dynamicFunctionThrowTypeExtension
15661566

1567+
-
1568+
class: PHPStan\Type\Php\ParseStrParameterOutTypeExtension
1569+
tags:
1570+
- phpstan.functionParameterOutTypeExtension
1571+
15671572
-
15681573
class: PHPStan\Type\Php\PregMatchTypeSpecifyingExtension
15691574
tags:
@@ -1774,6 +1779,11 @@ services:
17741779
tags:
17751780
- phpstan.broker.dynamicFunctionReturnTypeExtension
17761781

1782+
-
1783+
class: PHPStan\Type\Php\TrimFunctionDynamicReturnTypeExtension
1784+
tags:
1785+
- phpstan.broker.dynamicFunctionReturnTypeExtension
1786+
17771787
-
17781788
class: PHPStan\Type\Php\VersionCompareFunctionDynamicReturnTypeExtension
17791789
tags:

phpstan-baseline.neon

+5
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,11 @@ parameters:
715715
count: 1
716716
path: src/Type/Accessory/AccessoryNumericStringType.php
717717

718+
-
719+
message: "#^Doing instanceof PHPStan\\\\Type\\\\IntersectionType is error\\-prone and deprecated\\.$#"
720+
count: 1
721+
path: src/Type/Accessory/AccessoryUppercaseStringType.php
722+
718723
-
719724
message: "#^Doing instanceof PHPStan\\\\Type\\\\IntersectionType is error\\-prone and deprecated\\.$#"
720725
count: 1

resources/functionMap.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -6362,7 +6362,7 @@
63626362
'mb_strrpos' => ['0|positive-int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'],
63636363
'mb_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'],
63646364
'mb_strtolower' => ['lowercase-string', 'str'=>'string', 'encoding='=>'string'],
6365-
'mb_strtoupper' => ['string', 'str'=>'string', 'encoding='=>'string'],
6365+
'mb_strtoupper' => ['uppercase-string', 'str'=>'string', 'encoding='=>'string'],
63666366
'mb_strwidth' => ['0|positive-int', 'str'=>'string', 'encoding='=>'string'],
63676367
'mb_substitute_character' => ['mixed', 'substchar='=>'mixed'],
63686368
'mb_substr' => ['string', 'str'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'],
@@ -12087,7 +12087,7 @@
1208712087
'strtok\'1' => ['non-empty-string|false', 'token'=>'string'],
1208812088
'strtolower' => ['lowercase-string', 'str'=>'string'],
1208912089
'strtotime' => ['int|false', 'time'=>'string', 'now='=>'int'],
12090-
'strtoupper' => ['string', 'str'=>'string'],
12090+
'strtoupper' => ['uppercase-string', 'str'=>'string'],
1209112091
'strtr' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'],
1209212092
'strtr\'1' => ['string', 'str'=>'string', 'replace_pairs'=>'array'],
1209312093
'strval' => ['string', 'var'=>'__stringAndStringable|int|float|bool|resource|null'],

src/PhpDoc/TypeNodeResolver.php

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
5151
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
5252
use PHPStan\Type\Accessory\AccessoryNumericStringType;
53+
use PHPStan\Type\Accessory\AccessoryUppercaseStringType;
5354
use PHPStan\Type\Accessory\NonEmptyArrayType;
5455
use PHPStan\Type\ArrayType;
5556
use PHPStan\Type\BenevolentUnionType;
@@ -223,6 +224,9 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
223224
case 'lowercase-string':
224225
return new IntersectionType([new StringType(), new AccessoryLowercaseStringType()]);
225226

227+
case 'uppercase-string':
228+
return new IntersectionType([new StringType(), new AccessoryUppercaseStringType()]);
229+
226230
case 'literal-string':
227231
return new IntersectionType([new StringType(), new AccessoryLiteralStringType()]);
228232

@@ -303,6 +307,13 @@ private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameSco
303307
new AccessoryLowercaseStringType(),
304308
]);
305309

310+
case 'non-empty-uppercase-string':
311+
return new IntersectionType([
312+
new StringType(),
313+
new AccessoryNonEmptyStringType(),
314+
new AccessoryUppercaseStringType(),
315+
]);
316+
306317
case 'truthy-string':
307318
case 'non-falsy-string':
308319
return new IntersectionType([

src/Reflection/InitializerExprTypeResolver.php

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
3232
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
3333
use PHPStan\Type\Accessory\AccessoryNumericStringType;
34+
use PHPStan\Type\Accessory\AccessoryUppercaseStringType;
3435
use PHPStan\Type\Accessory\NonEmptyArrayType;
3536
use PHPStan\Type\ArrayType;
3637
use PHPStan\Type\BenevolentUnionType;
@@ -480,10 +481,15 @@ public function resolveConcatType(Type $left, Type $right): Type
480481
if ($leftStringType->isLiteralString()->and($rightStringType->isLiteralString())->yes()) {
481482
$accessoryTypes[] = new AccessoryLiteralStringType();
482483
}
484+
483485
if ($leftStringType->isLowercaseString()->and($rightStringType->isLowercaseString())->yes()) {
484486
$accessoryTypes[] = new AccessoryLowercaseStringType();
485487
}
486488

489+
if ($leftStringType->isUppercaseString()->and($rightStringType->isUppercaseString())->yes()) {
490+
$accessoryTypes[] = new AccessoryUppercaseStringType();
491+
}
492+
487493
$leftNumericStringNonEmpty = TypeCombinator::remove($leftStringType, new ConstantStringType(''));
488494
if ($leftNumericStringNonEmpty->isNumericString()->yes()) {
489495
$allRightConstantsZeroOrMore = false;

src/Rules/Api/ApiInstanceofTypeRule.php

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
1717
use PHPStan\Type\Accessory\AccessoryNumericStringType;
1818
use PHPStan\Type\Accessory\AccessoryType;
19+
use PHPStan\Type\Accessory\AccessoryUppercaseStringType;
1920
use PHPStan\Type\Accessory\HasMethodType;
2021
use PHPStan\Type\Accessory\HasOffsetType;
2122
use PHPStan\Type\Accessory\HasPropertyType;
@@ -86,6 +87,7 @@ final class ApiInstanceofTypeRule implements Rule
8687
AccessoryNumericStringType::class => 'Type::isNumericString()',
8788
AccessoryLiteralStringType::class => 'Type::isLiteralString()',
8889
AccessoryLowercaseStringType::class => 'Type::isLowercaseString()',
90+
AccessoryUppercaseStringType::class => 'Type::isUppercaseString()',
8991
AccessoryNonEmptyStringType::class => 'Type::isNonEmptyString()',
9092
AccessoryNonFalsyStringType::class => 'Type::isNonFalsyString()',
9193
HasMethodType::class => 'Type::hasMethod()',

src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,26 @@ public function processNode(Node $node, Scope $scope): array
7575
};
7676

7777
$verbosity = VerbosityLevel::value();
78+
7879
if (
7980
(
8081
$leftType->isConstantScalarValue()->yes()
8182
&& !$leftType->isString()->no()
8283
&& !$rightType->isConstantScalarValue()->yes()
8384
&& !$rightType->isString()->no()
84-
&& TrinaryLogic::extremeIdentity($leftType->isLowercaseString(), $rightType->isLowercaseString())->maybe()
85+
&& (
86+
TrinaryLogic::extremeIdentity($leftType->isLowercaseString(), $rightType->isLowercaseString())->maybe()
87+
|| TrinaryLogic::extremeIdentity($leftType->isUppercaseString(), $rightType->isUppercaseString())->maybe()
88+
)
8589
) || (
8690
$rightType->isConstantScalarValue()->yes()
8791
&& !$rightType->isString()->no()
8892
&& !$leftType->isConstantScalarValue()->yes()
8993
&& !$leftType->isString()->no()
90-
&& TrinaryLogic::extremeIdentity($leftType->isLowercaseString(), $rightType->isLowercaseString())->maybe()
94+
&& (
95+
TrinaryLogic::extremeIdentity($leftType->isLowercaseString(), $rightType->isLowercaseString())->maybe()
96+
|| TrinaryLogic::extremeIdentity($leftType->isUppercaseString(), $rightType->isUppercaseString())->maybe()
97+
)
9198
)
9299
) {
93100
$verbosity = VerbosityLevel::precise();

src/Type/Accessory/AccessoryArrayListType.php

+5
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,11 @@ public function isLowercaseString(): TrinaryLogic
414414
return TrinaryLogic::createNo();
415415
}
416416

417+
public function isUppercaseString(): TrinaryLogic
418+
{
419+
return TrinaryLogic::createNo();
420+
}
421+
417422
public function isClassStringType(): TrinaryLogic
418423
{
419424
return TrinaryLogic::createNo();

src/Type/Accessory/AccessoryLiteralStringType.php

+5
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,11 @@ public function isLowercaseString(): TrinaryLogic
313313
return TrinaryLogic::createMaybe();
314314
}
315315

316+
public function isUppercaseString(): TrinaryLogic
317+
{
318+
return TrinaryLogic::createMaybe();
319+
}
320+
316321
public function isClassStringType(): TrinaryLogic
317322
{
318323
return TrinaryLogic::createMaybe();

src/Type/Accessory/AccessoryLowercaseStringType.php

+5
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ public function isLowercaseString(): TrinaryLogic
309309
return TrinaryLogic::createYes();
310310
}
311311

312+
public function isUppercaseString(): TrinaryLogic
313+
{
314+
return TrinaryLogic::createMaybe();
315+
}
316+
312317
public function isClassStringType(): TrinaryLogic
313318
{
314319
return TrinaryLogic::createMaybe();

src/Type/Accessory/AccessoryNonEmptyStringType.php

+5
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@ public function isLowercaseString(): TrinaryLogic
310310
return TrinaryLogic::createMaybe();
311311
}
312312

313+
public function isUppercaseString(): TrinaryLogic
314+
{
315+
return TrinaryLogic::createMaybe();
316+
}
317+
313318
public function isClassStringType(): TrinaryLogic
314319
{
315320
return TrinaryLogic::createMaybe();

src/Type/Accessory/AccessoryNonFalsyStringType.php

+5
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,11 @@ public function isLowercaseString(): TrinaryLogic
310310
return TrinaryLogic::createMaybe();
311311
}
312312

313+
public function isUppercaseString(): TrinaryLogic
314+
{
315+
return TrinaryLogic::createMaybe();
316+
}
317+
313318
public function isClassStringType(): TrinaryLogic
314319
{
315320
return TrinaryLogic::createMaybe();

src/Type/Accessory/AccessoryNumericStringType.php

+5
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ public function isLowercaseString(): TrinaryLogic
312312
return TrinaryLogic::createMaybe();
313313
}
314314

315+
public function isUppercaseString(): TrinaryLogic
316+
{
317+
return TrinaryLogic::createMaybe();
318+
}
319+
315320
public function isClassStringType(): TrinaryLogic
316321
{
317322
return TrinaryLogic::createNo();

0 commit comments

Comments
 (0)