IDEA-161298 (Inspection 'Method is identical to its super method' should warn about protected method with super call only)

This commit is contained in:
Bas Leijdekkers
2016-09-16 11:45:37 +02:00
parent 6a68f91170
commit f02ee59e5c
2 changed files with 44 additions and 9 deletions
@@ -18,7 +18,12 @@ package com.siyeh.ig.inheritance;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.PackageScope;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -158,7 +163,7 @@ public class RedundantMethodOverrideInspection extends BaseInspection {
}
}
private static boolean isSuperCallWithSameArguments(PsiCodeBlock body, PsiMethod method, PsiMethod superMethod) {
private boolean isSuperCallWithSameArguments(PsiCodeBlock body, PsiMethod method, PsiMethod superMethod) {
final PsiStatement[] statements = body.getStatements();
if (statements.length != 1) {
return false;
@@ -190,10 +195,31 @@ public class RedundantMethodOverrideInspection extends BaseInspection {
if (!MethodCallUtils.isSuperMethodCall(methodCallExpression, method)) return false;
if (superMethod.hasModifierProperty(PsiModifier.PROTECTED)) {
final PsiJavaFile superFile = (PsiJavaFile)superMethod.getContainingFile();
final PsiJavaFile file = (PsiJavaFile)method.getContainingFile();
// implementing a protected method in another package makes it available to that package.
if (!superFile.getPackageName().equals(file.getPackageName())) return false;
PsiPackage aPackage = JavaPsiFacade.getInstance(method.getProject()).findPackage(file.getPackageName());
if (aPackage == null) {
return false; // when package statement is incorrect
}
final PackageScope scope = new PackageScope(aPackage, false, false);
if (isOnTheFly()) {
final PsiSearchHelper searchHelper = PsiSearchHelper.SERVICE.getInstance(method.getProject());
final PsiSearchHelper.SearchCostResult cost =
searchHelper.isCheapEnoughToSearch(method.getName(), scope, null, null);
if (cost == PsiSearchHelper.SearchCostResult.ZERO_OCCURRENCES) {
return true;
}
if (cost == PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES) {
return false;
}
}
final Query<PsiReference> search = ReferencesSearch.search(method, scope);
final PsiClass containingClass = method.getContainingClass();
for (PsiReference reference : search) {
if (!PsiTreeUtil.isAncestor(containingClass, reference.getElement(), true)) {
return false;
}
}
}
return areSameArguments(methodCallExpression, method);
@@ -223,11 +249,11 @@ public class RedundantMethodOverrideInspection extends BaseInspection {
else if (list2 == null) {
return false;
}
final Set<String> annotations1 = new HashSet();
final Set<String> annotations1 = new HashSet<>();
for (PsiAnnotation annotation : list1.getAnnotations()) {
annotations1.add(annotation.getQualifiedName());
}
final Set<String> annotations2 = new HashSet();
final Set<String> annotations2 = new HashSet<>();
for (PsiAnnotation annotation : list2.getAnnotations()) {
annotations2.add(annotation.getQualifiedName());
}
@@ -243,7 +269,7 @@ public class RedundantMethodOverrideInspection extends BaseInspection {
}
private static <T> Set<T> disjunction(Collection<T> set1, Collection<T> set2) {
final Set<T> result = new HashSet();
final Set<T> result = new HashSet<>();
for (T t : set1) {
if (!set2.contains(t)) {
result.add(t);
@@ -1,5 +1,3 @@
package redundant_method_override;
import java.util.ArrayList;
public class RedundantMethodOverride extends S {
@@ -88,9 +86,20 @@ class C extends B {
}
class MyList extends ArrayList {
@Override
protected void removeRange(int fromIndex, int toIndex) {
protected void <warning descr="Method 'removeRange()' is identical to its super method">removeRange</warning>(int fromIndex, int toIndex) {
super.removeRange(fromIndex, toIndex);
}
void m() {
removeRange(0, 1);
new MyList2().removeRange(0, 0);
}
}
class MyList2 extends ArrayList {
@Override
protected void removeRange(int a, int b) {
super.removeRange(a, b);
}
}
////////////////
class Sup {