Deprecation warning not highlighted when superclass default constructor is deprecated...
authoranna <anna.kozlova@jetbrains.com>
Tue, 7 Jun 2011 12:03:12 +0000 (16:03 +0400)
committeranna <anna.kozlova@jetbrains.com>
Tue, 7 Jun 2011 17:34:58 +0000 (21:34 +0400)
java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuper/expected.xml [new file with mode: 0644]
java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuper/src/Test.java [new file with mode: 0644]
java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuperNotCalled/expected.xml [new file with mode: 0644]
java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuperNotCalled/src/Test.java [new file with mode: 0644]
java/java-tests/testSrc/com/intellij/codeInspection/DeprecationInspectionTest.java

index 54f090eaec8faa84cd1e4a19e3c724ebfc58ca7e..8c2009b23ab98695e33001c359bdb216fa5ee794 100644 (file)
@@ -19,12 +19,15 @@ import com.intellij.codeInsight.daemon.JavaErrorMessages;
 import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
 import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
 import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.LocalInspectionTool;
 import com.intellij.codeInspection.ProblemHighlightType;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
 import com.intellij.psi.infos.MethodCandidateInfo;
 import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
+import com.intellij.refactoring.util.RefactoringUIUtil;
+import com.intellij.refactoring.util.RefactoringUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -119,8 +122,52 @@ public class DeprecationInspection extends BaseJavaLocalInspectionTool {
         if (!method.isConstructor()) {
           List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
           checkMethodOverridesDeprecated(methodSignature, superMethodSignatures, myHolder);
+        } else {
+          checkImplicitCallToSuper(method);
+        }
+    }
+
+    private void checkImplicitCallToSuper(PsiMethod method) {
+      final PsiClass containingClass = method.getContainingClass();
+      assert containingClass != null;
+      final PsiClass superClass = containingClass.getSuperClass();
+      if (hasDefaultDeprecatedConstructor(superClass)) {
+        final PsiCodeBlock body = method.getBody();
+        if (body != null) {
+          final PsiStatement[] statements = body.getStatements();
+          if (statements.length == 0 || !RefactoringUtil.isSuperOrThisCall(statements[0], true, true)) {
+            registerDefaultConstructorProblem(superClass, method.getNameIdentifier());
+          }
         }
       }
+    }
+
+    private void registerDefaultConstructorProblem(PsiClass superClass, PsiIdentifier nameIdentifier) {
+      myHolder.registerProblem(nameIdentifier, "Default constructor in " + superClass.getQualifiedName() + " is deprecated", ProblemHighlightType.LIKE_DEPRECATED);
+    }
+
+    @Override
+    public void visitClass(PsiClass aClass) {
+      final PsiMethod[] currentConstructors = aClass.getConstructors();
+      if (currentConstructors.length == 0) {
+        final PsiClass superClass = aClass.getSuperClass();
+        if (hasDefaultDeprecatedConstructor(superClass)) {
+          registerDefaultConstructorProblem(superClass, aClass.getNameIdentifier());
+        }
+      }
+    }
+  }
+
+  private static boolean hasDefaultDeprecatedConstructor(PsiClass superClass) {
+    if (superClass != null) {
+      final PsiMethod[] constructors = superClass.getConstructors();
+      for (PsiMethod constructor : constructors) {
+        if (constructor.getParameterList().getParametersCount() == 0 && constructor.isDeprecated()) {
+          return true;
+        }
+      }
+    }
+    return false;
   }
 
   //@top
diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuper/expected.xml b/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuper/expected.xml
new file mode 100644 (file)
index 0000000..2ea8b4a
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+  <problem>
+    <file>Test.java</file>
+    <line>5</line>
+    <description>Default constructor in C is deprecated</description>
+  </problem>
+</problems>
+
diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuper/src/Test.java b/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuper/src/Test.java
new file mode 100644 (file)
index 0000000..52d0116
--- /dev/null
@@ -0,0 +1,6 @@
+class C {
+  @Deprecated C() { }
+}
+
+class D extends C {
+}
diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuperNotCalled/expected.xml b/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuperNotCalled/expected.xml
new file mode 100644 (file)
index 0000000..fbfc5a0
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<problems>
+  <problem>
+    <file>Test.java</file>
+    <line>6</line>
+    <description>Default constructor in C is deprecated</description>
+  </problem>
+</problems>
+
diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuperNotCalled/src/Test.java b/java/java-tests/testData/inspection/deprecation/deprecatedDefaultConstructorInSuperNotCalled/src/Test.java
new file mode 100644 (file)
index 0000000..c40f1d0
--- /dev/null
@@ -0,0 +1,8 @@
+class C {
+  @Deprecated C() { }
+}
+
+class D extends C {
+  D() {
+  }
+}
index f8254695922829cb1a253489945c18b2411a1d78..b53c7ed5741826b301ef5626660cb0615bc2ca5e 100644 (file)
@@ -32,4 +32,13 @@ public class DeprecationInspectionTest extends InspectionTestCase {
   public void testDeprecatedField() throws Exception{
     doTest();
   }
+
+  public void testDeprecatedDefaultConstructorInSuper() throws Exception {
+    doTest();
+  }
+
+  public void testDeprecatedDefaultConstructorInSuperNotCalled() throws Exception {
+    doTest();
+  }
+
 }