1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00
This commit is contained in:
orklah 2021-09-16 19:21:11 +02:00
parent 5a2df475ca
commit f87bd56105
2 changed files with 25 additions and 10 deletions

View File

@ -1220,7 +1220,7 @@ class ArithmeticOpAnalyzer
TIntRange $left_type_part,
TIntRange $right_type_part
): void {
//If Pow first operand is negative, the result will be negative, else it will be positive
//If Pow first operand is negative, the result could be positive or negative, else it will be positive
//If Pow second operand is negative, the result will be float, if it's 0, it will be 1/-1, else positive
if ($left_type_part->isPositive()) {
if ($right_type_part->isPositive()) {
@ -1235,7 +1235,15 @@ class ArithmeticOpAnalyzer
}
} elseif ($left_type_part->isNegative()) {
if ($right_type_part->isPositive()) {
$new_result_type = new Type\Union([new TIntRange(null, -1)]);
if ($right_type_part->min_bound === $right_type_part->max_bound) {
if ($right_type_part->max_bound % 2 === 0) {
$new_result_type = new Type\Union([new TIntRange(1, null)]);
} else {
$new_result_type = new Type\Union([new TIntRange(null, -1)]);
}
} else {
$new_result_type = Type::getInt(true);
}
} elseif ($right_type_part->isNegative()) {
$new_result_type = Type::getFloat();
} elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {
@ -1254,8 +1262,15 @@ class ArithmeticOpAnalyzer
$new_result_type = Type::getEmpty();
}
} else {
//$left_type_part may be a mix of positive, negative and 0
if ($right_type_part->isPositive()) {
$new_result_type = new Type\Union([new TInt(), new TFloat()]);
if ($right_type_part->min_bound === $right_type_part->max_bound
&& $right_type_part->max_bound % 2 === 0
) {
$new_result_type = new Type\Union([new TIntRange(1, null)]);
} else {
$new_result_type = Type::getInt(true);
}
} elseif ($right_type_part->isNegative()) {
$new_result_type = Type::getFloat();
} elseif ($right_type_part->min_bound === 0 && $right_type_part->max_bound === 0) {

View File

@ -258,10 +258,10 @@ class IntRangeTest extends TestCase
$f = 0 ** $b;
$g = 0 ** $c;
$h = 0 ** $d;
$i = -2 ** $a;
$j = -2 ** $b;
$k = -2 ** $c;
$l = -2 ** $d;
$i = (-2) ** $a;
$j = (-2) ** $b;
$k = (-2) ** $c;
$l = (-2) ** $d;
$m = 2 ** $a;
$n = 2 ** $b;
$o = 2 ** $c;
@ -284,7 +284,7 @@ class IntRangeTest extends TestCase
'$f===' => 'empty',
'$g===' => '1',
'$h===' => 'empty',
'$i===' => 'int<min, -1>',
'$i===' => 'int',
'$j===' => 'float',
'$k===' => '-1',
'$l===' => 'float|int',
@ -296,13 +296,13 @@ class IntRangeTest extends TestCase
'$r===' => 'int<1, max>',
'$s===' => 'float',
'$t===' => '-1',
'$u===' => 'int<min, -1>',
'$u===' => 'int<1, max>',
'$v===' => 'float',
'$w===' => '1',
'$x===' => '0',
'$y===' => 'empty',
'$z===' => '1',
'$aa===' => 'float|int',
'$aa===' => 'int<1, max>',
'$ab===' => 'float',
]
],