IDEA-66739 (Inspection "equals() method which does not check class of parameter" should not report methods with "return false" body)

IDEA-25556 (Inspection "equals() doesn't check class of parameter" - shouldn't fail when only calling super.equals)
This commit is contained in:
Bas Leijdekkers
2011-03-31 13:11:29 +02:00
parent 4d41f2fd92
commit e2e5f321ab
2 changed files with 81 additions and 6 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2003-2008 Dave Griffith, Bas Leijdekkers
* Copyright 2003-2011 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +16,13 @@
package com.siyeh.ig.bugs;
import com.intellij.psi.*;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.MethodUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class EqualsWhichDoesntCheckParameterClassInspection
@@ -64,13 +67,75 @@ public class EqualsWhichDoesntCheckParameterClassInspection
if(body == null){
return;
}
if(isParameterChecked(body, parameter)){
return;
}
if (isParameterCheckNotNeeded(body, parameter)) {
return;
}
registerMethodError(method);
}
private static boolean isParameterCheckNotNeeded(
PsiCodeBlock body, PsiParameter parameter) {
final PsiStatement[] statements = body.getStatements();
if (statements.length == 0) {
return true;
}
if (statements.length != 1) {
return false;
}
final PsiStatement statement = statements[0];
if (!(statement instanceof PsiReturnStatement)) {
return false;
}
final PsiReturnStatement returnStatement =
(PsiReturnStatement) statement;
final PsiExpression returnValue =
returnStatement.getReturnValue();
final Object constant =
ExpressionUtils.computeConstantExpression(returnValue);
if (Boolean.FALSE.equals(constant)) {
return true;
}
if (!(returnValue instanceof PsiMethodCallExpression)) {
return false;
}
final PsiMethodCallExpression methodCallExpression =
(PsiMethodCallExpression) returnValue;
return isCallToSuperEquals(methodCallExpression, parameter);
}
private static boolean isCallToSuperEquals(
PsiMethodCallExpression methodCallExpression,
PsiParameter parameter) {
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final PsiExpression qualifierExpression =
methodExpression.getQualifierExpression();
if (!(qualifierExpression instanceof PsiSuperExpression)) {
return false;
}
final String name = methodExpression.getReferenceName();
if (!HardcodedMethodConstants.EQUALS.equals(name)) {
return false;
}
final PsiExpressionList argumentList =
methodCallExpression.getArgumentList();
final PsiExpression[] arguments = argumentList.getExpressions();
if (arguments.length != 1) {
return false;
}
final PsiExpression argument = arguments[0];
if (!(argument instanceof PsiReferenceExpression)) {
return false;
}
final PsiReferenceExpression referenceExpression =
(PsiReferenceExpression) argument;
final PsiElement target = referenceExpression.resolve();
return parameter.equals(target);
}
private static boolean isParameterChecked(PsiCodeBlock body,
PsiParameter parameter){
if (usesEqualsBuilderReflectionEquals(body)) {
@@ -103,7 +168,7 @@ public class EqualsWhichDoesntCheckParameterClassInspection
(PsiMethodCallExpression) returnValue;
final PsiReferenceExpression methodExpression =
methodCallExpression.getMethodExpression();
final String referenceName =
@NonNls final String referenceName =
methodExpression.getReferenceName();
if (!"reflectionEquals".equals(referenceName)) {
return false;
@@ -115,8 +180,7 @@ public class EqualsWhichDoesntCheckParameterClassInspection
}
final PsiReferenceExpression referenceExpression =
(PsiReferenceExpression) qualifier;
final PsiElement target =
referenceExpression.resolve();
final PsiElement target = referenceExpression.resolve();
if (!(target instanceof PsiClass)) {
return false;
}
@@ -67,4 +67,15 @@ class Three {
return three;
}
}
class Four {
@Override
public boolean equals(Object obj) {
return false;
}
}
class Five {
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}