diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java index 35d0ed185833..a6f04f8d66a8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspectionBase.java @@ -67,6 +67,7 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool { public boolean ADD_APPLET_TO_ENTRIES = true; public boolean ADD_SERVLET_TO_ENTRIES = true; public boolean ADD_NONJAVA_TO_ENTRIES = true; + protected boolean TEST_ENTRY_POINTS = true; public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.dead.code.display.name"); public static final String SHORT_NAME = HighlightInfoType.UNUSED_SYMBOL_SHORT_NAME; @@ -128,6 +129,14 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool { return ADD_NONJAVA_TO_ENTRIES; } + public boolean isTestEntryPoints() { + return TEST_ENTRY_POINTS; + } + + public void setTestEntryPoints(boolean testEntryPoints) { + TEST_ENTRY_POINTS = testEntryPoints; + } + @Override @NotNull public String getDisplayName() { @@ -153,12 +162,19 @@ public class UnusedDeclarationInspectionBase extends GlobalInspectionTool { for (EntryPoint extension : myExtensions) { extension.readExternal(node); } + + final String testEntriesAttr = node.getAttributeValue("test_entries"); + TEST_ENTRY_POINTS = testEntriesAttr == null || Boolean.parseBoolean(testEntriesAttr); } @Override public void writeSettings(@NotNull Element node) throws WriteExternalException { myLocalInspectionBase.writeSettings(node); writeUnusedDeclarationSettings(node); + + if (!TEST_ENTRY_POINTS) { + node.setAttribute("test_entries", Boolean.toString(false)); + } } protected void writeUnusedDeclarationSettings(Element node) throws WriteExternalException { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java index 42ad42bfeb94..1cb8b5a9bb3f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java @@ -23,13 +23,16 @@ import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase; import com.intellij.codeInspection.ex.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.javadoc.PsiDocTag; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.IncorrectOperationException; import gnu.trove.THashMap; import org.jdom.Element; @@ -109,7 +112,17 @@ public class RefJavaManagerImpl extends RefJavaManager { public boolean isEntryPoint(final RefElement element) { UnusedDeclarationInspectionBase tool = getDeadCodeTool(element); - return tool != null && tool.isEntryPoint(element); + return tool != null && tool.isEntryPoint(element) && isTestSource(tool, element); + } + + private static boolean isTestSource(UnusedDeclarationInspectionBase tool, RefElement refElement) { + if (tool.isTestEntryPoints()) return true; + final PsiElement element = refElement.getElement(); + final VirtualFile file = PsiUtilCore.getVirtualFile(element); + if (file != null) { + return !ProjectRootManager.getInstance(element.getProject()).getFileIndex().isInTestSourceContent(file); + } + return false; } @Nullable diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java index a6efe9e21907..7731b21d1ac6 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java @@ -25,6 +25,9 @@ import com.intellij.codeInspection.reference.RefVisitor; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspectionBase; import com.intellij.openapi.ui.VerticalFlowLayout; +import com.intellij.ui.TitledSeparator; +import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.JBRadioButton; import com.intellij.ui.components.JBTabbedPane; import com.intellij.util.ui.JBUI; import org.jetbrains.annotations.NotNull; @@ -123,10 +126,31 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase GridBagConstraints gc = new GridBagConstraints(); gc.weightx = 1; gc.weighty = 0; - gc.insets = JBUI.insets(0, 20, 2, 0); + gc.fill = GridBagConstraints.HORIZONTAL; gc.anchor = GridBagConstraints.NORTHWEST; + gc.gridx = 0; + gc.gridy = GridBagConstraints.RELATIVE; + add(new JBLabel("When entry point is located in test sources:"), gc); + final JBRadioButton asEntryPoint = new JBRadioButton("Treat as entry point", isTestEntryPoints()); + final JBRadioButton asUnused = new JBRadioButton("Mark callees as unused", !isTestEntryPoints()); + final ButtonGroup group = new ButtonGroup(); + group.add(asEntryPoint); + group.add(asUnused); + final ActionListener listener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setTestEntryPoints(asEntryPoint.isSelected()); + } + }; + asEntryPoint.addActionListener(listener); + asUnused.addActionListener(listener); + add(asEntryPoint, gc); + add(asUnused, gc); + add(new TitledSeparator(), gc); + + gc.insets = JBUI.insets(0, 20, 2, 0); myMainsCheckbox = new JCheckBox(InspectionsBundle.message("inspection.dead.code.option.main")); myMainsCheckbox.setSelected(ADD_MAINS_TO_ENTRIES); myMainsCheckbox.addActionListener(new ActionListener() { @@ -136,7 +160,7 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase } }); - gc.gridy = 0; + add(myMainsCheckbox, gc); myAppletToEntries = new JCheckBox(InspectionsBundle.message("inspection.dead.code.option.applet")); @@ -147,7 +171,6 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase ADD_APPLET_TO_ENTRIES = myAppletToEntries.isSelected(); } }); - gc.gridy++; add(myAppletToEntries, gc); myServletToEntries = new JCheckBox(InspectionsBundle.message("inspection.dead.code.option.servlet")); @@ -158,7 +181,6 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase ADD_SERVLET_TO_ENTRIES = myServletToEntries.isSelected(); } }); - gc.gridy++; add(myServletToEntries, gc); for (final EntryPoint extension : myExtensions) { @@ -171,7 +193,6 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase extension.setSelected(extCheckbox.isSelected()); } }); - gc.gridy++; add(extCheckbox, gc); } } @@ -186,11 +207,9 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase } }); - gc.gridy++; add(myNonJavaCheckbox, gc); gc.fill = GridBagConstraints.NONE; - gc.gridy++; gc.weighty = 1; final JPanel btnPanel = new JPanel(new VerticalFlowLayout()); btnPanel.add(EntryPointsManagerImpl.createConfigureClassPatternsButton()); diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java index d60b49e98566..341b24194be4 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationPresentation.java @@ -435,6 +435,7 @@ public class UnusedDeclarationPresentation extends DefaultInspectionToolPresenta RefJavaElement refElement = (RefJavaElement)refEntity; if (!compareVisibilities(refElement, localInspectionTool)) return; if (!(getContext().getUIOptions().FILTER_RESOLVED_ITEMS && getIgnoredRefElements().contains(refElement)) && refElement.isValid() && getFilter().accepts(refElement)) { + if (getTool().isEntryPoint(refElement)) return; registerContentEntry(refEntity, RefJavaUtil.getInstance().getPackageName(refEntity)); } }