qmljs: add check for comparisons not depending on values

currently we mainly try to warn about primitive == null/undefined or
primitive === non primitive.
There are other that we could warn about null==null null==undefined,
but I feel that they might be triggered too much by clean code.

Change-Id: Id43d838d60a4e13f361be34e4bb38211777a081e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
Fawzi Mohamed
2021-01-29 23:20:31 +01:00
parent cc00af8334
commit 7015ef04b7
4 changed files with 116 additions and 12 deletions

View File

@@ -1275,6 +1275,30 @@ static bool shouldAvoidNonStrictEqualityCheck(const Value *lhs, const Value *rhs
return false;
}
static bool equalIsAlwaysFalse(const Value *lhs, const Value *rhs)
{
if ((lhs->asNullValue() || lhs->asUndefinedValue())
&& (rhs->asNumberValue() || rhs->asBooleanValue() || rhs->asStringValue()))
return true;
return false;
}
static bool strictCompareConstant(const Value *lhs, const Value *rhs)
{
if (lhs->asUnknownValue() || rhs->asUnknownValue())
return false;
if (lhs->asBooleanValue() && !rhs->asBooleanValue())
return true;
if (lhs->asNumberValue() && !rhs->asNumberValue())
return true;
if (lhs->asStringValue() && !rhs->asStringValue())
return true;
if (lhs->asObjectValue() && (!rhs->asObjectValue() || !rhs->asNullValue() || !rhs->asUndefinedValue()))
return true;
return false;
}
bool Check::visit(BinaryExpression *ast)
{
const QString source = _doc->source();
@@ -1300,6 +1324,18 @@ bool Check::visit(BinaryExpression *ast)
|| shouldAvoidNonStrictEqualityCheck(rhsValue, lhsValue)) {
addMessage(MaybeWarnEqualityTypeCoercion, ast->operatorToken);
}
if (equalIsAlwaysFalse(lhsValue, rhsValue)
|| equalIsAlwaysFalse(rhsValue, lhsValue))
addMessage(WarnLogicalValueDoesNotDependOnValues, ast->operatorToken);
}
if (ast->op == QSOperator::StrictEqual || ast->op == QSOperator::StrictNotEqual) {
Evaluate eval(&_scopeChain);
const Value *lhsValue = eval(ast->left);
const Value *rhsValue = eval(ast->right);
if (strictCompareConstant(lhsValue, rhsValue)
|| strictCompareConstant(rhsValue, lhsValue)) {
addMessage(WarnLogicalValueDoesNotDependOnValues, ast->operatorToken);
}
}
// check odd + ++ combinations

View File

@@ -247,6 +247,8 @@ StaticAnalysisMessages::StaticAnalysisMessages()
tr("Hit maximum recursion limit when visiting AST."));
newMsg(ErrTypeIsInstantiatedRecursively, Error,
tr("Type cannot be instantiated recursively (%1)."), 1);
newMsg(WarnLogicalValueDoesNotDependOnValues, Warning,
tr("Logical value does not depend on actual values"));
}
} // anonymous namespace

View File

@@ -131,6 +131,7 @@ enum Type
ErrShorterStringValueExpected = 322,
ErrInvalidArrayValueLength = 323,
ErrHitMaximumRecursion = 324,
WarnLogicalValueDoesNotDependOnValues = 325,
WarnDuplicateImport = 400
};