1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Add better checks

This commit is contained in:
Brown 2020-07-26 19:09:26 -04:00
parent d9d5fdd6c9
commit 74eea18563
4 changed files with 115 additions and 16 deletions

View File

@ -309,8 +309,7 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler
$code_location,
$suppressed_issues,
$failed_reconciliation,
$is_equality,
$is_strict_equality
$is_equality
);
}
@ -464,8 +463,7 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler
?CodeLocation $code_location,
array $suppressed_issues,
int &$failed_reconciliation,
bool $is_equality,
?int $min_count
bool $is_equality
) : Union {
$old_var_type_string = $existing_var_type->getId();
@ -474,7 +472,7 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler
$positive_types = [];
foreach ($existing_var_type->getAtomicTypes() as $atomic_type) {
if ($atomic_type instanceof TLiteralInt
if ($atomic_type instanceof Type\Atomic\TLiteralInt
&& !$atomic_type->value < 1
) {
$did_remove_type = true;

View File

@ -1243,24 +1243,51 @@ class TypeCombination
return null;
}
$had_zero = isset($combination->ints['int(0)']);
if ($type instanceof TLiteralInt) {
if ($type->value === 0) {
$had_zero = true;
}
if ($combination->ints !== null && count($combination->ints) < $literal_limit) {
$combination->ints[$type_key] = $type;
} else {
$combination->ints[$type_key] = $type;
$all_nonnegative = !array_filter(
$combination->ints,
function ($int) {
return $int->value < 0;
}
);
$combination->ints = null;
$combination->value_types['int'] = new TInt();
if (!isset($combination->value_types['int'])) {
$combination->value_types['int'] = $all_nonnegative ? new TPositiveInt() : new TInt();
} elseif ($combination->value_types['int'] instanceof TPositiveInt
&& !$all_nonnegative
) {
$combination->value_types['int'] = new TInt();
}
}
} else {
if ($type instanceof TPositiveInt) {
if (($combination->ints
&& !array_filter(
$combination->ints,
function ($int) {
return $int->value < 1;
}
))
|| !isset($combination->value_types['int'])
) {
if ($combination->ints) {
$all_nonnegative = !array_filter(
$combination->ints,
function ($int) {
return $int->value < 0;
}
);
if ($all_nonnegative) {
$combination->value_types['int'] = $type;
} else {
$combination->value_types['int'] = new TInt();
}
} elseif (!isset($combination->value_types['int'])) {
$combination->value_types['int'] = $type;
}
} else {
@ -1270,6 +1297,13 @@ class TypeCombination
$combination->ints = null;
}
if ($had_zero
&& isset($combination->value_types['int'])
&& $combination->value_types['int'] instanceof TPositiveInt
) {
$combination->ints = ['int(0)' => new TLiteralInt(0)];
}
return null;
}

View File

@ -571,6 +571,65 @@ class TypeCombinationTest extends TestCase
'array{null}'
],
],
'combineZeroAndPositiveInt' => [
'int(0)|positive-int',
[
'0',
'positive-int',
],
],
'combinePositiveIntAndZero' => [
'int(0)|positive-int',
[
'positive-int',
'0',
],
],
'combinePositiveIntAndMinusOne' => [
'int',
[
'positive-int',
'-1',
],
],
'combineMinusOneAndPositiveInt' => [
'int',
[
'-1',
'positive-int',
],
],
'combineZeroMinusOneAndPositiveInt' => [
'int',
[
'0',
'-1',
'positive-int',
],
],
'combineZeroOneAndPositiveInt' => [
'int(0)|positive-int',
[
'0',
'1',
'positive-int',
],
],
'combinePositiveIntOneAndZero' => [
'int(0)|positive-int',
[
'positive-int',
'1',
'0',
],
],
'combinePositiveInts' => [
'positive-int',
[
'positive-int',
'positive-int',
],
],
];
}

View File

@ -710,7 +710,15 @@ class ValueTest extends TestCase
function makeNumStringFromFloat(float $v) {
return (string) $v;
}'
],
],
'compareNegatedValue' => [
'<?php
$i = rand(-1, 5);
if (!($i > 0)) {
echo $i;
}',
],
];
}