Skip to content

Commit

Permalink
Type::getFiniteTypes()
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 19, 2023
1 parent 175307e commit 7912caf
Show file tree
Hide file tree
Showing 38 changed files with 423 additions and 1 deletion.
5 changes: 5 additions & 0 deletions src/Type/Accessory/AccessoryArrayListType.php
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('list');
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/AccessoryLiteralStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@ public function exponentiate(Type $exponent): Type
]);
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('literal-string');
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/AccessoryNonEmptyStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,11 @@ public function exponentiate(Type $exponent): Type
]);
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('non-empty-string');
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/AccessoryNonFalsyStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,11 @@ public function exponentiate(Type $exponent): Type
]);
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('non-falsy-string');
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/AccessoryNumericStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ public function exponentiate(Type $exponent): Type
]);
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('numeric-string');
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/HasMethodType.php
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public static function __set_state(array $properties): Type
{
return new self($properties['methodName']);
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/HasOffsetType.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public static function __set_state(array $properties): Type
{
return new self($properties['offsetType']);
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/HasOffsetValueType.php
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public static function __set_state(array $properties): Type
{
return new self($properties['offsetType'], $properties['valueType']);
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/HasPropertyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public static function __set_state(array $properties): Type
{
return new self($properties['propertyName']);
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/NonEmptyArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public static function __set_state(array $properties): Type
{
return new self();
Expand Down
5 changes: 5 additions & 0 deletions src/Type/Accessory/OversizedArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public static function __set_state(array $properties): Type
{
return new self();
Expand Down
5 changes: 5 additions & 0 deletions src/Type/ArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

/**
* @param mixed[] $properties
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Type/BooleanType.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ public function tryRemove(Type $typeToRemove): ?Type
return null;
}

public function getFiniteTypes(): array
{
return [
new ConstantBooleanType(true),
new ConstantBooleanType(false),
];
}

public function exponentiate(Type $exponent): Type
{
return ExponentiateHelper::exponentiate($this, $exponent);
Expand Down
5 changes: 5 additions & 0 deletions src/Type/CallableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
if ($this->isCommonCallable) {
Expand Down
5 changes: 5 additions & 0 deletions src/Type/ClosureType.php
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
$parameters = [];
Expand Down
40 changes: 40 additions & 0 deletions src/Type/Constant/ConstantArrayType.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Type\Constant;

use Nette\Utils\Strings;
use PHPStan\Internal\CombinationsHelper;
use PHPStan\Php\PhpVersion;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
Expand All @@ -13,6 +14,7 @@
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Reflection\InaccessibleMethod;
use PHPStan\Reflection\InitializerExprTypeResolver;
use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\Reflection\TrivialParametersAcceptor;
use PHPStan\ShouldNotHappenException;
Expand Down Expand Up @@ -1606,6 +1608,44 @@ public static function isValidIdentifier(string $value): bool
return $result !== null;
}

public function getFiniteTypes(): array
{
$arraysArraysForCombinations = [];
$count = 0;
foreach ($this->getAllArrays() as $array) {
$values = $array->getValueTypes();
$arraysForCombinations = [];
$combinationCount = 1;
foreach ($values as $valueType) {
if ($valueType->getFiniteTypes() === []) {
return [];
}
$arraysForCombinations[] = $valueType->getFiniteTypes();
$combinationCount *= count($valueType->getFiniteTypes());
}
$arraysArraysForCombinations[] = $arraysForCombinations;
$count += $combinationCount;
}

if ($count > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) {
return [];
}

$finiteTypes = [];
foreach ($arraysArraysForCombinations as $arraysForCombinations) {
$combinations = CombinationsHelper::combinations($arraysForCombinations);
foreach ($combinations as $combination) {
$builder = ConstantArrayTypeBuilder::createEmpty();
foreach ($combination as $i => $v) {
$builder->setOffsetValueType($this->keyTypes[$i], $v);
}
$finiteTypes[] = $builder->getArray();
}
}

return $finiteTypes;
}

/**
* @param mixed[] $properties
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Type/FloatType.php
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ public function toPhpDocNode(): TypeNode
return new IdentifierTypeNode('float');
}

public function getFiniteTypes(): array
{
return [];
}

/**
* @param mixed[] $properties
*/
Expand Down
20 changes: 20 additions & 0 deletions src/Type/IntegerRangeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Reflection\InitializerExprTypeResolver;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantIntegerType;
Expand Down Expand Up @@ -615,6 +616,25 @@ public function exponentiate(Type $exponent): Type
return parent::exponentiate($exponent);
}

public function getFiniteTypes(): array
{
if ($this->min === null || $this->max === null) {
return [];
}

$size = $this->max - $this->min;
if ($size > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) {
return [];
}

$types = [];
for ($i = $this->min; $i <= $this->max; $i++) {
$types[] = new ConstantIntegerType($i);
}

return $types;
}

public function toPhpDocNode(): TypeNode
{
if ($this->min === null) {
Expand Down
5 changes: 5 additions & 0 deletions src/Type/IntegerType.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ public function tryRemove(Type $typeToRemove): ?Type
return null;
}

public function getFiniteTypes(): array
{
return [];
}

public function exponentiate(Type $exponent): Type
{
return ExponentiateHelper::exponentiate($this, $exponent);
Expand Down
24 changes: 23 additions & 1 deletion src/Type/IntersectionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PHPStan\Reflection\ClassMemberAccessAnswerer;
use PHPStan\Reflection\ConstantReflection;
use PHPStan\Reflection\ExtendedMethodReflection;
use PHPStan\Reflection\InitializerExprTypeResolver;
use PHPStan\Reflection\ParametersAcceptor;
use PHPStan\Reflection\PropertyReflection;
use PHPStan\Reflection\TrivialParametersAcceptor;
Expand Down Expand Up @@ -40,6 +41,7 @@
use function implode;
use function in_array;
use function ksort;
use function md5;
use function sprintf;
use function strlen;
use function substr;
Expand Down Expand Up @@ -719,7 +721,7 @@ public function getEnumCases(): array
foreach ($this->types as $type) {
$oneType = [];
foreach ($type->getEnumCases() as $enumCase) {
$oneType[$enumCase->describe(VerbosityLevel::typeOnly())] = $enumCase;
$oneType[md5($enumCase->describe(VerbosityLevel::typeOnly()))] = $enumCase;
}
$compare[] = $oneType;
}
Expand Down Expand Up @@ -995,6 +997,26 @@ public function exponentiate(Type $exponent): Type
return $this->intersectTypes(static fn (Type $type): Type => $type->exponentiate($exponent));
}

public function getFiniteTypes(): array
{
$compare = [];
foreach ($this->types as $type) {
$oneType = [];
foreach ($type->getFiniteTypes() as $finiteType) {
$oneType[md5($finiteType->describe(VerbosityLevel::typeOnly()))] = $finiteType;
}
$compare[] = $oneType;
}

$result = array_values(array_intersect_key(...$compare));

if (count($result) > InitializerExprTypeResolver::CALCULATE_SCALARS_LIMIT) {
return [];
}

return $result;
}

/**
* @param mixed[] $properties
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Type/IterableType.php
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@ public function exponentiate(Type $exponent): Type
return new ErrorType();
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
$isMixedKeyType = $this->keyType instanceof MixedType && $this->keyType->describe(VerbosityLevel::precise()) === 'mixed';
Expand Down
5 changes: 5 additions & 0 deletions src/Type/MixedType.php
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,11 @@ public function exponentiate(Type $exponent): Type
]);
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('mixed');
Expand Down
5 changes: 5 additions & 0 deletions src/Type/NeverType.php
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,11 @@ public function exponentiate(Type $exponent): Type
return $this;
}

public function getFiniteTypes(): array
{
return [];
}

public function toPhpDocNode(): TypeNode
{
return new IdentifierTypeNode('never');
Expand Down
Loading

0 comments on commit 7912caf

Please sign in to comment.