From f3636dbb9a30b32a611b8dd2e7955f0cb9178386 Mon Sep 17 00:00:00 2001 From: Martin Herndl Date: Thu, 3 Mar 2022 14:41:52 +0100 Subject: [PATCH] Fix non-integer range comparisons --- .../AssertTypeSpecifyingExtension.php | 36 ++++++++++++++++--- .../ImpossibleCheckTypeMethodCallRuleTest.php | 10 ++++++ tests/Type/WebMozartAssert/data/bug-118.php | 14 ++++++++ tests/Type/WebMozartAssert/data/bug-119.php | 17 +++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 tests/Type/WebMozartAssert/data/bug-118.php create mode 100644 tests/Type/WebMozartAssert/data/bug-119.php diff --git a/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php b/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php index 1090363..124c541 100644 --- a/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php +++ b/src/Type/WebMozartAssert/AssertTypeSpecifyingExtension.php @@ -40,6 +40,7 @@ use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantArrayTypeBuilder; use PHPStan\Type\Constant\ConstantStringType; +use PHPStan\Type\IntegerType; use PHPStan\Type\IterableType; use PHPStan\Type\MixedType; use PHPStan\Type\ObjectType; @@ -485,31 +486,56 @@ private static function getExpressionResolvers(): array $value2->value ); }, - 'greaterThan' => static function (Scope $scope, Arg $value, Arg $limit): Expr { + 'greaterThan' => static function (Scope $scope, Arg $value, Arg $limit): ?Expr { + $valueType = $scope->getType($value->value); + if ((new IntegerType())->isSuperTypeOf($valueType)->no()) { + return null; + } + return new Greater( $value->value, $limit->value ); }, - 'greaterThanEq' => static function (Scope $scope, Arg $value, Arg $limit): Expr { + 'greaterThanEq' => static function (Scope $scope, Arg $value, Arg $limit): ?Expr { + $valueType = $scope->getType($value->value); + if ((new IntegerType())->isSuperTypeOf($valueType)->no()) { + return null; + } + return new GreaterOrEqual( $value->value, $limit->value ); }, - 'lessThan' => static function (Scope $scope, Arg $value, Arg $limit): Expr { + 'lessThan' => static function (Scope $scope, Arg $value, Arg $limit): ?Expr { + $valueType = $scope->getType($value->value); + if ((new IntegerType())->isSuperTypeOf($valueType)->no()) { + return null; + } + return new Smaller( $value->value, $limit->value ); }, - 'lessThanEq' => static function (Scope $scope, Arg $value, Arg $limit): Expr { + 'lessThanEq' => static function (Scope $scope, Arg $value, Arg $limit): ?Expr { + $valueType = $scope->getType($value->value); + if ((new IntegerType())->isSuperTypeOf($valueType)->no()) { + return null; + } + return new SmallerOrEqual( $value->value, $limit->value ); }, - 'range' => static function (Scope $scope, Arg $value, Arg $min, Arg $max): Expr { + 'range' => static function (Scope $scope, Arg $value, Arg $min, Arg $max): ?Expr { + $valueType = $scope->getType($value->value); + if ((new IntegerType())->isSuperTypeOf($valueType)->no()) { + return null; + } + return new BooleanAnd( new GreaterOrEqual( $value->value, diff --git a/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php b/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php index bca1e3c..ed57700 100644 --- a/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php +++ b/tests/Type/WebMozartAssert/ImpossibleCheckTypeMethodCallRuleTest.php @@ -80,6 +80,16 @@ public function testBug85(): void $this->analyse([__DIR__ . '/data/bug-85.php'], []); } + public function testBug118(): void + { + $this->analyse([__DIR__ . '/data/bug-118.php'], []); + } + + public function testBug119(): void + { + $this->analyse([__DIR__ . '/data/bug-119.php'], []); + } + public static function getAdditionalConfigFiles(): array { return [ diff --git a/tests/Type/WebMozartAssert/data/bug-118.php b/tests/Type/WebMozartAssert/data/bug-118.php new file mode 100644 index 0000000..25486f5 --- /dev/null +++ b/tests/Type/WebMozartAssert/data/bug-118.php @@ -0,0 +1,14 @@ +