IDEA-161298 (Inspection 'Method is identical to its super method' should warn about...
authorBas Leijdekkers <basleijdekkers@gmail.com>
Fri, 16 Sep 2016 09:44:50 +0000 (11:44 +0200)
committerBas Leijdekkers <basleijdekkers@gmail.com>
Fri, 16 Sep 2016 09:45:37 +0000 (11:45 +0200)
plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/inheritance/RedundantMethodOverrideInspection.java
plugins/InspectionGadgets/test/com/siyeh/igtest/inheritance/redundant_method_override/RedundantMethodOverride.java

index 92f922eeb15168dcdb26bd9642b95a98c6e0eb5d..fd2c77dd8b905198584f3940c9cf4d9b60398dba 100644 (file)
@@ -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);
index 918c09171e1ac1890fd121f8abfd8721114b1d3a..84fb1046988ad4c7800ae17e0d34fc86c5b5d381 100644 (file)
@@ -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 {