stateless EP inspection: don't take ProjectComponents into account
authorSergey Ignatov <sergey.ignatov@jetbrains.com>
Tue, 3 Nov 2015 15:12:26 +0000 (18:12 +0300)
committerSergey Ignatov <sergey.ignatov@jetbrains.com>
Tue, 3 Nov 2015 15:13:45 +0000 (18:13 +0300)
on IDEA-CR-6432

plugins/devkit/src/inspections/StatefulEpInspection.java
plugins/devkit/testData/inspections/statefulEp/ProjectComp.java [new file with mode: 0644]
plugins/devkit/testData/inspections/statefulEp/plugin.xml
plugins/devkit/testSources/inspections/StatefulEpInspectionTest.java

index 3cc5b1c9ff7c6e5f17d02e2f8bdace705148de6b..ee97296bf201efb6f88d2c3f35afaef083971261 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.InspectionManager;
 import com.intellij.codeInspection.LocalQuickFix;
 import com.intellij.codeInspection.ProblemDescriptor;
 import com.intellij.codeInspection.ProblemHighlightType;
+import com.intellij.openapi.components.ProjectComponent;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.util.InheritanceUtil;
@@ -36,11 +37,12 @@ public class StatefulEpInspection extends DevKitInspectionBase {
     PsiField[] fields = psiClass.getFields();
     if (fields.length == 0) return super.checkClass(psiClass, manager, isOnTheFly);
     final boolean isQuickFix = InheritanceUtil.isInheritor(psiClass, LocalQuickFix.class.getCanonicalName());
+    final boolean isProjectComponent = InheritanceUtil.isInheritor(psiClass, ProjectComponent.class.getCanonicalName());
     if (isQuickFix || ExtensionPointLocator.isImplementedEp(psiClass)) {
       List<ProblemDescriptor> result = ContainerUtil.newArrayList();
       for (final PsiField field : fields) {
         for (Class c : new Class[]{PsiElement.class, PsiReference.class, Project.class}) {
-          if (c == Project.class && field.hasModifierProperty(PsiModifier.FINAL)) continue;
+          if (c == Project.class && (field.hasModifierProperty(PsiModifier.FINAL) || isProjectComponent)) continue;
           String message = c == PsiElement.class
                            ? "Potential memory leak: don't hold PsiElement, use SmartPsiElementPointer instead" +
                              (isQuickFix ? "; also see LocalQuickFixOnPsiElement" : "")
diff --git a/plugins/devkit/testData/inspections/statefulEp/ProjectComp.java b/plugins/devkit/testData/inspections/statefulEp/ProjectComp.java
new file mode 100644 (file)
index 0000000..dcb5ec5
--- /dev/null
@@ -0,0 +1,12 @@
+public class ProjectComp implements com.intellij.openapi.components.ProjectComponent {
+  <warning descr="Potential memory leak: don't hold PsiElement, use SmartPsiElementPointer instead">final com.intellij.psi.PsiElement pe;</warning>
+  <warning descr="Don't use PsiReference as a field in extension">final com.intellij.psi.PsiReference r;</warning>
+  com.intellij.openapi.project.Project p;
+  final com.intellij.openapi.project.Project pf;
+  public ProjectComp() {
+    super();
+    pe = null;
+    r =null;
+    p = pf = null;
+  }
+}
\ No newline at end of file
index dcfcc027c96126a0b806b832f6917ae31f525473..239327c04384b43f2f1746174f07e0047ae05e9d 100644 (file)
@@ -4,5 +4,6 @@
   </extensionPoints>
   <extensions>
     <ep implementation="Ext"/>
+    <ep implementation="ProjectComp"/>
   </extensions>
 </idea-plugin>
\ No newline at end of file
index 722511ac1125c4159d4db726cacd141283318059..1da065f5ada140b822f3324b5373e2bacb09dd8b 100644 (file)
@@ -32,6 +32,7 @@ public class StatefulEpInspectionTest extends PluginModuleTestCase {
     myFixture.addClass("package com.intellij.psi; public class PsiElement {}");
     myFixture.addClass("package com.intellij.psi; public class PsiReference {}");
     myFixture.addClass("package com.intellij.codeInspection; public class LocalQuickFix {}");
+    myFixture.addClass("package com.intellij.openapi.components; public interface ProjectComponent {}");
     myFixture.enableInspections(new StatefulEpInspection());
   }
 
@@ -47,4 +48,9 @@ public class StatefulEpInspectionTest extends PluginModuleTestCase {
     setPluginXml("plugin.xml");
     myFixture.testHighlighting("Ext.java");
   }
+  
+  public void testProjectComp() {
+    setPluginXml("plugin.xml");
+    myFixture.testHighlighting("ProjectComp.java");
+  }
 }