diff --git a/java/execution/impl/src/com/intellij/execution/actions/AbstractAddToTestsPatternAction.java b/java/execution/impl/src/com/intellij/execution/actions/AbstractAddToTestsPatternAction.java index 1c5765a39650..851bdf322343 100644 --- a/java/execution/impl/src/com/intellij/execution/actions/AbstractAddToTestsPatternAction.java +++ b/java/execution/impl/src/com/intellij/execution/actions/AbstractAddToTestsPatternAction.java @@ -26,12 +26,11 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; import com.intellij.psi.PsiElement; +import com.intellij.psi.search.PsiElementProcessor; import org.jetbrains.annotations.NotNull; import javax.swing.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; public abstract class AbstractAddToTestsPatternAction extends AnAction { @NotNull protected abstract AbstractPatternBasedConfigurationProducer getPatternBasedProducer(); @@ -46,7 +45,9 @@ public abstract class AbstractAddToTestsPatternAction classes = getPatternBasedProducer().collectTestMembers(psiElements, true); + final LinkedHashSet classes = new LinkedHashSet(); + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(classes); + getPatternBasedProducer().collectTestMembers(psiElements, true, true, processor); final Project project = CommonDataKeys.PROJECT.getData(dataContext); final List patternConfigurations = collectPatternConfigurations(classes, project); @@ -86,11 +87,13 @@ public abstract class AbstractAddToTestsPatternAction foundMembers = getPatternBasedProducer().collectTestMembers(psiElements, true); - if (foundMembers.isEmpty()) return; + PsiElementProcessor.CollectElementsWithLimit processor = new PsiElementProcessor.CollectElementsWithLimit(2); + getPatternBasedProducer().collectTestMembers(psiElements, false, false, processor); + Collection collection = processor.getCollection(); + if (collection.isEmpty()) return; final Project project = CommonDataKeys.PROJECT.getData(dataContext); if (project != null) { - final List foundConfigurations = collectPatternConfigurations(foundMembers, project); + final List foundConfigurations = collectPatternConfigurations(collection, project); if (!foundConfigurations.isEmpty()) { presentation.setVisible(true); if (foundConfigurations.size() == 1) { @@ -101,7 +104,7 @@ public abstract class AbstractAddToTestsPatternAction collectPatternConfigurations(Set foundClasses, Project project) { + private List collectPatternConfigurations(Collection foundClasses, Project project) { final List configurations = RunManager.getInstance(project).getConfigurationsList(getConfigurationType()); final List foundConfigurations = new ArrayList(); for (RunConfiguration configuration : configurations) { diff --git a/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java b/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java index 12a0502e31a6..b1186ab0efc3 100644 --- a/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java +++ b/java/execution/impl/src/com/intellij/execution/testframework/AbstractPatternBasedConfigurationProducer.java @@ -26,10 +26,12 @@ import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.LangDataKeys; import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; +import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.util.ClassUtil; import java.util.ArrayList; @@ -55,18 +57,27 @@ public abstract class AbstractPatternBasedConfigurationProducer classes = new LinkedHashSet(); - final PsiElement[] elements = collectPatternElements(context, classes); - if (elements != null && collectTestMembers(elements, false).size() > 1) { - return true; + final PsiElementProcessor.CollectElementsWithLimit processor = new PsiElementProcessor.CollectElementsWithLimit(2); + final PsiElement[] locationElements = collectLocationElements(classes, dataContext); + if (locationElements != null) { + collectTestMembers(locationElements, false, false, processor); } - return false; + else { + collectContextElements(dataContext, false, false, classes, processor); + } + return processor.getCollection().size() > 1; } public boolean isConfiguredFromContext(ConfigurationContext context, Set patterns) { final LinkedHashSet classes = new LinkedHashSet(); - collectPatternElements(context, classes); + final DataContext dataContext = context.getDataContext(); + final PsiElement[] locationElements = collectLocationElements(classes, dataContext); + if (locationElements == null) { + collectContextElements(dataContext, true, false, classes, new PsiElementProcessor.CollectElements()); + } if (Comparing.equal(classes, patterns)) { return true; } @@ -74,43 +85,91 @@ public abstract class AbstractPatternBasedConfigurationProducer classes) { - PsiElement[] elements = collectPatternElements(context, classes); - if (elements == null || collectTestMembers(elements, false).size() <= 1) { + PsiElement[] result; + final DataContext dataContext = context.getDataContext(); + final PsiElement[] locationElements = collectLocationElements(classes, dataContext); + PsiElementProcessor.CollectElements processor = new PsiElementProcessor.CollectElements(); + if (locationElements != null) { + collectTestMembers(locationElements, false, true, processor); + result = processor.toArray(); + } + else if (collectContextElements(dataContext, true, true, classes, processor)) { + result = processor.toArray(); + } + else { return null; } - return elements[0]; + if (result.length <= 1) { + return null; + } + return result[0]; } - public Set collectTestMembers(PsiElement[] psiElements, boolean checkAbstract) { - final Set foundMembers = new LinkedHashSet(); + public void collectTestMembers(PsiElement[] psiElements, + boolean checkAbstract, + boolean checkIsTest, + PsiElementProcessor.CollectElements collectingProcessor) { for (PsiElement psiElement : psiElements) { if (psiElement instanceof PsiClassOwner) { final PsiClass[] classes = ((PsiClassOwner)psiElement).getClasses(); for (PsiClass aClass : classes) { - if (isTestClass(aClass)) { - foundMembers.add(aClass); + if ((!checkIsTest || isTestClass(aClass)) && !collectingProcessor.execute(aClass)) { + return; } } } else if (psiElement instanceof PsiClass) { - if (isTestClass((PsiClass)psiElement)) { - foundMembers.add(psiElement); + if ((!checkIsTest || isTestClass((PsiClass)psiElement)) && !collectingProcessor.execute(psiElement)) { + return; } } else if (psiElement instanceof PsiMethod) { - if (isTestMethod(checkAbstract, psiElement)) { - foundMembers.add(psiElement); + if ((!checkIsTest || isTestMethod(checkAbstract, psiElement)) && !collectingProcessor.execute(psiElement)) { + return; } } else if (psiElement instanceof PsiDirectory) { final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage((PsiDirectory)psiElement); - if (aPackage != null) { - foundMembers.add(aPackage); + if (aPackage != null && !collectingProcessor.execute(aPackage)) { + return; } } } - return foundMembers; } - - private PsiElement[] collectPatternElements(ConfigurationContext context, LinkedHashSet classes) { - final DataContext dataContext = context.getDataContext(); + + private boolean collectContextElements(DataContext dataContext, + boolean checkAbstract, + boolean checkIsTest, + LinkedHashSet classes, + PsiElementProcessor.CollectElements processor) { + PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext); + if (elements != null) { + collectTestMembers(elements, checkAbstract, checkIsTest, processor); + for (PsiElement psiClass : processor.getCollection()) { + classes.add(getQName(psiClass)); + } + return true; + } + else { + final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext); + if (files != null) { + Project project = CommonDataKeys.PROJECT.getData(dataContext); + if (project != null) { + final PsiManager psiManager = PsiManager.getInstance(project); + for (VirtualFile file : files) { + final PsiFile psiFile = psiManager.findFile(file); + if (psiFile instanceof PsiClassOwner) { + collectTestMembers(((PsiClassOwner)psiFile).getClasses(), checkAbstract, checkIsTest, processor); + for (PsiElement psiMember : processor.getCollection()) { + classes.add(((PsiClass)psiMember).getQualifiedName()); + } + } + } + return true; + } + } + } + return false; + } + + private static PsiElement[] collectLocationElements(LinkedHashSet classes, DataContext dataContext) { final Location[] locations = Location.DATA_KEYS.getData(dataContext); if (locations != null) { List elements = new ArrayList(); @@ -121,29 +180,6 @@ public abstract class AbstractPatternBasedConfigurationProducer psiFiles = new ArrayList(); - final PsiManager psiManager = PsiManager.getInstance(context.getProject()); - for (VirtualFile file : files) { - final PsiFile psiFile = psiManager.findFile(file); - if (psiFile instanceof PsiClassOwner) { - for (PsiElement psiMember : collectTestMembers(((PsiClassOwner)psiFile).getClasses(), true)) { - classes.add(((PsiClass)psiMember).getQualifiedName()); - } - psiFiles.add(psiFile); - } - } - return psiFiles.toArray(new PsiElement[psiFiles.size()]); - } - } return null; }