Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PhpVersion param on isSmallerThanOrEqual and isGreaterThanOrEqual #3478

Merged
merged 7 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
10 changes: 6 additions & 4 deletions src/Analyser/TypeSpecifier.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand Down
2 changes: 2 additions & 0 deletions src/Analyser/TypeSpecifierFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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),
Expand Down
8 changes: 4 additions & 4 deletions src/Reflection/InitializerExprTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 7 additions & 2 deletions src/Rules/Functions/RandomIntParametersRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
)
{
}

Expand Down Expand Up @@ -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).';
Expand Down
5 changes: 3 additions & 2 deletions src/Type/CompoundType.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace PHPStan\Type;

use PHPStan\Php\PhpVersion;
use PHPStan\TrinaryLogic;

/** @api */
Expand All @@ -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;

}
8 changes: 4 additions & 4 deletions src/Type/Constant/ConstantBooleanType.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,31 +40,31 @@ 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();
}
return new NeverType();
}

public function getSmallerOrEqualType(): Type
public function getSmallerOrEqualType(PhpVersion $phpVersion): Type
{
if ($this->value) {
return new MixedType();
}
return StaticTypeFactory::falsey();
}

public function getGreaterType(): Type
public function getGreaterType(PhpVersion $phpVersion): Type
{
if ($this->value) {
return new NeverType();
}
return StaticTypeFactory::truthy();
}

public function getGreaterOrEqualType(): Type
public function getGreaterOrEqualType(PhpVersion $phpVersion): Type
{
if ($this->value) {
return StaticTypeFactory::truthy();
Expand Down
9 changes: 5 additions & 4 deletions src/Type/Constant/ConstantStringType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand All @@ -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),
Expand Down
5 changes: 3 additions & 2 deletions src/Type/Enum/EnumCaseObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand Down
34 changes: 17 additions & 17 deletions src/Type/IntegerRangeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand All @@ -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 = [];

Expand All @@ -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(),
Expand All @@ -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 = [];

Expand Down Expand Up @@ -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);
}

Expand Down
Loading
Loading