mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
optimize show popup for multiple selection: minimize classes processing to detect test cases (IDEA-144401)
This commit is contained in:
+11
-8
@@ -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<T extends ModuleBasedConfiguration> extends AnAction {
|
||||
@NotNull protected abstract AbstractPatternBasedConfigurationProducer<T> getPatternBasedProducer();
|
||||
@@ -46,7 +45,9 @@ public abstract class AbstractAddToTestsPatternAction<T extends ModuleBasedConfi
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final DataContext dataContext = e.getDataContext();
|
||||
final PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
|
||||
final Set<PsiElement> classes = getPatternBasedProducer().collectTestMembers(psiElements, true);
|
||||
final LinkedHashSet<PsiElement> classes = new LinkedHashSet<PsiElement>();
|
||||
PsiElementProcessor.CollectElements<PsiElement> processor = new PsiElementProcessor.CollectElements<PsiElement>(classes);
|
||||
getPatternBasedProducer().collectTestMembers(psiElements, true, true, processor);
|
||||
|
||||
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
final List<T> patternConfigurations = collectPatternConfigurations(classes, project);
|
||||
@@ -86,11 +87,13 @@ public abstract class AbstractAddToTestsPatternAction<T extends ModuleBasedConfi
|
||||
final DataContext dataContext = e.getDataContext();
|
||||
final PsiElement[] psiElements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
|
||||
if (psiElements != null) {
|
||||
final Set<PsiElement> foundMembers = getPatternBasedProducer().collectTestMembers(psiElements, true);
|
||||
if (foundMembers.isEmpty()) return;
|
||||
PsiElementProcessor.CollectElementsWithLimit<PsiElement> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiElement>(2);
|
||||
getPatternBasedProducer().collectTestMembers(psiElements, false, false, processor);
|
||||
Collection<PsiElement> collection = processor.getCollection();
|
||||
if (collection.isEmpty()) return;
|
||||
final Project project = CommonDataKeys.PROJECT.getData(dataContext);
|
||||
if (project != null) {
|
||||
final List<T> foundConfigurations = collectPatternConfigurations(foundMembers, project);
|
||||
final List<T> foundConfigurations = collectPatternConfigurations(collection, project);
|
||||
if (!foundConfigurations.isEmpty()) {
|
||||
presentation.setVisible(true);
|
||||
if (foundConfigurations.size() == 1) {
|
||||
@@ -101,7 +104,7 @@ public abstract class AbstractAddToTestsPatternAction<T extends ModuleBasedConfi
|
||||
}
|
||||
}
|
||||
|
||||
private List<T> collectPatternConfigurations(Set<PsiElement> foundClasses, Project project) {
|
||||
private List<T> collectPatternConfigurations(Collection<PsiElement> foundClasses, Project project) {
|
||||
final List<RunConfiguration> configurations = RunManager.getInstance(project).getConfigurationsList(getConfigurationType());
|
||||
final List<T> foundConfigurations = new ArrayList<T>();
|
||||
for (RunConfiguration configuration : configurations) {
|
||||
|
||||
+82
-46
@@ -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<T extends Module
|
||||
}
|
||||
|
||||
public boolean isMultipleElementsSelected(ConfigurationContext context) {
|
||||
if (TestsUIUtil.isMultipleSelectionImpossible(context.getDataContext())) return false;
|
||||
final DataContext dataContext = context.getDataContext();
|
||||
if (TestsUIUtil.isMultipleSelectionImpossible(dataContext)) return false;
|
||||
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
|
||||
final PsiElement[] elements = collectPatternElements(context, classes);
|
||||
if (elements != null && collectTestMembers(elements, false).size() > 1) {
|
||||
return true;
|
||||
final PsiElementProcessor.CollectElementsWithLimit<PsiElement> processor = new PsiElementProcessor.CollectElementsWithLimit<PsiElement>(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<String> patterns) {
|
||||
final LinkedHashSet<String> classes = new LinkedHashSet<String>();
|
||||
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<PsiElement>());
|
||||
}
|
||||
if (Comparing.equal(classes, patterns)) {
|
||||
return true;
|
||||
}
|
||||
@@ -74,43 +85,91 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
|
||||
}
|
||||
|
||||
public PsiElement checkPatterns(ConfigurationContext context, LinkedHashSet<String> 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<PsiElement> processor = new PsiElementProcessor.CollectElements<PsiElement>();
|
||||
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<PsiElement> collectTestMembers(PsiElement[] psiElements, boolean checkAbstract) {
|
||||
final Set<PsiElement> foundMembers = new LinkedHashSet<PsiElement>();
|
||||
public void collectTestMembers(PsiElement[] psiElements,
|
||||
boolean checkAbstract,
|
||||
boolean checkIsTest,
|
||||
PsiElementProcessor.CollectElements<PsiElement> 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<String> classes) {
|
||||
final DataContext dataContext = context.getDataContext();
|
||||
|
||||
private boolean collectContextElements(DataContext dataContext,
|
||||
boolean checkAbstract,
|
||||
boolean checkIsTest,
|
||||
LinkedHashSet<String> classes,
|
||||
PsiElementProcessor.CollectElements<PsiElement> 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<String> classes, DataContext dataContext) {
|
||||
final Location<?>[] locations = Location.DATA_KEYS.getData(dataContext);
|
||||
if (locations != null) {
|
||||
List<PsiElement> elements = new ArrayList<PsiElement>();
|
||||
@@ -121,29 +180,6 @@ public abstract class AbstractPatternBasedConfigurationProducer<T extends Module
|
||||
}
|
||||
return elements.toArray(new PsiElement[elements.size()]);
|
||||
}
|
||||
PsiElement[] elements = LangDataKeys.PSI_ELEMENT_ARRAY.getData(dataContext);
|
||||
if (elements != null) {
|
||||
for (PsiElement psiClass : collectTestMembers(elements, true)) {
|
||||
classes.add(getQName(psiClass));
|
||||
}
|
||||
return elements;
|
||||
} else {
|
||||
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
|
||||
if (files != null) {
|
||||
final List<PsiFile> psiFiles = new ArrayList<PsiFile>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user