mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Detect erroneous use of empty check on bools
This commit is contained in:
parent
3e98c800ec
commit
06b64a4a01
@ -297,15 +297,19 @@ class PropertyFetchAnalyzer
|
||||
$codebase->analyzer->incrementNonMixedCount($statements_analyzer->getRootFilePath());
|
||||
}
|
||||
|
||||
if ($stmt_var_type->isNullable() && !$context->inside_isset && !$stmt_var_type->ignore_nullable_issues) {
|
||||
if (IssueBuffer::accepts(
|
||||
new PossiblyNullPropertyFetch(
|
||||
'Cannot get property on possibly null variable ' . $stmt_var_id . ' of type ' . $stmt_var_type,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
if ($stmt_var_type->isNullable() && !$stmt_var_type->ignore_nullable_issues) {
|
||||
if (!$context->inside_isset) {
|
||||
if (IssueBuffer::accepts(
|
||||
new PossiblyNullPropertyFetch(
|
||||
'Cannot get property on possibly null variable ' . $stmt_var_id . ' of type ' . $stmt_var_type,
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt)
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
} else {
|
||||
$stmt->inferredType = Type::getNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1651,6 +1651,24 @@ class ExpressionAnalyzer
|
||||
Context $context
|
||||
) {
|
||||
self::analyzeIssetVar($statements_analyzer, $stmt->expr, $context);
|
||||
|
||||
if (isset($stmt->expr->inferredType)
|
||||
&& $stmt->expr->inferredType->hasBool()
|
||||
&& $stmt->expr->inferredType->isSingle()
|
||||
&& !$stmt->expr->inferredType->from_docblock
|
||||
) {
|
||||
if (IssueBuffer::accepts(
|
||||
new \Psalm\Issue\InvalidArgument(
|
||||
'Calling empty on a boolean value is almost certainly unintended',
|
||||
new CodeLocation($statements_analyzer->getSource(), $stmt->expr),
|
||||
'empty'
|
||||
),
|
||||
$statements_analyzer->getSuppressedIssues()
|
||||
)) {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->inferredType = Type::getBool();
|
||||
}
|
||||
|
||||
|
@ -343,6 +343,16 @@ class EmptyTest extends TestCase
|
||||
}
|
||||
}',
|
||||
],
|
||||
'allowEmptyCheckOnPossiblyNullPropertyFetch' => [
|
||||
'<?php
|
||||
class A {
|
||||
public bool $b = false;
|
||||
}
|
||||
|
||||
function foo(?A $a) : void {
|
||||
if (!empty($a->b)) {}
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@ -373,6 +383,13 @@ class EmptyTest extends TestCase
|
||||
'error_message' => 'RedundantCondition',
|
||||
'error_levels' => ['MixedAssignment', 'MissingParamType'],
|
||||
],
|
||||
'preventEmptyOnBool' => [
|
||||
'<?php
|
||||
function foo(bool $b) : void {
|
||||
if (!empty($b)) {}
|
||||
}',
|
||||
'error_message' => 'InvalidArgument',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user