From e2e5f321ab717df382f169fca7f8cad991308d31 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Thu, 31 Mar 2011 13:11:29 +0200 Subject: [PATCH] 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) --- ...chDoesntCheckParameterClassInspection.java | 74 +++++++++++++++++-- .../EqualsWhichDoesntCheckParameterClass.java | 13 +++- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java index 7257ed090a81..244fc7ed4834 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/EqualsWhichDoesntCheckParameterClassInspection.java @@ -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; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java index 7bedea513d3e..f31cceebc9fb 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/equals_which_doesnt_check_parameter/EqualsWhichDoesntCheckParameterClass.java @@ -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); + } +}