mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Add negated identity with false case
This is the opposite of === true and works the same.
This commit is contained in:
parent
c9f52c449b
commit
26f8e5b333
@ -12,4 +12,8 @@ function returnsABool(): bool {
|
||||
if (returnsABool() === true) {
|
||||
echo "hi!";
|
||||
}
|
||||
|
||||
if (returnsABool() !== false) {
|
||||
echo "hi!";
|
||||
}
|
||||
```
|
||||
|
@ -2076,41 +2076,58 @@ class AssertionFinder
|
||||
if ($codebase
|
||||
&& $source instanceof StatementsAnalyzer
|
||||
&& ($var_type = $source->node_data->getType($base_conditional))
|
||||
&& $conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical
|
||||
) {
|
||||
if ($conditional instanceof PhpParser\Node\Expr\BinaryOp\NotIdentical) {
|
||||
$false_type = Type::getFalse();
|
||||
$config = $source->getCodebase()->config;
|
||||
|
||||
if (!UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$var_type,
|
||||
$false_type
|
||||
) && !UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$false_type,
|
||||
$var_type
|
||||
if ($config->strict_binary_operands
|
||||
&& $var_type->isSingle()
|
||||
&& $var_type->hasBool()
|
||||
&& !$var_type->from_docblock
|
||||
) {
|
||||
if (IssueBuffer::accepts(
|
||||
new RedundantIdentityWithTrue(
|
||||
'The "!== false" part of this comparison is redundant',
|
||||
new CodeLocation($source, $conditional)
|
||||
),
|
||||
$source->getSuppressedIssues()
|
||||
)) {
|
||||
if ($var_type->from_docblock) {
|
||||
if (IssueBuffer::accepts(
|
||||
new RedundantConditionGivenDocblockType(
|
||||
'Docblock-defined type ' . $var_type . ' can never contain false',
|
||||
new CodeLocation($source, $conditional),
|
||||
$var_type->getId() . ' false'
|
||||
),
|
||||
$source->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
} else {
|
||||
if (IssueBuffer::accepts(
|
||||
new RedundantCondition(
|
||||
$var_type . ' can never contain false',
|
||||
new CodeLocation($source, $conditional),
|
||||
$var_type->getId() . ' false'
|
||||
),
|
||||
$source->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
$false_type = Type::getFalse();
|
||||
|
||||
if (!UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$var_type,
|
||||
$false_type
|
||||
) && !UnionTypeComparator::isContainedBy(
|
||||
$codebase,
|
||||
$false_type,
|
||||
$var_type
|
||||
)) {
|
||||
if ($var_type->from_docblock) {
|
||||
if (IssueBuffer::accepts(
|
||||
new RedundantConditionGivenDocblockType(
|
||||
'Docblock-defined type ' . $var_type . ' can never contain false',
|
||||
new CodeLocation($source, $conditional),
|
||||
$var_type->getId() . ' false'
|
||||
),
|
||||
$source->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
} else {
|
||||
if (IssueBuffer::accepts(
|
||||
new RedundantCondition(
|
||||
$var_type . ' can never contain false',
|
||||
new CodeLocation($source, $conditional),
|
||||
$var_type->getId() . ' false'
|
||||
),
|
||||
$source->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +107,29 @@ class BinaryOperationTest extends TestCase
|
||||
$this->analyzeFile('somefile.php', new \Psalm\Context());
|
||||
}
|
||||
|
||||
public function testStringFalseInequivalence(): void
|
||||
{
|
||||
$config = \Psalm\Config::getInstance();
|
||||
$config->strict_binary_operands = true;
|
||||
|
||||
$this->addFile(
|
||||
'somefile.php',
|
||||
'<?php
|
||||
function returnsABool(): bool {
|
||||
return rand(1, 2) === 1;
|
||||
}
|
||||
|
||||
if (returnsABool() !== false) {
|
||||
echo "hi!";
|
||||
}'
|
||||
);
|
||||
|
||||
$this->expectException(\Psalm\Exception\CodeException::class);
|
||||
$this->expectExceptionMessage('RedundantIdentityWithTrue');
|
||||
|
||||
$this->analyzeFile('somefile.php', new \Psalm\Context());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<string,array{string,assertions?:array<string,string>,error_levels?:string[]}>
|
||||
*/
|
||||
@ -532,7 +555,7 @@ class BinaryOperationTest extends TestCase
|
||||
],
|
||||
'IntOverflowPlus' => [
|
||||
'<?php
|
||||
$a = 2**62 - 1 + 2**62;
|
||||
$a = 2**62 - 1 + 2**62;
|
||||
$b = 2**62 + 2**62 - 1; // plus results in a float',
|
||||
'assertions' => [
|
||||
'$a' => 'int',
|
||||
|
Loading…
x
Reference in New Issue
Block a user