From f02ee59e5ce48705753c13fa6b38f86fd702831a Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 16 Sep 2016 11:44:50 +0200 Subject: [PATCH] IDEA-161298 (Inspection 'Method is identical to its super method' should warn about protected method with super call only) --- .../RedundantMethodOverrideInspection.java | 38 ++++++++++++++++--- .../RedundantMethodOverride.java | 15 ++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java index 92f922eeb151..fd2c77dd8b90 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java @@ -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 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 annotations1 = new HashSet(); + final Set annotations1 = new HashSet<>(); for (PsiAnnotation annotation : list1.getAnnotations()) { annotations1.add(annotation.getQualifiedName()); } - final Set annotations2 = new HashSet(); + final Set annotations2 = new HashSet<>(); for (PsiAnnotation annotation : list2.getAnnotations()) { annotations2.add(annotation.getQualifiedName()); } @@ -243,7 +269,7 @@ public class RedundantMethodOverrideInspection extends BaseInspection { } private static Set disjunction(Collection set1, Collection set2) { - final Set result = new HashSet(); + final Set result = new HashSet<>(); for (T t : set1) { if (!set2.contains(t)) { result.add(t); diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/redundant_method_override/RedundantMethodOverride.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/redundant_method_override/RedundantMethodOverride.java index 918c09171e1a..84fb1046988a 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/redundant_method_override/RedundantMethodOverride.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/redundant_method_override/RedundantMethodOverride.java @@ -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 removeRange(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 {