Skip to content

Commit

Permalink
Add PhpVersion parameter to various Type methods
Browse files Browse the repository at this point in the history
Co-authored-by: Ondřej Mirtes <[email protected]>
  • Loading branch information
VincentLanglet and ondrejmirtes authored Sep 25, 2024
1 parent c3cad7d commit ac91552
Show file tree
Hide file tree
Showing 23 changed files with 155 additions and 136 deletions.
2 changes: 2 additions & 0 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
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

0 comments on commit ac91552

Please sign in to comment.