1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

fix an old bug with inverting positive int + allow inverting TIntRange

This commit is contained in:
orklah 2021-09-09 22:42:23 +02:00
parent 488c13b7c5
commit c26f403e7e
2 changed files with 50 additions and 0 deletions

View File

@ -12,6 +12,7 @@ use Psalm\Internal\DataFlow\DataFlowNode;
use Psalm\Type;
use Psalm\Type\Atomic\TFloat;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TString;
class UnaryPlusMinusAnalyzer
@ -47,6 +48,37 @@ class UnaryPlusMinusAnalyzer
$type_part->value = -$type_part->value;
}
if ($type_part instanceof Type\Atomic\TIntRange
&& $stmt instanceof PhpParser\Node\Expr\UnaryMinus
) {
//we'll have to inverse min and max bound and negate any literal
$old_min_bound = $type_part->min_bound;
$old_max_bound = $type_part->max_bound;
if ($old_min_bound === null) {
//min bound is null, max bound will be null
$type_part->max_bound = null;
} elseif ($old_min_bound === 0) {
$type_part->max_bound = 0;
} else {
$type_part->max_bound = -$old_min_bound;
}
if ($old_max_bound === null) {
//max bound is null, min bound will be null
$type_part->min_bound = null;
} elseif ($old_max_bound === 0) {
$type_part->min_bound = 0;
} else {
$type_part->min_bound = -$old_max_bound;
}
}
if ($type_part instanceof Type\Atomic\TPositiveInt
&& $stmt instanceof PhpParser\Node\Expr\UnaryMinus
) {
$type_part = new TIntRange(null, 0);
}
$acceptable_types[] = $type_part;
} elseif ($type_part instanceof TString) {
$acceptable_types[] = new TInt;

View File

@ -344,6 +344,24 @@ class IntRangeTest extends TestCase
'$h===' => 'int<0, max>',
],
],
'UnaryMinus' => [
'<?php
function getInt(): int{return 0;}
$a = $c = $e = getInt();
assert($a > 5);
$b = -$a;
assert($c > 0);
$d = -$c;
assert($e > 5);
assert($e < 10);
$f = -$e;
',
'assertions' => [
'$b===' => 'int<min, -6>',
'$d===' => 'int<min, 0>',
'$f===' => 'int<-9, -6>',
],
],
];
}