1
0
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:
Brown 2019-11-06 16:14:46 -05:00
parent 3e98c800ec
commit 06b64a4a01
3 changed files with 48 additions and 9 deletions

View File

@ -297,15 +297,19 @@ class PropertyFetchAnalyzer
$codebase->analyzer->incrementNonMixedCount($statements_analyzer->getRootFilePath()); $codebase->analyzer->incrementNonMixedCount($statements_analyzer->getRootFilePath());
} }
if ($stmt_var_type->isNullable() && !$context->inside_isset && !$stmt_var_type->ignore_nullable_issues) { if ($stmt_var_type->isNullable() && !$stmt_var_type->ignore_nullable_issues) {
if (IssueBuffer::accepts( if (!$context->inside_isset) {
new PossiblyNullPropertyFetch( if (IssueBuffer::accepts(
'Cannot get property on possibly null variable ' . $stmt_var_id . ' of type ' . $stmt_var_type, new PossiblyNullPropertyFetch(
new CodeLocation($statements_analyzer->getSource(), $stmt) 'Cannot get property on possibly null variable ' . $stmt_var_id . ' of type ' . $stmt_var_type,
), new CodeLocation($statements_analyzer->getSource(), $stmt)
$statements_analyzer->getSuppressedIssues() ),
)) { $statements_analyzer->getSuppressedIssues()
// fall through )) {
// fall through
}
} else {
$stmt->inferredType = Type::getNull();
} }
} }

View File

@ -1651,6 +1651,24 @@ class ExpressionAnalyzer
Context $context Context $context
) { ) {
self::analyzeIssetVar($statements_analyzer, $stmt->expr, $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(); $stmt->inferredType = Type::getBool();
} }

View File

@ -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_message' => 'RedundantCondition',
'error_levels' => ['MixedAssignment', 'MissingParamType'], 'error_levels' => ['MixedAssignment', 'MissingParamType'],
], ],
'preventEmptyOnBool' => [
'<?php
function foo(bool $b) : void {
if (!empty($b)) {}
}',
'error_message' => 'InvalidArgument',
],
]; ];
} }
} }