Skip to content

Commit

Permalink
Delegate most of TypeCombinator::remove() to Type::tryRemove()
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaud-lb committed Feb 4, 2022
1 parent 9512513 commit 44866d8
Show file tree
Hide file tree
Showing 35 changed files with 263 additions and 94 deletions.
2 changes: 2 additions & 0 deletions src/Type/Accessory/AccessoryLiteralStringType.php
Expand Up @@ -17,6 +17,7 @@
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonObjectTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
Expand All @@ -30,6 +31,7 @@ class AccessoryLiteralStringType implements CompoundType, AccessoryType
use NonIterableTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonGenericTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct()
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/AccessoryNonEmptyStringType.php
Expand Up @@ -15,6 +15,7 @@
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonObjectTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\TruthyBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -30,6 +31,7 @@ class AccessoryNonEmptyStringType implements CompoundType, AccessoryType
use TruthyBooleanTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonGenericTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct()
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/AccessoryNumericStringType.php
Expand Up @@ -15,6 +15,7 @@
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonObjectTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -30,6 +31,7 @@ class AccessoryNumericStringType implements CompoundType, AccessoryType
use UndecidedBooleanTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonGenericTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct()
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/HasMethodType.php
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Type\CompoundType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\ObjectTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -26,6 +27,7 @@ class HasMethodType implements AccessoryType, CompoundType
use ObjectTypeTrait;
use NonGenericTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct(private string $methodName)
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/HasOffsetType.php
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Type\Traits\MaybeIterableTypeTrait;
use PHPStan\Type\Traits\MaybeObjectTypeTrait;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\TruthyBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -28,6 +29,7 @@ class HasOffsetType implements CompoundType, AccessoryType
use TruthyBooleanTypeTrait;
use NonGenericTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct(private Type $offsetType)
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/HasPropertyType.php
Expand Up @@ -8,6 +8,7 @@
use PHPStan\Type\CompoundType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\ObjectTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -21,6 +22,7 @@ class HasPropertyType implements AccessoryType, CompoundType
use ObjectTypeTrait;
use NonGenericTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct(private string $propertyName)
Expand Down
2 changes: 2 additions & 0 deletions src/Type/Accessory/NonEmptyArrayType.php
Expand Up @@ -12,6 +12,7 @@
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonObjectTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\TruthyBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use PHPStan\Type\Type;
Expand All @@ -26,6 +27,7 @@ class NonEmptyArrayType implements CompoundType, AccessoryType
use TruthyBooleanTypeTrait;
use NonGenericTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct()
Expand Down
18 changes: 18 additions & 0 deletions src/Type/ArrayType.php
Expand Up @@ -7,6 +7,7 @@
use PHPStan\Reflection\TrivialParametersAcceptor;
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Accessory\HasOffsetType;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantFloatType;
Expand Down Expand Up @@ -420,6 +421,23 @@ public function traverse(callable $cb): Type
return $this;
}

public function tryRemove(Type $typeToRemove): ?Type
{
if ($typeToRemove instanceof ConstantArrayType && $typeToRemove->isIterableAtLeastOnce()->no()) {
return TypeCombinator::intersect($this, new NonEmptyArrayType());
}

if ($typeToRemove instanceof NonEmptyArrayType) {
return new ConstantArrayType([], []);
}

if ($this instanceof ConstantArrayType && $typeToRemove instanceof HasOffsetType) {
return $this->unsetOffset($typeToRemove->getOffsetType());
}

return null;
}

/**
* @param mixed[] $properties
*/
Expand Down
10 changes: 10 additions & 0 deletions src/Type/BooleanType.php
Expand Up @@ -3,6 +3,7 @@
namespace PHPStan\Type;

use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantFloatType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
Expand Down Expand Up @@ -75,6 +76,15 @@ public function toArray(): Type
);
}

public function tryRemove(Type $typeToRemove): ?Type
{
if ($typeToRemove instanceof ConstantBooleanType) {
return new ConstantBooleanType(!$typeToRemove->getValue());
}

return null;
}

/**
* @param mixed[] $properties
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Type/CallableType.php
Expand Up @@ -16,6 +16,7 @@
use PHPStan\Type\Traits\MaybeIterableTypeTrait;
use PHPStan\Type\Traits\MaybeObjectTypeTrait;
use PHPStan\Type\Traits\MaybeOffsetAccessibleTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\TruthyBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;
use function array_map;
Expand All @@ -32,6 +33,7 @@ class CallableType implements CompoundType, ParametersAcceptor
use MaybeOffsetAccessibleTypeTrait;
use TruthyBooleanTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;

/** @var array<int, ParameterReflection> */
private array $parameters;
Expand Down
2 changes: 2 additions & 0 deletions src/Type/ClosureType.php
Expand Up @@ -24,6 +24,7 @@
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
use function array_map;
use function array_merge;
Expand All @@ -37,6 +38,7 @@ class ClosureType implements TypeWithClassName, ParametersAcceptor
use NonGenericTypeTrait;
use UndecidedComparisonTypeTrait;
use NonOffsetAccessibleTypeTrait;
use NonRemoveableTypeTrait;

private ObjectType $objectType;

Expand Down
9 changes: 9 additions & 0 deletions src/Type/Enum/EnumCaseObjectType.php
Expand Up @@ -91,6 +91,15 @@ public function getSubtractedType(): ?Type
return null;
}

public function tryRemove(Type $typeToRemove): ?Type
{
if ($this->isSuperTypeOf($typeToRemove)->yes()) {
return $this->subtract($typeToRemove);
}

return null;
}

public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection
{
$classReflection = $this->getClassReflection();
Expand Down
2 changes: 2 additions & 0 deletions src/Type/FloatType.php
Expand Up @@ -11,6 +11,7 @@
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonObjectTypeTrait;
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
use function get_class;
Expand All @@ -26,6 +27,7 @@ class FloatType implements Type
use UndecidedComparisonTypeTrait;
use NonGenericTypeTrait;
use NonOffsetAccessibleTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct()
Expand Down
3 changes: 3 additions & 0 deletions src/Type/Generic/TemplateTypeTrait.php
Expand Up @@ -5,6 +5,7 @@
use PHPStan\TrinaryLogic;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use PHPStan\Type\VerbosityLevel;
Expand All @@ -16,6 +17,8 @@
trait TemplateTypeTrait
{

use NonRemoveableTypeTrait;

private string $name;

private TemplateTypeScope $scope;
Expand Down
21 changes: 21 additions & 0 deletions src/Type/IntegerType.php
Expand Up @@ -76,4 +76,25 @@ public function toArray(): Type
);
}

public function tryRemove(Type $typeToRemove): ?Type
{
if ($typeToRemove instanceof IntegerRangeType || $typeToRemove instanceof ConstantIntegerType) {
if ($typeToRemove instanceof IntegerRangeType) {
$removeValueMin = $typeToRemove->getMin();
$removeValueMax = $typeToRemove->getMax();
} else {
$removeValueMin = $typeToRemove->getValue();
$removeValueMax = $typeToRemove->getValue();
}
$lowerPart = $removeValueMin !== null ? IntegerRangeType::fromInterval(null, $removeValueMin, -1) : null;
$upperPart = $removeValueMax !== null ? IntegerRangeType::fromInterval($removeValueMax, null, +1) : null;
if ($lowerPart !== null && $upperPart !== null) {
return new UnionType([$lowerPart, $upperPart]);
}
return $lowerPart ?? $upperPart ?? new NeverType();
}

return null;
}

}
3 changes: 3 additions & 0 deletions src/Type/IntersectionType.php
Expand Up @@ -22,6 +22,7 @@
use PHPStan\Type\Generic\TemplateType;
use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Generic\TemplateTypeVariance;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use function array_map;
use function count;
use function implode;
Expand All @@ -34,6 +35,8 @@
class IntersectionType implements CompoundType
{

use NonRemoveableTypeTrait;

/** @var Type[] */
private array $types;

Expand Down
19 changes: 19 additions & 0 deletions src/Type/IterableType.php
Expand Up @@ -4,6 +4,7 @@

use PHPStan\TrinaryLogic;
use PHPStan\Type\Constant\ConstantArrayType;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\Generic\TemplateMixedType;
use PHPStan\Type\Generic\TemplateType;
use PHPStan\Type\Generic\TemplateTypeMap;
Expand Down Expand Up @@ -278,6 +279,24 @@ public function traverse(callable $cb): Type
return $this;
}

public function tryRemove(Type $typeToRemove): ?Type
{
$arrayType = new ArrayType(new MixedType(), new MixedType());
if ($typeToRemove->isSuperTypeOf($arrayType)->yes()) {
return new GenericObjectType(Traversable::class, [
$this->getIterableKeyType(),
$this->getIterableValueType(),
]);
}

$traversableType = new ObjectType(Traversable::class);
if ($typeToRemove->isSuperTypeOf($traversableType)->yes()) {
return new ArrayType($this->getIterableKeyType(), $this->getIterableValueType());
}

return null;
}

/**
* @param mixed[] $properties
*/
Expand Down
9 changes: 9 additions & 0 deletions src/Type/MixedType.php
Expand Up @@ -420,6 +420,15 @@ public function isLiteralString(): TrinaryLogic
return TrinaryLogic::createMaybe();
}

public function tryRemove(Type $typeToRemove): ?Type
{
if ($this->isSuperTypeOf($typeToRemove)->yes()) {
return $this->subtract($typeToRemove);
}

return null;
}

/**
* @param mixed[] $properties
*/
Expand Down
2 changes: 2 additions & 0 deletions src/Type/NeverType.php
Expand Up @@ -13,6 +13,7 @@
use PHPStan\ShouldNotHappenException;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonCompoundTypeTrait;

Expand All @@ -23,6 +24,7 @@ class NeverType implements CompoundType
use UndecidedBooleanTypeTrait;
use NonGenericTypeTrait;
use UndecidedComparisonCompoundTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct(private bool $isExplicit = false)
Expand Down
2 changes: 2 additions & 0 deletions src/Type/NonexistentParentClassType.php
Expand Up @@ -14,6 +14,7 @@
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
use PHPStan\Type\Traits\TruthyBooleanTypeTrait;
use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;

Expand All @@ -27,6 +28,7 @@ class NonexistentParentClassType implements Type
use TruthyBooleanTypeTrait;
use NonGenericTypeTrait;
use UndecidedComparisonTypeTrait;
use NonRemoveableTypeTrait;

public function describe(VerbosityLevel $level): string
{
Expand Down
2 changes: 2 additions & 0 deletions src/Type/NullType.php
Expand Up @@ -13,6 +13,7 @@
use PHPStan\Type\Traits\NonGenericTypeTrait;
use PHPStan\Type\Traits\NonIterableTypeTrait;
use PHPStan\Type\Traits\NonObjectTypeTrait;
use PHPStan\Type\Traits\NonRemoveableTypeTrait;

/** @api */
class NullType implements ConstantScalarType
Expand All @@ -23,6 +24,7 @@ class NullType implements ConstantScalarType
use NonObjectTypeTrait;
use FalseyBooleanTypeTrait;
use NonGenericTypeTrait;
use NonRemoveableTypeTrait;

/** @api */
public function __construct()
Expand Down

0 comments on commit 44866d8

Please sign in to comment.