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:
parent
488c13b7c5
commit
c26f403e7e
@ -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;
|
||||
|
@ -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>',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user