Skip to content

Commit

Permalink
Merge pull request #10263 from robchett/maintain_loop_start_val_after…
Browse files Browse the repository at this point in the history
…_increment

Maintain loop start val after increment/decrement
  • Loading branch information
orklah committed Nov 4, 2023
2 parents d041b65 + fecc4eb commit 7233f38
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use Psalm\Issue\PossiblyNullOperand;
use Psalm\Issue\StringIncrement;
use Psalm\IssueBuffer;
use Psalm\Node\Expr\BinaryOp\VirtualMinus;
use Psalm\Node\Expr\BinaryOp\VirtualPlus;
use Psalm\StatementsSource;
use Psalm\Type;
use Psalm\Type\Atomic;
Expand Down Expand Up @@ -821,6 +823,28 @@ private static function analyzeOperands(
$result_type = Type::getInt();
}
}
} elseif ($parent instanceof VirtualPlus || $parent instanceof VirtualMinus) {
$sum = $parent instanceof VirtualPlus ? 1 : -1;
if ($context && $context->inside_loop && $left_type_part instanceof TLiteralInt) {
if ($parent instanceof VirtualPlus) {
$new_type = new TIntRange($left_type_part->value + $sum, null);
} else {
$new_type = new TIntRange(null, $left_type_part->value + $sum);
}
} elseif ($left_type_part instanceof TLiteralInt) {
$new_type = new TLiteralInt($left_type_part->value + $sum);
} elseif ($left_type_part instanceof TIntRange) {
$start = $left_type_part->min_bound === null ? null : $left_type_part->min_bound + $sum;
$end = $left_type_part->max_bound === null ? null : $left_type_part->max_bound + $sum;
$new_type = new TIntRange($start, $end);
} else {
$new_type = new TInt();
}

$result_type = Type::combineUnionTypes(
new Union([$new_type], ['from_calculation' => true]),
$result_type,
);
} else {
$result_type = Type::combineUnionTypes(
$always_positive ? Type::getIntRange(1, null) : Type::getInt(true),
Expand Down
34 changes: 34 additions & 0 deletions tests/BinaryOperationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,40 @@ function scope(array $a): int|float {
'$b' => 'float|int',
],
],
'incrementInLoop' => [
'code' => '<?php
for ($i = 0; $i < 10; $i++) {
if (rand(0,1)) {
break;
}
}
for ($j = 100; $j < 110; $j++) {
if (rand(0,1)) {
break;
}
}',
'assertions' => [
'$i' => 'int<0, 10>',
'$j' => 'int<100, 110>',
],
],
'decrementInLoop' => [
'code' => '<?php
for ($i = 10; $i > 0; $i--) {
if (rand(0,1)) {
break;
}
}
for ($j = 110; $j > 100; $j--) {
if (rand(0,1)) {
break;
}
}',
'assertions' => [
'$i' => 'int<0, 10>',
'$j' => 'int<100, 110>',
],
],
'coalesceFilterOutNullEvenWithTernary' => [
'code' => '<?php
Expand Down
2 changes: 1 addition & 1 deletion tests/Loop/ForTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ function test(Node $head) {
* @param list<int> $arr
*/
function cartesianProduct(array $arr) : void {
for ($i = 20; $arr[$i] === 5 && $i > 0; $i--) {}
for ($i = 20; $i > 0 && $arr[$i] === 5 ; $i--) {}
}',
],
'noCrashOnLongThing' => [
Expand Down
58 changes: 58 additions & 0 deletions tests/TypeReconciliation/RedundantConditionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,64 @@ function foo(int $x) : void {
}
}',
],
'allowIntValueCheckAfterComparisonDueToUnderflow' => [
'code' => '<?php
function foo(int $x) : void {
$x = $x - 1;
if (!is_int($x)) {
echo "Is a float.";
} else {
echo "Is an int.";
}
}
function bar(int $x) : void {
$x = $x - 1;
if (is_float($x)) {
echo "Is a float.";
} else {
echo "Is an int.";
}
}',
],
'allowIntValueCheckAfterComparisonDueToUnderflowDec' => [
'code' => '<?php
function foo(int $x) : void {
$x--;
if (!is_int($x)) {
echo "Is a float.";
} else {
echo "Is an int.";
}
}
function bar(int $x) : void {
$x--;
if (is_float($x)) {
echo "Is a float.";
} else {
echo "Is an int.";
}
}',
],
'allowIntValueCheckAfterComparisonDueToConditionalUnderflow' => [
'code' => '<?php
function foo(int $x) : void {
if (rand(0, 1)) {
$x = $x - 1;
}
if (is_float($x)) {
echo "Is a float.";
} else {
echo "Is an int.";
}
}',
],
'changeStringValue' => [
'code' => '<?php
$concat = "";
Expand Down

0 comments on commit 7233f38

Please sign in to comment.