Skip to content

Commit

Permalink
Support numeric-string in ConstantString->generalize()
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Feb 22, 2024
1 parent c73d75c commit 6275102
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 12 deletions.
24 changes: 14 additions & 10 deletions src/Type/Constant/ConstantStringType.php
Expand Up @@ -22,6 +22,7 @@
use PHPStan\Type\Accessory\AccessoryLiteralStringType;
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
use PHPStan\Type\Accessory\AccessoryNumericStringType;
use PHPStan\Type\ClassStringType;
use PHPStan\Type\CompoundType;
use PHPStan\Type\ConstantScalarType;
Expand Down Expand Up @@ -407,19 +408,22 @@ public function generalize(GeneralizePrecision $precision): Type
}

if ($this->getValue() !== '' && $precision->isMoreSpecific()) {
$accessories = [
new StringType(),
new AccessoryLiteralStringType(),
];

if (is_numeric($this->getValue())) {
$accessories[] = new AccessoryNumericStringType();
}

if ($this->getValue() !== '0') {
return new IntersectionType([
new StringType(),
new AccessoryNonFalsyStringType(),
new AccessoryLiteralStringType(),
]);
$accessories[] = new AccessoryNonFalsyStringType();
} else {
$accessories[] = new AccessoryNonEmptyStringType();
}

return new IntersectionType([
new StringType(),
new AccessoryNonEmptyStringType(),
new AccessoryLiteralStringType(),
]);
return new IntersectionType($accessories);
}

if ($precision->isMoreSpecific()) {
Expand Down
3 changes: 2 additions & 1 deletion src/Type/Php/StrRepeatFunctionReturnTypeExtension.php
Expand Up @@ -20,6 +20,7 @@
use function count;
use function str_repeat;
use function strlen;
use function strpos;

class StrRepeatFunctionReturnTypeExtension implements DynamicFunctionReturnTypeExtension
{
Expand Down Expand Up @@ -76,7 +77,7 @@ public function getTypeFromFunctionCall(

if ($inputType->isNumericString()->yes()) {
$hasDecimalPoint = false;
foreach($inputType->getConstantStrings() as $constantString) {
foreach ($inputType->getConstantStrings() as $constantString) {
if (strpos($constantString->getValue(), '.') !== false) {
$hasDecimalPoint = true;
break;
Expand Down
3 changes: 2 additions & 1 deletion tests/PHPStan/Type/Constant/ConstantStringTypeTest.php
Expand Up @@ -154,7 +154,8 @@ public function testGeneralize(): void
$this->assertSame('literal-string&non-falsy-string', (new ConstantStringType('NonexistentClass'))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('literal-string', (new ConstantStringType(''))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('literal-string&non-falsy-string', (new ConstantStringType('a'))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('literal-string&non-empty-string', (new ConstantStringType('0'))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('literal-string&non-empty-string&numeric-string', (new ConstantStringType('0'))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('literal-string&non-falsy-string&numeric-string', (new ConstantStringType('1.123'))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('string', (new ConstantStringType(''))->generalize(GeneralizePrecision::lessSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('string', (new ConstantStringType('a'))->generalize(GeneralizePrecision::lessSpecific())->describe(VerbosityLevel::precise()));
$this->assertSame('literal-string&non-falsy-string', (new ConstantStringType(stdClass::class))->generalize(GeneralizePrecision::moreSpecific())->describe(VerbosityLevel::precise()));
Expand Down

0 comments on commit 6275102

Please sign in to comment.