1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 12:55:26 +01:00

Merge pull request #6473 from orklah/double-assert2

assert both sides of an equality
This commit is contained in:
orklah 2021-10-04 13:30:38 +02:00 committed by GitHub
commit ac6a75ea7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 0 deletions

View File

@ -90,6 +90,12 @@ class Algebra
{ {
$clause_count = count($clauses); $clause_count = count($clauses);
//65536 seems to be a significant threshold, when put at 65537, the code https://psalm.dev/r/216f362ea6 goes
//from seconds in analysis to many minutes
if ($clause_count > 65536) {
return [];
}
if ($clause_count > 50) { if ($clause_count > 50) {
$all_has_unknown = true; $all_has_unknown = true;

View File

@ -3354,6 +3354,12 @@ class AssertionFinder
$source $source
); );
$other_var_name = ExpressionIdentifier::getArrayVarId(
$conditional->right,
$this_class_name,
$source
);
$other_type = $source->node_data->getType($conditional->left); $other_type = $source->node_data->getType($conditional->left);
$var_type = $source->node_data->getType($conditional->right); $var_type = $source->node_data->getType($conditional->right);
} elseif ($typed_value_position === self::ASSIGNMENT_TO_LEFT) { } elseif ($typed_value_position === self::ASSIGNMENT_TO_LEFT) {
@ -3363,6 +3369,12 @@ class AssertionFinder
$source $source
); );
$other_var_name = ExpressionIdentifier::getArrayVarId(
$conditional->left,
$this_class_name,
$source
);
$var_type = $source->node_data->getType($conditional->left); $var_type = $source->node_data->getType($conditional->left);
$other_type = $source->node_data->getType($conditional->right); $other_type = $source->node_data->getType($conditional->right);
} else { } else {
@ -3383,6 +3395,16 @@ class AssertionFinder
} else { } else {
$if_types[$var_name] = [['~' . $var_type->getAssertionString()]]; $if_types[$var_name] = [['~' . $var_type->getAssertionString()]];
} }
// we count the Atomics instead of using isSingle because Psalm considers multiple literals as Single
// however, getAssertionString return the assertion for the first Atomic only
if ($other_var_name && $other_type && count($other_type->getAtomicTypes()) === 1) {
if ($identical) {
$if_types[$other_var_name] = [['=' . $other_type->getAssertionString(true)]];
} else {
$if_types[$other_var_name] = [['~' . $other_type->getAssertionString()]];
}
}
} }
if ($codebase if ($codebase

View File

@ -2675,6 +2675,22 @@ class ConditionalTest extends \Psalm\Tests\TestCase
'$_a===' => '"N"|"Y"', '$_a===' => '"N"|"Y"',
] ]
], ],
'assertionsWorksBothWays' => [
'<?php
$a = 2;
$b = getPositiveInt();
assert($a === $b);
/** @return positive-int */
function getPositiveInt(): int{
return 2;
}',
'assertions' => [
'$a===' => '2',
'$b===' => '2',
]
],
'nullErasureWithSmallerAndGreater' => [ 'nullErasureWithSmallerAndGreater' => [
'<?php '<?php
function getIntOrNull(): ?int{return null;} function getIntOrNull(): ?int{return null;}