diff --git a/plugins/devkit/src/inspections/StatefulEpInspection.java b/plugins/devkit/src/inspections/StatefulEpInspection.java index f226a8d74846..eb30ce42152a 100644 --- a/plugins/devkit/src/inspections/StatefulEpInspection.java +++ b/plugins/devkit/src/inspections/StatefulEpInspection.java @@ -26,9 +26,11 @@ import com.intellij.psi.PsiField; import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiReference; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.xml.XmlTag; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.devkit.util.ExtensionCandidate; import org.jetbrains.idea.devkit.util.ExtensionLocator; import org.jetbrains.uast.UClass; @@ -42,13 +44,20 @@ public class StatefulEpInspection extends DevKitUastInspectionBase { if (fields.length == 0) return super.checkClass(psiClass, manager, isOnTheFly); final boolean isQuickFix = InheritanceUtil.isInheritor(psiClass, LocalQuickFix.class.getCanonicalName()); - if (isQuickFix || ExtensionLocator.isRegisteredExtension(psiClass)) { - final boolean isProjectComponent = InheritanceUtil.isInheritor(psiClass, ProjectComponent.class.getCanonicalName()); + ExtensionLocator locator = new ExtensionLocator(psiClass); + List targets = locator.findCandidates(); + if (isQuickFix || !targets.isEmpty()) { + boolean isProjectComponent = InheritanceUtil.isInheritor(psiClass, ProjectComponent.class.getCanonicalName()); + boolean projectService = ContainerUtil.find(targets, candidate -> { + XmlTag element = candidate.pointer.getElement(); + String name = element != null ? element.getName() : null; + return "projectService".equals(name); + }) != null; List result = ContainerUtil.newArrayList(); - for (final PsiField field : fields) { + for (PsiField field : fields) { for (Class c : new Class[]{PsiElement.class, PsiReference.class, Project.class}) { - if (c == Project.class && (field.hasModifierProperty(PsiModifier.FINAL) || isProjectComponent)) continue; + if (c == Project.class && (field.hasModifierProperty(PsiModifier.FINAL) || isProjectComponent || projectService)) 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/ProjectService.java b/plugins/devkit/testData/inspections/statefulEp/ProjectService.java new file mode 100644 index 000000000000..2397463d1109 --- /dev/null +++ b/plugins/devkit/testData/inspections/statefulEp/ProjectService.java @@ -0,0 +1,14 @@ +import com.intellij.openapi.project.Project; + +public class ProjectService { + final com.intellij.psi.PsiElement pe; + final com.intellij.psi.PsiReference r; + Project p; + final Project pf; + public ProjectService(Project project) { + super(); + pe = null; + r = null; + p = pf = project; + } +} \ No newline at end of file diff --git a/plugins/devkit/testData/inspections/statefulEp/plugin.xml b/plugins/devkit/testData/inspections/statefulEp/plugin.xml index a5480e99c638..54d78e836afd 100644 --- a/plugins/devkit/testData/inspections/statefulEp/plugin.xml +++ b/plugins/devkit/testData/inspections/statefulEp/plugin.xml @@ -1,10 +1,13 @@ + + + \ No newline at end of file diff --git a/plugins/devkit/testSources/inspections/StatefulEpInspectionTest.java b/plugins/devkit/testSources/inspections/StatefulEpInspectionTest.java index 189faa9360ca..65897e63bd46 100644 --- a/plugins/devkit/testSources/inspections/StatefulEpInspectionTest.java +++ b/plugins/devkit/testSources/inspections/StatefulEpInspectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,4 +54,9 @@ public class StatefulEpInspectionTest extends PluginModuleTestCase { setPluginXml("plugin.xml"); myFixture.testHighlighting("ProjectComp.java"); } + + public void testProjectService() { + setPluginXml("plugin.xml"); + myFixture.testHighlighting("ProjectService.java"); + } }