diff --git a/UPGRADING.md b/UPGRADING.md index a6b527bc54..14b029acc9 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -178,3 +178,5 @@ As a replacement you can implement [`PHPStan\Type\ExpressionTypeResolverExtensio * Parameter `$callableParameters` of [`MutatingScope::enterAnonymousFunction()`](https://apiref.phpstan.org/2.0.x/PHPStan.Analyser.MutatingScope.html#_enterAnonymousFunction) and [`enterArrowFunction()`](https://apiref.phpstan.org/2.0.x/PHPStan.Analyser.MutatingScope.html#_enterArrowFunction) made required * Parameter `StatementContext $context` of [`NodeScopeResolver::processStmtNodes()`](https://apiref.phpstan.org/2.0.x/PHPStan.Analyser.NodeScopeResolver.html#_processStmtNodes) made required * ClassPropertiesNode - remove `$extensions` parameter from [`getUninitializedProperties()`](https://apiref.phpstan.org/2.0.x/PHPStan.Node.ClassPropertiesNode.html#_getUninitializedProperties) +* `Type::getSmallerType()`, `Type::getSmallerOrEqualType()`, `Type::getGreaterType()`, `Type::getGreaterOrEqualType()`, `Type::isSmallerThan()`, `Type::isSmallerThanOrEqual()` now require [`PhpVersion`](https://apiref.phpstan.org/2.0.x/PHPStan.Php.PhpVersion.html) as argument. +* `CompoundType::isGreaterThan()`, `CompoundType::isGreaterThanOrEqual()` now require [`PhpVersion`](https://apiref.phpstan.org/2.0.x/PHPStan.Php.PhpVersion.html) as argument. diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 0e2ead8dde..2c9ef02f75 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -747,19 +747,19 @@ private function resolveType(string $exprString, Expr $node): Type } if ($node instanceof Expr\BinaryOp\Smaller) { - return $this->getType($node->left)->isSmallerThan($this->getType($node->right))->toBooleanType(); + return $this->getType($node->left)->isSmallerThan($this->getType($node->right), $this->phpVersion)->toBooleanType(); } if ($node instanceof Expr\BinaryOp\SmallerOrEqual) { - return $this->getType($node->left)->isSmallerThanOrEqual($this->getType($node->right))->toBooleanType(); + return $this->getType($node->left)->isSmallerThanOrEqual($this->getType($node->right), $this->phpVersion)->toBooleanType(); } if ($node instanceof Expr\BinaryOp\Greater) { - return $this->getType($node->right)->isSmallerThan($this->getType($node->left))->toBooleanType(); + return $this->getType($node->right)->isSmallerThan($this->getType($node->left), $this->phpVersion)->toBooleanType(); } if ($node instanceof Expr\BinaryOp\GreaterOrEqual) { - return $this->getType($node->right)->isSmallerThanOrEqual($this->getType($node->left))->toBooleanType(); + return $this->getType($node->right)->isSmallerThanOrEqual($this->getType($node->left), $this->phpVersion)->toBooleanType(); } if ($node instanceof Expr\BinaryOp\Equal) { diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 8c40e83826..9484fc52a7 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -22,6 +22,7 @@ use PHPStan\Node\Expr\AlwaysRememberedExpr; use PHPStan\Node\IssetExpr; use PHPStan\Node\Printer\ExprPrinter; +use PHPStan\Php\PhpVersion; use PHPStan\Reflection\Assertions; use PHPStan\Reflection\ParametersAcceptor; use PHPStan\Reflection\ParametersAcceptorSelector; @@ -100,6 +101,7 @@ final class TypeSpecifier public function __construct( private ExprPrinter $exprPrinter, private ReflectionProvider $reflectionProvider, + private PhpVersion $phpVersion, private array $functionTypeSpecifyingExtensions, private array $methodTypeSpecifyingExtensions, private array $staticMethodTypeSpecifyingExtensions, @@ -406,7 +408,7 @@ public function specifyTypesInCondition( $result = $result->unionWith( $this->create( $expr->left, - $orEqual ? $rightType->getSmallerOrEqualType() : $rightType->getSmallerType(), + $orEqual ? $rightType->getSmallerOrEqualType($this->phpVersion) : $rightType->getSmallerType($this->phpVersion), TypeSpecifierContext::createTruthy(), $scope, )->setRootExpr($expr), @@ -416,7 +418,7 @@ public function specifyTypesInCondition( $result = $result->unionWith( $this->create( $expr->right, - $orEqual ? $leftType->getGreaterOrEqualType() : $leftType->getGreaterType(), + $orEqual ? $leftType->getGreaterOrEqualType($this->phpVersion) : $leftType->getGreaterType($this->phpVersion), TypeSpecifierContext::createTruthy(), $scope, )->setRootExpr($expr), @@ -427,7 +429,7 @@ public function specifyTypesInCondition( $result = $result->unionWith( $this->create( $expr->left, - $orEqual ? $rightType->getGreaterType() : $rightType->getGreaterOrEqualType(), + $orEqual ? $rightType->getGreaterType($this->phpVersion) : $rightType->getGreaterOrEqualType($this->phpVersion), TypeSpecifierContext::createTruthy(), $scope, )->setRootExpr($expr), @@ -437,7 +439,7 @@ public function specifyTypesInCondition( $result = $result->unionWith( $this->create( $expr->right, - $orEqual ? $leftType->getSmallerType() : $leftType->getSmallerOrEqualType(), + $orEqual ? $leftType->getSmallerType($this->phpVersion) : $leftType->getSmallerOrEqualType($this->phpVersion), TypeSpecifierContext::createTruthy(), $scope, )->setRootExpr($expr), diff --git a/src/Analyser/TypeSpecifierFactory.php b/src/Analyser/TypeSpecifierFactory.php index 60219c3b6d..83315b6e0c 100644 --- a/src/Analyser/TypeSpecifierFactory.php +++ b/src/Analyser/TypeSpecifierFactory.php @@ -5,6 +5,7 @@ use PHPStan\Broker\BrokerFactory; use PHPStan\DependencyInjection\Container; use PHPStan\Node\Printer\ExprPrinter; +use PHPStan\Php\PhpVersion; use PHPStan\Reflection\ReflectionProvider; use function array_merge; @@ -24,6 +25,7 @@ public function create(): TypeSpecifier $typeSpecifier = new TypeSpecifier( $this->container->getByType(ExprPrinter::class), $this->container->getByType(ReflectionProvider::class), + $this->container->getByType(PhpVersion::class), $this->container->getServicesByTag(self::FUNCTION_TYPE_SPECIFYING_EXTENSION_TAG), $this->container->getServicesByTag(self::METHOD_TYPE_SPECIFYING_EXTENSION_TAG), $this->container->getServicesByTag(self::STATIC_METHOD_TYPE_SPECIFYING_EXTENSION_TAG), diff --git a/src/Reflection/InitializerExprTypeResolver.php b/src/Reflection/InitializerExprTypeResolver.php index b4beb587bf..fdb3344d69 100644 --- a/src/Reflection/InitializerExprTypeResolver.php +++ b/src/Reflection/InitializerExprTypeResolver.php @@ -316,19 +316,19 @@ public function getType(Expr $expr, InitializerExprContext $context): Type } if ($expr instanceof Expr\BinaryOp\Smaller) { - return $this->getType($expr->left, $context)->isSmallerThan($this->getType($expr->right, $context))->toBooleanType(); + return $this->getType($expr->left, $context)->isSmallerThan($this->getType($expr->right, $context), $this->phpVersion)->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\SmallerOrEqual) { - return $this->getType($expr->left, $context)->isSmallerThanOrEqual($this->getType($expr->right, $context))->toBooleanType(); + return $this->getType($expr->left, $context)->isSmallerThanOrEqual($this->getType($expr->right, $context), $this->phpVersion)->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\Greater) { - return $this->getType($expr->right, $context)->isSmallerThan($this->getType($expr->left, $context))->toBooleanType(); + return $this->getType($expr->right, $context)->isSmallerThan($this->getType($expr->left, $context), $this->phpVersion)->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\GreaterOrEqual) { - return $this->getType($expr->right, $context)->isSmallerThanOrEqual($this->getType($expr->left, $context))->toBooleanType(); + return $this->getType($expr->right, $context)->isSmallerThanOrEqual($this->getType($expr->left, $context), $this->phpVersion)->toBooleanType(); } if ($expr instanceof Expr\BinaryOp\LogicalXor) { diff --git a/src/Rules/Functions/RandomIntParametersRule.php b/src/Rules/Functions/RandomIntParametersRule.php index ecca6e7d09..e35c21a3ed 100644 --- a/src/Rules/Functions/RandomIntParametersRule.php +++ b/src/Rules/Functions/RandomIntParametersRule.php @@ -5,6 +5,7 @@ use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; +use PHPStan\Php\PhpVersion; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -21,7 +22,11 @@ final class RandomIntParametersRule implements Rule { - public function __construct(private ReflectionProvider $reflectionProvider, private bool $reportMaybes) + public function __construct( + private ReflectionProvider $reflectionProvider, + private PhpVersion $phpVersion, + private bool $reportMaybes, + ) { } @@ -55,7 +60,7 @@ public function processNode(Node $node, Scope $scope): array return []; } - $isSmaller = $maxType->isSmallerThan($minType); + $isSmaller = $maxType->isSmallerThan($minType, $this->phpVersion); if ($isSmaller->yes() || $isSmaller->maybe() && $this->reportMaybes) { $message = 'Parameter #1 $min (%s) of function random_int expects lower number than parameter #2 $max (%s).'; diff --git a/src/Type/CompoundType.php b/src/Type/CompoundType.php index ea9b2f4660..775a4eb50f 100644 --- a/src/Type/CompoundType.php +++ b/src/Type/CompoundType.php @@ -2,6 +2,7 @@ namespace PHPStan\Type; +use PHPStan\Php\PhpVersion; use PHPStan\TrinaryLogic; /** @api */ @@ -14,8 +15,8 @@ public function isAcceptedBy(Type $acceptingType, bool $strictTypes): TrinaryLog public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes): AcceptsResult; - public function isGreaterThan(Type $otherType): TrinaryLogic; + public function isGreaterThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic; - public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic; + public function isGreaterThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic; } diff --git a/src/Type/Constant/ConstantBooleanType.php b/src/Type/Constant/ConstantBooleanType.php index db5328d0d2..cbebe5b48b 100644 --- a/src/Type/Constant/ConstantBooleanType.php +++ b/src/Type/Constant/ConstantBooleanType.php @@ -40,7 +40,7 @@ public function describe(VerbosityLevel $level): string return $this->value ? 'true' : 'false'; } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { if ($this->value) { return StaticTypeFactory::falsey(); @@ -48,7 +48,7 @@ public function getSmallerType(): Type return new NeverType(); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { if ($this->value) { return new MixedType(); @@ -56,7 +56,7 @@ public function getSmallerOrEqualType(): Type return StaticTypeFactory::falsey(); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { if ($this->value) { return new NeverType(); @@ -64,7 +64,7 @@ public function getGreaterType(): Type return StaticTypeFactory::truthy(); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { if ($this->value) { return StaticTypeFactory::truthy(); diff --git a/src/Type/Constant/ConstantStringType.php b/src/Type/Constant/ConstantStringType.php index 39b259ee37..09ddd2741e 100644 --- a/src/Type/Constant/ConstantStringType.php +++ b/src/Type/Constant/ConstantStringType.php @@ -6,6 +6,7 @@ use Nette\Utils\Strings; use PhpParser\Node\Name; use PHPStan\Analyser\OutOfClassScope; +use PHPStan\Php\PhpVersion; use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode; use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode; use PHPStan\PhpDocParser\Ast\Type\TypeNode; @@ -461,7 +462,7 @@ public function generalize(GeneralizePrecision $precision): Type return new StringType(); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { $subtractedTypes = [ new ConstantBooleanType(true), @@ -480,7 +481,7 @@ public function getSmallerType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { $subtractedTypes = [ IntegerRangeType::createAllGreaterThan((float) $this->value), @@ -493,7 +494,7 @@ public function getSmallerOrEqualType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { $subtractedTypes = [ new ConstantBooleanType(false), @@ -507,7 +508,7 @@ public function getGreaterType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { $subtractedTypes = [ IntegerRangeType::createAllSmallerThan((float) $this->value), diff --git a/src/Type/Enum/EnumCaseObjectType.php b/src/Type/Enum/EnumCaseObjectType.php index 42d8f4afc2..e0bc8c3340 100644 --- a/src/Type/Enum/EnumCaseObjectType.php +++ b/src/Type/Enum/EnumCaseObjectType.php @@ -2,6 +2,7 @@ namespace PHPStan\Type\Enum; +use PHPStan\Php\PhpVersion; use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode; use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode; use PHPStan\PhpDocParser\Ast\Type\TypeNode; @@ -179,12 +180,12 @@ public function generalize(GeneralizePrecision $precision): Type return new parent($this->getClassName(), null, $this->getClassReflection()); } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { return TrinaryLogic::createNo(); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { return TrinaryLogic::createNo(); } diff --git a/src/Type/IntegerRangeType.php b/src/Type/IntegerRangeType.php index 534be0ebbb..d5680a59ac 100644 --- a/src/Type/IntegerRangeType.php +++ b/src/Type/IntegerRangeType.php @@ -308,75 +308,75 @@ public function generalize(GeneralizePrecision $precision): Type return new IntegerType(); } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createYes(); } else { - $minIsSmaller = (new ConstantIntegerType($this->min))->isSmallerThan($otherType); + $minIsSmaller = (new ConstantIntegerType($this->min))->isSmallerThan($otherType, $phpVersion); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createNo(); } else { - $maxIsSmaller = (new ConstantIntegerType($this->max))->isSmallerThan($otherType); + $maxIsSmaller = (new ConstantIntegerType($this->max))->isSmallerThan($otherType, $phpVersion); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createYes(); } else { - $minIsSmaller = (new ConstantIntegerType($this->min))->isSmallerThanOrEqual($otherType); + $minIsSmaller = (new ConstantIntegerType($this->min))->isSmallerThanOrEqual($otherType, $phpVersion); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createNo(); } else { - $maxIsSmaller = (new ConstantIntegerType($this->max))->isSmallerThanOrEqual($otherType); + $maxIsSmaller = (new ConstantIntegerType($this->max))->isSmallerThanOrEqual($otherType, $phpVersion); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } - public function isGreaterThan(Type $otherType): TrinaryLogic + public function isGreaterThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createNo(); } else { - $minIsSmaller = $otherType->isSmallerThan((new ConstantIntegerType($this->min))); + $minIsSmaller = $otherType->isSmallerThan((new ConstantIntegerType($this->min)), $phpVersion); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createYes(); } else { - $maxIsSmaller = $otherType->isSmallerThan((new ConstantIntegerType($this->max))); + $maxIsSmaller = $otherType->isSmallerThan((new ConstantIntegerType($this->max)), $phpVersion); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } - public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic + public function isGreaterThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($this->min === null) { $minIsSmaller = TrinaryLogic::createNo(); } else { - $minIsSmaller = $otherType->isSmallerThanOrEqual((new ConstantIntegerType($this->min))); + $minIsSmaller = $otherType->isSmallerThanOrEqual((new ConstantIntegerType($this->min)), $phpVersion); } if ($this->max === null) { $maxIsSmaller = TrinaryLogic::createYes(); } else { - $maxIsSmaller = $otherType->isSmallerThanOrEqual((new ConstantIntegerType($this->max))); + $maxIsSmaller = $otherType->isSmallerThanOrEqual((new ConstantIntegerType($this->max)), $phpVersion); } return TrinaryLogic::extremeIdentity($minIsSmaller, $maxIsSmaller); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { $subtractedTypes = [ new ConstantBooleanType(true), @@ -389,7 +389,7 @@ public function getSmallerType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { $subtractedTypes = []; @@ -400,7 +400,7 @@ public function getSmallerOrEqualType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { $subtractedTypes = [ new NullType(), @@ -418,7 +418,7 @@ public function getGreaterType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { $subtractedTypes = []; @@ -692,7 +692,7 @@ public function toPhpDocNode(): TypeNode public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType { - if ($this->isSmallerThan($type)->yes() || $this->isGreaterThan($type)->yes()) { + if ($this->isSmallerThan($type, $phpVersion)->yes() || $this->isGreaterThan($type, $phpVersion)->yes()) { return new ConstantBooleanType(false); } diff --git a/src/Type/IntersectionType.php b/src/Type/IntersectionType.php index 8bf38bddda..13704c9a5d 100644 --- a/src/Type/IntersectionType.php +++ b/src/Type/IntersectionType.php @@ -802,14 +802,14 @@ public function isCloneable(): TrinaryLogic return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isCloneable()); } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType)); + return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType, $phpVersion)); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType)); + return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType, $phpVersion)); } public function isNull(): TrinaryLogic @@ -876,34 +876,34 @@ public function isInteger(): TrinaryLogic return $this->intersectResults(static fn (Type $type): TrinaryLogic => $type->isInteger()); } - public function isGreaterThan(Type $otherType): TrinaryLogic + public function isGreaterThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->intersectResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThan($type)); + return $this->intersectResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThan($type, $phpVersion)); } - public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic + public function isGreaterThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->intersectResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThanOrEqual($type)); + return $this->intersectResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThanOrEqual($type, $phpVersion)); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { - return $this->intersectTypes(static fn (Type $type): Type => $type->getSmallerType()); + return $this->intersectTypes(static fn (Type $type): Type => $type->getSmallerType($phpVersion)); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { - return $this->intersectTypes(static fn (Type $type): Type => $type->getSmallerOrEqualType()); + return $this->intersectTypes(static fn (Type $type): Type => $type->getSmallerOrEqualType($phpVersion)); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { - return $this->intersectTypes(static fn (Type $type): Type => $type->getGreaterType()); + return $this->intersectTypes(static fn (Type $type): Type => $type->getGreaterType($phpVersion)); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { - return $this->intersectTypes(static fn (Type $type): Type => $type->getGreaterOrEqualType()); + return $this->intersectTypes(static fn (Type $type): Type => $type->getGreaterOrEqualType($phpVersion)); } public function toBoolean(): BooleanType diff --git a/src/Type/NullType.php b/src/Type/NullType.php index a59f86e868..01870ed2da 100644 --- a/src/Type/NullType.php +++ b/src/Type/NullType.php @@ -108,27 +108,27 @@ public function equals(Type $type): bool return $type instanceof self; } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($otherType instanceof ConstantScalarType) { return TrinaryLogic::createFromBoolean(null < $otherType->getValue()); } if ($otherType instanceof CompoundType) { - return $otherType->isGreaterThan($this); + return $otherType->isGreaterThan($this, $phpVersion); } return TrinaryLogic::createMaybe(); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($otherType instanceof ConstantScalarType) { return TrinaryLogic::createFromBoolean(null <= $otherType->getValue()); } if ($otherType instanceof CompoundType) { - return $otherType->isGreaterThanOrEqual($this); + return $otherType->isGreaterThanOrEqual($this, $phpVersion); } return TrinaryLogic::createMaybe(); @@ -338,12 +338,12 @@ public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType return new BooleanType(); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { return new NeverType(); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { // All falsey types except '0' return new UnionType([ @@ -356,7 +356,7 @@ public function getSmallerOrEqualType(): Type ]); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { // All truthy types, but also '0' return new MixedType(false, new UnionType([ @@ -369,7 +369,7 @@ public function getGreaterType(): Type ])); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { return new MixedType(); } diff --git a/src/Type/Traits/ConstantNumericComparisonTypeTrait.php b/src/Type/Traits/ConstantNumericComparisonTypeTrait.php index 2b3b4a45c5..c6efe96950 100644 --- a/src/Type/Traits/ConstantNumericComparisonTypeTrait.php +++ b/src/Type/Traits/ConstantNumericComparisonTypeTrait.php @@ -2,6 +2,7 @@ namespace PHPStan\Type\Traits; +use PHPStan\Php\PhpVersion; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\Constant\ConstantFloatType; use PHPStan\Type\IntegerRangeType; @@ -13,7 +14,7 @@ trait ConstantNumericComparisonTypeTrait { - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { $subtractedTypes = [ new ConstantBooleanType(true), @@ -29,7 +30,7 @@ public function getSmallerType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { $subtractedTypes = [ IntegerRangeType::createAllGreaterThan($this->value), @@ -43,7 +44,7 @@ public function getSmallerOrEqualType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { $subtractedTypes = [ new NullType(), @@ -59,7 +60,7 @@ public function getGreaterType(): Type return TypeCombinator::remove(new MixedType(), TypeCombinator::union(...$subtractedTypes)); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { $subtractedTypes = [ IntegerRangeType::createAllSmallerThan($this->value), diff --git a/src/Type/Traits/ConstantScalarTypeTrait.php b/src/Type/Traits/ConstantScalarTypeTrait.php index 527d10b68a..7452cd3c83 100644 --- a/src/Type/Traits/ConstantScalarTypeTrait.php +++ b/src/Type/Traits/ConstantScalarTypeTrait.php @@ -78,27 +78,27 @@ public function equals(Type $type): bool return $type instanceof self && $this->value === $type->value; } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($otherType instanceof ConstantScalarType) { return TrinaryLogic::createFromBoolean($this->value < $otherType->getValue()); } if ($otherType instanceof CompoundType) { - return $otherType->isGreaterThan($this); + return $otherType->isGreaterThan($this, $phpVersion); } return TrinaryLogic::createMaybe(); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { if ($otherType instanceof ConstantScalarType) { return TrinaryLogic::createFromBoolean($this->value <= $otherType->getValue()); } if ($otherType instanceof CompoundType) { - return $otherType->isGreaterThanOrEqual($this); + return $otherType->isGreaterThanOrEqual($this, $phpVersion); } return TrinaryLogic::createMaybe(); diff --git a/src/Type/Traits/LateResolvableTypeTrait.php b/src/Type/Traits/LateResolvableTypeTrait.php index bff88f730e..ff3d015f36 100644 --- a/src/Type/Traits/LateResolvableTypeTrait.php +++ b/src/Type/Traits/LateResolvableTypeTrait.php @@ -367,14 +367,14 @@ public function toArrayKey(): Type return $this->resolve()->toArrayKey(); } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->resolve()->isSmallerThan($otherType); + return $this->resolve()->isSmallerThan($otherType, $phpVersion); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->resolve()->isSmallerThanOrEqual($otherType); + return $this->resolve()->isSmallerThanOrEqual($otherType, $phpVersion); } public function isNull(): TrinaryLogic @@ -482,24 +482,24 @@ public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType return new BooleanType(); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { - return $this->resolve()->getSmallerType(); + return $this->resolve()->getSmallerType($phpVersion); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { - return $this->resolve()->getSmallerOrEqualType(); + return $this->resolve()->getSmallerOrEqualType($phpVersion); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { - return $this->resolve()->getGreaterType(); + return $this->resolve()->getGreaterType($phpVersion); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { - return $this->resolve()->getGreaterOrEqualType(); + return $this->resolve()->getGreaterOrEqualType($phpVersion); } public function inferTemplateTypes(Type $receivedType): TemplateTypeMap @@ -539,26 +539,26 @@ public function isAcceptedWithReasonBy(Type $acceptingType, bool $strictTypes): return $acceptingType->acceptsWithReason($result, $strictTypes); } - public function isGreaterThan(Type $otherType): TrinaryLogic + public function isGreaterThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { $result = $this->resolve(); if ($result instanceof CompoundType) { - return $result->isGreaterThan($otherType); + return $result->isGreaterThan($otherType, $phpVersion); } - return $otherType->isSmallerThan($result); + return $otherType->isSmallerThan($result, $phpVersion); } - public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic + public function isGreaterThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { $result = $this->resolve(); if ($result instanceof CompoundType) { - return $result->isGreaterThanOrEqual($otherType); + return $result->isGreaterThanOrEqual($otherType, $phpVersion); } - return $otherType->isSmallerThanOrEqual($result); + return $otherType->isSmallerThanOrEqual($result, $phpVersion); } public function exponentiate(Type $exponent): Type diff --git a/src/Type/Traits/UndecidedComparisonCompoundTypeTrait.php b/src/Type/Traits/UndecidedComparisonCompoundTypeTrait.php index e40b72fad4..6adf571d54 100644 --- a/src/Type/Traits/UndecidedComparisonCompoundTypeTrait.php +++ b/src/Type/Traits/UndecidedComparisonCompoundTypeTrait.php @@ -2,6 +2,7 @@ namespace PHPStan\Type\Traits; +use PHPStan\Php\PhpVersion; use PHPStan\TrinaryLogic; use PHPStan\Type\Type; @@ -10,12 +11,12 @@ trait UndecidedComparisonCompoundTypeTrait use UndecidedComparisonTypeTrait; - public function isGreaterThan(Type $otherType): TrinaryLogic + public function isGreaterThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { return TrinaryLogic::createMaybe(); } - public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic + public function isGreaterThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { return TrinaryLogic::createMaybe(); } diff --git a/src/Type/Traits/UndecidedComparisonTypeTrait.php b/src/Type/Traits/UndecidedComparisonTypeTrait.php index e5c6d2c891..6761274cf1 100644 --- a/src/Type/Traits/UndecidedComparisonTypeTrait.php +++ b/src/Type/Traits/UndecidedComparisonTypeTrait.php @@ -2,6 +2,7 @@ namespace PHPStan\Type\Traits; +use PHPStan\Php\PhpVersion; use PHPStan\TrinaryLogic; use PHPStan\Type\MixedType; use PHPStan\Type\Type; @@ -9,32 +10,32 @@ trait UndecidedComparisonTypeTrait { - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { return TrinaryLogic::createMaybe(); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { return TrinaryLogic::createMaybe(); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { return new MixedType(); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { return new MixedType(); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { return new MixedType(); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { return new MixedType(); } diff --git a/src/Type/Type.php b/src/Type/Type.php index 727e2f8a31..47446d0dad 100644 --- a/src/Type/Type.php +++ b/src/Type/Type.php @@ -215,9 +215,9 @@ public function toArray(): Type; public function toArrayKey(): Type; - public function isSmallerThan(Type $otherType): TrinaryLogic; + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic; - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic; + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic; /** * Is Type of a known constant value? Includes literal strings, integers, floats, true, false, null, and array shapes. @@ -269,13 +269,13 @@ public function isScalar(): TrinaryLogic; public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType; - public function getSmallerType(): Type; + public function getSmallerType(PhpVersion $phpVersion): Type; - public function getSmallerOrEqualType(): Type; + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type; - public function getGreaterType(): Type; + public function getGreaterType(PhpVersion $phpVersion): Type; - public function getGreaterOrEqualType(): Type; + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type; /** * Returns actual template type for a given object. diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index af4ede1b40..839bad3817 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -783,14 +783,14 @@ public function isCloneable(): TrinaryLogic return $this->unionResults(static fn (Type $type): TrinaryLogic => $type->isCloneable()); } - public function isSmallerThan(Type $otherType): TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType)); + return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThan($otherType, $phpVersion)); } - public function isSmallerThanOrEqual(Type $otherType): TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType)); + return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isSmallerThanOrEqual($otherType, $phpVersion)); } public function isNull(): TrinaryLogic @@ -843,34 +843,34 @@ public function isInteger(): TrinaryLogic return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $type->isInteger()); } - public function getSmallerType(): Type + public function getSmallerType(PhpVersion $phpVersion): Type { - return $this->unionTypes(static fn (Type $type): Type => $type->getSmallerType()); + return $this->unionTypes(static fn (Type $type): Type => $type->getSmallerType($phpVersion)); } - public function getSmallerOrEqualType(): Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): Type { - return $this->unionTypes(static fn (Type $type): Type => $type->getSmallerOrEqualType()); + return $this->unionTypes(static fn (Type $type): Type => $type->getSmallerOrEqualType($phpVersion)); } - public function getGreaterType(): Type + public function getGreaterType(PhpVersion $phpVersion): Type { - return $this->unionTypes(static fn (Type $type): Type => $type->getGreaterType()); + return $this->unionTypes(static fn (Type $type): Type => $type->getGreaterType($phpVersion)); } - public function getGreaterOrEqualType(): Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): Type { - return $this->unionTypes(static fn (Type $type): Type => $type->getGreaterOrEqualType()); + return $this->unionTypes(static fn (Type $type): Type => $type->getGreaterOrEqualType($phpVersion)); } - public function isGreaterThan(Type $otherType): TrinaryLogic + public function isGreaterThan(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThan($type)); + return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThan($type, $phpVersion)); } - public function isGreaterThanOrEqual(Type $otherType): TrinaryLogic + public function isGreaterThanOrEqual(Type $otherType, PhpVersion $phpVersion): TrinaryLogic { - return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThanOrEqual($type)); + return $this->notBenevolentUnionResults(static fn (Type $type): TrinaryLogic => $otherType->isSmallerThanOrEqual($type, $phpVersion)); } public function toBoolean(): BooleanType diff --git a/tests/PHPStan/Rules/Api/ApiClassImplementsRuleTest.php b/tests/PHPStan/Rules/Api/ApiClassImplementsRuleTest.php index a6a68a9b5e..f2b13d25c2 100644 --- a/tests/PHPStan/Rules/Api/ApiClassImplementsRuleTest.php +++ b/tests/PHPStan/Rules/Api/ApiClassImplementsRuleTest.php @@ -32,32 +32,32 @@ public function testRuleOutOfPhpStan(): void $this->analyse([__DIR__ . '/data/class-implements-out-of-phpstan.php'], [ [ 'Implementing PHPStan\DependencyInjection\Type\DynamicThrowTypeExtensionProvider is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', - 19, + 20, $tip, ], [ 'Implementing PHPStan\Type\Type is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', - 53, + 54, $tip, ], [ 'Implementing PHPStan\Reflection\ReflectionProvider is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', - 338, + 339, $tip, ], [ 'Implementing PHPStan\Analyser\Scope is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', - 343, + 344, $tip, ], [ 'Implementing PHPStan\Reflection\FunctionReflection is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', - 348, + 349, $tip, ], [ 'Implementing PHPStan\Reflection\ExtendedMethodReflection is not covered by backward compatibility promise. The interface might change in a minor PHPStan version.', - 352, + 353, $tip, ], ]); diff --git a/tests/PHPStan/Rules/Api/data/class-implements-out-of-phpstan.php b/tests/PHPStan/Rules/Api/data/class-implements-out-of-phpstan.php index c7b42d7e6e..c5211fd650 100644 --- a/tests/PHPStan/Rules/Api/data/class-implements-out-of-phpstan.php +++ b/tests/PHPStan/Rules/Api/data/class-implements-out-of-phpstan.php @@ -5,6 +5,7 @@ use PhpParser\Node\Expr\FuncCall; use PHPStan\Analyser\Scope; use PHPStan\DependencyInjection\Type\DynamicThrowTypeExtensionProvider; +use PHPStan\Php\PhpVersion; use PHPStan\Reflection\ClassMemberAccessAnswerer; use PHPStan\Reflection\ExtendedMethodReflection; use PHPStan\Reflection\FunctionReflection; @@ -247,12 +248,12 @@ public function toArrayKey(): \PHPStan\Type\Type // TODO: Implement toArrayKey() method. } - public function isSmallerThan(Type $otherType): \PHPStan\TrinaryLogic + public function isSmallerThan(Type $otherType, PhpVersion $phpVersion): \PHPStan\TrinaryLogic { // TODO: Implement isSmallerThan() method. } - public function isSmallerThanOrEqual(Type $otherType): \PHPStan\TrinaryLogic + public function isSmallerThanOrEqual(Type $otherType, PhpVersion $phpVersion): \PHPStan\TrinaryLogic { // TODO: Implement isSmallerThanOrEqual() method. } @@ -277,22 +278,22 @@ public function isLiteralString(): \PHPStan\TrinaryLogic // TODO: Implement isLiteralString() method. } - public function getSmallerType(): \PHPStan\Type\Type + public function getSmallerType(PhpVersion $phpVersion): \PHPStan\Type\Type { // TODO: Implement getSmallerType() method. } - public function getSmallerOrEqualType(): \PHPStan\Type\Type + public function getSmallerOrEqualType(PhpVersion $phpVersion): \PHPStan\Type\Type { // TODO: Implement getSmallerOrEqualType() method. } - public function getGreaterType(): \PHPStan\Type\Type + public function getGreaterType(PhpVersion $phpVersion): \PHPStan\Type\Type { // TODO: Implement getGreaterType() method. } - public function getGreaterOrEqualType(): \PHPStan\Type\Type + public function getGreaterOrEqualType(PhpVersion $phpVersion): \PHPStan\Type\Type { // TODO: Implement getGreaterOrEqualType() method. } diff --git a/tests/PHPStan/Rules/Functions/RandomIntParametersRuleTest.php b/tests/PHPStan/Rules/Functions/RandomIntParametersRuleTest.php index 4b9ab4e23c..40c0526e25 100644 --- a/tests/PHPStan/Rules/Functions/RandomIntParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/RandomIntParametersRuleTest.php @@ -2,6 +2,7 @@ namespace PHPStan\Rules\Functions; +use PHPStan\Php\PhpVersion; use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use const PHP_INT_SIZE; @@ -14,7 +15,7 @@ class RandomIntParametersRuleTest extends RuleTestCase protected function getRule(): Rule { - return new RandomIntParametersRule($this->createReflectionProvider(), true); + return new RandomIntParametersRule($this->createReflectionProvider(), new PhpVersion(80000), true); } public function testFile(): void