IDEA-208222 Search Everywhere: Items duplicated in Files and Symbols sections

This commit is contained in:
Mikhail Sokolov
2019-03-01 14:56:37 +03:00
parent e6f9612ad6
commit 3c3705da9a
15 changed files with 169 additions and 156 deletions
@@ -1273,5 +1273,7 @@
<externalAnnotationsArtifactsResolver implementation="com.intellij.jarRepository.ExternalAnnotationsRepositoryResolver"/>
<errorQuickFixProvider implementation="com.intellij.codeInsight.daemon.impl.analysis.JavaErrorQuickFixProvider"/>
<fileTypeDetector implementation="com.intellij.openapi.fileTypes.impl.JavaFileTypeDetector"/>
<searchEverywhereResultsEqualityProvider implementation="com.intellij.ide.JavaClassAndFileEqualityProvider"/>
</extensions>
</idea-plugin>
@@ -1,39 +1,46 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.actions.searcheverywhere;
package com.intellij.ide;
import com.intellij.ide.actions.SearchEverywhereClassifier;
import com.intellij.ide.actions.searcheverywhere.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ClassAndFileEqualityProvider implements SEResultsEqualityProvider {
public class JavaClassAndFileEqualityProvider implements SEResultsEqualityProvider {
@NotNull
@Override
public Action compareItems(@NotNull SESearcher.ElementInfo newItemInfo, @NotNull SESearcher.ElementInfo alreadyFoundItemInfo) {
public SEEqualElementsActionType compareItems(@NotNull SearchEverywhereFoundElementInfo newItemInfo, @NotNull SearchEverywhereFoundElementInfo alreadyFoundItemInfo) {
PsiElement newElementPsi = PsiElementsEqualityProvider.toPsi(newItemInfo.getElement());
PsiElement alreadyFoundPsi = PsiElementsEqualityProvider.toPsi(alreadyFoundItemInfo.getElement());
if (newElementPsi == null || alreadyFoundPsi == null) {
return Action.DO_NOTHING;
return SEEqualElementsActionType.DO_NOTHING;
}
if (isClassAndFile(newItemInfo, alreadyFoundItemInfo) && isSameFile(newElementPsi, alreadyFoundPsi)) {
return newItemInfo.priority > alreadyFoundItemInfo.priority ? Action.REPLACE : Action.SKIP;
return newItemInfo.priority > alreadyFoundItemInfo.priority ? SEEqualElementsActionType.REPLACE : SEEqualElementsActionType.SKIP;
}
return Action.DO_NOTHING;
return SEEqualElementsActionType.DO_NOTHING;
}
private static boolean isClassAndFile(@NotNull SESearcher.ElementInfo newItemInfo, @NotNull SESearcher.ElementInfo alreadyFoundItemInfo) {
SearchEverywhereContributor<?> c1 = newItemInfo.getContributor();
SearchEverywhereContributor<?> c2 = alreadyFoundItemInfo.getContributor();
return c1 instanceof ClassSearchEverywhereContributor && c2 instanceof FileSearchEverywhereContributor
|| c2 instanceof ClassSearchEverywhereContributor && c1 instanceof FileSearchEverywhereContributor;
private static boolean isClassAndFile(@NotNull SearchEverywhereFoundElementInfo newItemInfo, @NotNull SearchEverywhereFoundElementInfo alreadyFoundItemInfo) {
Object newElement = newItemInfo.getElement();
Object oldElement = alreadyFoundItemInfo.getElement();
return isClass(newElement) && isFile(oldElement)
|| isClass(oldElement) && isFile(newElement);
}
private static boolean isFile(Object element) {
return element instanceof PsiFile || element instanceof VirtualFile;
}
private static boolean isClass(Object element) {
return element instanceof PsiClass;
}
private static boolean isSameFile(@NotNull PsiElement newItem, @NotNull PsiElement alreadyFound) {
@@ -20,8 +20,8 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider.Action.REPLACE;
import static com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider.Action.SKIP;
import static com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider.SEEqualElementsActionType.REPLACE;
import static com.intellij.ide.actions.searcheverywhere.SEResultsEqualityProvider.SEEqualElementsActionType.SKIP;
/**
* @author msokolov
@@ -121,7 +121,7 @@ class MultiThreadSearcher implements SESearcher {
* @return {@link ProgressIndicator} that could be used to track and/or cancel searching process
*/
@Override
public ProgressIndicator findMoreItems(@NotNull Map<? extends SearchEverywhereContributor<?>, Collection<ElementInfo>> alreadyFound,
public ProgressIndicator findMoreItems(@NotNull Map<? extends SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> alreadyFound,
@NotNull String pattern,
boolean useNonProjectItems,
@NotNull SearchEverywhereContributor<?> contributorToExpand,
@@ -236,13 +236,13 @@ class MultiThreadSearcher implements SESearcher {
}
private static abstract class ResultsAccumulator {
protected final Map<SearchEverywhereContributor<?>, Collection<ElementInfo>> sections;
protected final Map<SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> sections;
protected final MultiThreadSearcher.Listener myListener;
protected final Executor myNotificationExecutor;
protected final SEResultsEqualityProvider myEqualityProvider;
protected final ProgressIndicator myProgressIndicator;
ResultsAccumulator(Map<SearchEverywhereContributor<?>, Collection<ElementInfo>> sections,
ResultsAccumulator(Map<SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> sections,
SEResultsEqualityProvider equalityProvider,
Listener listener,
Executor notificationExecutor,
@@ -254,16 +254,18 @@ class MultiThreadSearcher implements SESearcher {
myProgressIndicator = progressIndicator;
}
protected Map<SEResultsEqualityProvider.Action, Collection<ElementInfo>> getActionsWithOtherElements(ElementInfo newElement) {
Map<SEResultsEqualityProvider.Action, Collection<ElementInfo>> res = new EnumMap<>(SEResultsEqualityProvider.Action.class);
protected Map<SEResultsEqualityProvider.SEEqualElementsActionType, Collection<SearchEverywhereFoundElementInfo>> getActionsWithOtherElements(
SearchEverywhereFoundElementInfo newElement) {
Map<SEResultsEqualityProvider.SEEqualElementsActionType, Collection<SearchEverywhereFoundElementInfo>> res = new EnumMap<>(
SEResultsEqualityProvider.SEEqualElementsActionType.class);
res.put(REPLACE, new ArrayList<>());
res.put(SKIP, new ArrayList<>());
sections.values()
.stream()
.flatMap(Collection::stream)
.forEach(info -> {
SEResultsEqualityProvider.Action action = myEqualityProvider.compareItems(newElement, info);
if (action != SEResultsEqualityProvider.Action.DO_NOTHING) {
SEResultsEqualityProvider.SEEqualElementsActionType action = myEqualityProvider.compareItems(newElement, info);
if (action != SEResultsEqualityProvider.SEEqualElementsActionType.DO_NOTHING) {
res.get(action).add(info);
}
});
@@ -289,7 +291,7 @@ class MultiThreadSearcher implements SESearcher {
private final int myNewLimit;
private volatile boolean hasMore;
ShowMoreResultsAccumulator(Map<? extends SearchEverywhereContributor<?>, Collection<ElementInfo>> alreadyFound, SEResultsEqualityProvider equalityProvider,
ShowMoreResultsAccumulator(Map<? extends SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> alreadyFound, SEResultsEqualityProvider equalityProvider,
SearchEverywhereContributor<?> contributor, int newLimit, Listener listener, Executor notificationExecutor, ProgressIndicator progressIndicator) {
super(new ConcurrentHashMap<>(alreadyFound), equalityProvider, listener, notificationExecutor, progressIndicator);
myExpandedContributor = contributor;
@@ -300,14 +302,14 @@ class MultiThreadSearcher implements SESearcher {
public boolean addElement(Object element, SearchEverywhereContributor<?> contributor, int priority, ProgressIndicator indicator) {
assert contributor == myExpandedContributor; // Only expanded contributor items allowed
Collection<ElementInfo> section = sections.get(contributor);
ElementInfo newElementInfo = new ElementInfo(element, priority, contributor);
Collection<SearchEverywhereFoundElementInfo> section = sections.get(contributor);
SearchEverywhereFoundElementInfo newElementInfo = new SearchEverywhereFoundElementInfo(element, priority, contributor);
if (section.size() >= myNewLimit) {
return false;
}
Map<SEResultsEqualityProvider.Action, Collection<ElementInfo>> otherElementsMap = getActionsWithOtherElements(newElementInfo);
Map<SEResultsEqualityProvider.SEEqualElementsActionType, Collection<SearchEverywhereFoundElementInfo>> otherElementsMap = getActionsWithOtherElements(newElementInfo);
if (otherElementsMap.get(REPLACE).isEmpty() && !otherElementsMap.get(SKIP).isEmpty()) {
LOG.debug(String.format("Element %s for contributor %s was skipped", element.toString(), contributor.getSearchProviderId()));
return true;
@@ -316,9 +318,9 @@ class MultiThreadSearcher implements SESearcher {
section.add(newElementInfo);
runInNotificationExecutor(() -> myListener.elementsAdded(Collections.singletonList(newElementInfo)));
List<ElementInfo> toRemove = new ArrayList<>(otherElementsMap.get(REPLACE));
List<SearchEverywhereFoundElementInfo> toRemove = new ArrayList<>(otherElementsMap.get(REPLACE));
toRemove.forEach(info -> {
Collection<ElementInfo> list = sections.get(info.getContributor());
Collection<SearchEverywhereFoundElementInfo> list = sections.get(info.getContributor());
list.remove(info);
LOG.debug(String.format("Element %s for contributor %s is removed", info.getElement().toString(), info.getContributor().getSearchProviderId()));
});
@@ -364,9 +366,9 @@ class MultiThreadSearcher implements SESearcher {
@Override
public boolean addElement(Object element, SearchEverywhereContributor<?> contributor, int priority, ProgressIndicator indicator) throws InterruptedException {
ElementInfo newElementInfo = new ElementInfo(element, priority, contributor);
SearchEverywhereFoundElementInfo newElementInfo = new SearchEverywhereFoundElementInfo(element, priority, contributor);
Condition condition = conditionsMap.get(contributor);
Collection<ElementInfo> section = sections.get(contributor);
Collection<SearchEverywhereFoundElementInfo> section = sections.get(contributor);
int limit = sectionsLimits.get(contributor);
lock.lock();
@@ -380,7 +382,7 @@ class MultiThreadSearcher implements SESearcher {
return false;
}
Map<SEResultsEqualityProvider.Action, Collection<ElementInfo>> otherElementsMap = getActionsWithOtherElements(newElementInfo);
Map<SEResultsEqualityProvider.SEEqualElementsActionType, Collection<SearchEverywhereFoundElementInfo>> otherElementsMap = getActionsWithOtherElements(newElementInfo);
if (otherElementsMap.get(REPLACE).isEmpty() && !otherElementsMap.get(SKIP).isEmpty()) {
LOG.debug(String.format("Element %s for contributor %s was skipped", element.toString(), contributor.getSearchProviderId()));
return true;
@@ -389,9 +391,9 @@ class MultiThreadSearcher implements SESearcher {
section.add(newElementInfo);
runInNotificationExecutor(() -> myListener.elementsAdded(Collections.singletonList(newElementInfo)));
List<ElementInfo> toRemove = new ArrayList<>(otherElementsMap.get(REPLACE));
List<SearchEverywhereFoundElementInfo> toRemove = new ArrayList<>(otherElementsMap.get(REPLACE));
toRemove.forEach(info -> {
Collection<ElementInfo> list = sections.get(info.getContributor());
Collection<SearchEverywhereFoundElementInfo> list = sections.get(info.getContributor());
Condition listCondition = conditionsMap.get(info.getContributor());
list.remove(info);
LOG.debug(String.format("Element %s for contributor %s is removed", info.getElement().toString(), info.getContributor().getSearchProviderId()));
@@ -12,19 +12,19 @@ public class PsiElementsEqualityProvider implements SEResultsEqualityProvider {
@NotNull
@Override
public Action compareItems(@NotNull SESearcher.ElementInfo newItemInfo, @NotNull SESearcher.ElementInfo alreadyFoundItemInfo) {
public SEEqualElementsActionType compareItems(@NotNull SearchEverywhereFoundElementInfo newItemInfo, @NotNull SearchEverywhereFoundElementInfo alreadyFoundItemInfo) {
PsiElement newElementPsi = toPsi(newItemInfo.getElement());
PsiElement alreadyFoundPsi = toPsi(alreadyFoundItemInfo.getElement());
if (newElementPsi == null || alreadyFoundPsi == null) {
return Action.DO_NOTHING;
return SEEqualElementsActionType.DO_NOTHING;
}
if (Objects.equals(newElementPsi, alreadyFoundPsi)) {
return newItemInfo.priority > alreadyFoundItemInfo.priority ? Action.REPLACE : Action.SKIP;
return newItemInfo.priority > alreadyFoundItemInfo.priority ? SEEqualElementsActionType.REPLACE : SEEqualElementsActionType.SKIP;
}
return Action.DO_NOTHING;
return SEEqualElementsActionType.DO_NOTHING;
}
@Nullable
@@ -12,12 +12,12 @@ public interface SEResultsEqualityProvider {
ExtensionPointName<SEResultsEqualityProvider> EP_NAME = ExtensionPointName.create("com.intellij.searchEverywhereResultsEqualityProvider");
enum Action {
enum SEEqualElementsActionType {
DO_NOTHING, SKIP, REPLACE
}
@NotNull
Action compareItems(@NotNull SESearcher.ElementInfo newItem, @NotNull SESearcher.ElementInfo alreadyFoundItem);
SEEqualElementsActionType compareItems(@NotNull SearchEverywhereFoundElementInfo newItem, @NotNull SearchEverywhereFoundElementInfo alreadyFoundItem);
@NotNull
static List<SEResultsEqualityProvider> getProviders() {
@@ -29,12 +29,12 @@ public interface SEResultsEqualityProvider {
return new SEResultsEqualityProvider() {
@NotNull
@Override
public Action compareItems(@NotNull SESearcher.ElementInfo newItem, @NotNull SESearcher.ElementInfo alreadyFoundItem) {
public SEEqualElementsActionType compareItems(@NotNull SearchEverywhereFoundElementInfo newItem, @NotNull SearchEverywhereFoundElementInfo alreadyFoundItem) {
return providers.stream()
.map(provider -> provider.compareItems(newItem, alreadyFoundItem))
.filter(action -> action != SEResultsEqualityProvider.Action.DO_NOTHING)
.filter(action -> action != SEEqualElementsActionType.DO_NOTHING)
.findFirst()
.orElse(SEResultsEqualityProvider.Action.DO_NOTHING);
.orElse(SEEqualElementsActionType.DO_NOTHING);
}
};
}
@@ -15,7 +15,7 @@ interface SESearcher {
boolean useNonProjectItems,
@NotNull Function<? super SearchEverywhereContributor<?>, ? extends SearchEverywhereContributorFilter<?>> filterSupplier);
ProgressIndicator findMoreItems(@NotNull Map<? extends SearchEverywhereContributor<?>, Collection<ElementInfo>> alreadyFound,
ProgressIndicator findMoreItems(@NotNull Map<? extends SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> alreadyFound,
@NotNull String pattern,
boolean useNonProjectItems,
@NotNull SearchEverywhereContributor<?> contributorToExpand,
@@ -26,35 +26,8 @@ interface SESearcher {
* Search process listener interface
*/
interface Listener {
void elementsAdded(@NotNull List<ElementInfo> list);
void elementsRemoved(@NotNull List<ElementInfo> list);
void elementsAdded(@NotNull List<SearchEverywhereFoundElementInfo> list);
void elementsRemoved(@NotNull List<SearchEverywhereFoundElementInfo> list);
void searchFinished(@NotNull Map<SearchEverywhereContributor<?>, Boolean> hasMoreContributors);
}
/**
* Class containing info about found elements
*/
class ElementInfo {
public final int priority;
public final Object element;
public final SearchEverywhereContributor<?> contributor;
public ElementInfo(Object element, int priority, SearchEverywhereContributor<?> contributor) {
this.priority = priority;
this.element = element;
this.contributor = contributor;
}
public int getPriority() {
return priority;
}
public Object getElement() {
return element;
}
public SearchEverywhereContributor<?> getContributor() {
return contributor;
}
}
}
@@ -0,0 +1,29 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.actions.searcheverywhere;
/**
* Class containing info about found elements
*/
public class SearchEverywhereFoundElementInfo {
public final int priority;
public final Object element;
public final SearchEverywhereContributor<?> contributor;
public SearchEverywhereFoundElementInfo(Object element, int priority, SearchEverywhereContributor<?> contributor) {
this.priority = priority;
this.element = element;
this.contributor = contributor;
}
public int getPriority() {
return priority;
}
public Object getElement() {
return element;
}
public SearchEverywhereContributor<?> getContributor() {
return contributor;
}
}
@@ -543,8 +543,8 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
}
else {
myListModel.clear();
List<SESearcher.ElementInfo> lst =
ContainerUtil.map(commands, command -> new SESearcher.ElementInfo(command, 0, stubCommandContributor));
List<SearchEverywhereFoundElementInfo> lst =
ContainerUtil.map(commands, command -> new SearchEverywhereFoundElementInfo(command, 0, stubCommandContributor));
myListModel.addElements(lst);
ScrollingUtil.ensureSelectionExists(myResultsList);
}
@@ -861,7 +861,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
private void showMoreElements(SearchEverywhereContributor contributor) {
featureTriggered(SearchEverywhereUsageTriggerCollector.MORE_ITEM_SELECTED, null);
Map<SearchEverywhereContributor<?>, Collection<SESearcher.ElementInfo>> found = myListModel.getFoundElementsMap();
Map<SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> found = myListModel.getFoundElementsMap();
int limit = myListModel.getItemsForContributor(contributor)
+ (mySelectedTab.getContributor().isPresent() ? SINGLE_CONTRIBUTOR_ELEMENTS_LIMIT : MULTIPLE_CONTRIBUTORS_ELEMENTS_LIMIT);
mySearchProgressIndicator = mySearcher.findMoreItems(found, getSearchPattern(), isUseNonProjectItems(), contributor, limit, c -> myContributorFilters.get(c.getSearchProviderId()));
@@ -1006,7 +1006,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
static final Object MORE_ELEMENT = new Object();
private final List<SESearcher.ElementInfo> listElements = new ArrayList<>();
private final List<SearchEverywhereFoundElementInfo> listElements = new ArrayList<>();
private boolean resultsExpired = false;
@@ -1044,16 +1044,16 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
.anyMatch(info -> info.getElement() == MORE_ELEMENT && info.getContributor() == contributor);
}
public void addElements(List<SESearcher.ElementInfo> items) {
public void addElements(List<SearchEverywhereFoundElementInfo> items) {
if (items.isEmpty()) {
return;
}
Map<SearchEverywhereContributor<?>, List<SESearcher.ElementInfo>> itemsMap = new HashMap<>();
Map<SearchEverywhereContributor<?>, List<SearchEverywhereFoundElementInfo>> itemsMap = new HashMap<>();
items.forEach(info -> {
List<SESearcher.ElementInfo> list = itemsMap.computeIfAbsent(info.getContributor(), contributor -> new ArrayList<>());
List<SearchEverywhereFoundElementInfo> list = itemsMap.computeIfAbsent(info.getContributor(), contributor -> new ArrayList<>());
list.add(info);
});
itemsMap.forEach((contributor, list) -> Collections.sort(list, Comparator.comparingInt(SESearcher.ElementInfo::getPriority).reversed()));
itemsMap.forEach((contributor, list) -> Collections.sort(list, Comparator.comparingInt(SearchEverywhereFoundElementInfo::getPriority).reversed()));
if (resultsExpired) {
retainContributors(itemsMap.keySet());
@@ -1062,7 +1062,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
itemsMap.forEach((contributor, list) -> {
Object[] oldItems = ArrayUtil.toObjectArray(getFoundItems(contributor));
Object[] newItems = list.stream()
.map(SESearcher.ElementInfo::getElement)
.map(SearchEverywhereFoundElementInfo::getElement)
.toArray();
try {
Diff.Change change = Diff.buildChanges(oldItems, newItems);
@@ -1085,7 +1085,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
// there were items for this contributor before update
if (startIndex >= 0) {
listElements.subList(startIndex, endIndex + 1)
.sort(Comparator.comparingInt(SESearcher.ElementInfo::getPriority).reversed());
.sort(Comparator.comparingInt(SearchEverywhereFoundElementInfo::getPriority).reversed());
fireContentsChanged(this, startIndex, endIndex);
}
});
@@ -1093,11 +1093,11 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
}
private void retainContributors(Collection<SearchEverywhereContributor<?>> retainContributors) {
Iterator<SESearcher.ElementInfo> iterator = listElements.iterator();
Iterator<SearchEverywhereFoundElementInfo> iterator = listElements.iterator();
int startInterval = 0;
int endInterval = -1;
while (iterator.hasNext()) {
SESearcher.ElementInfo item = iterator.next();
SearchEverywhereFoundElementInfo item = iterator.next();
if (retainContributors.contains(item.getContributor())) {
if (startInterval <= endInterval) {
fireIntervalRemoved(this, startInterval, endInterval);
@@ -1119,7 +1119,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
}
private void clearMoreItems() {
ListIterator<SESearcher.ElementInfo> iterator = listElements.listIterator();
ListIterator<SearchEverywhereFoundElementInfo> iterator = listElements.listIterator();
while (iterator.hasNext()) {
int index = iterator.nextIndex();
if (iterator.next().getElement() == MORE_ELEMENT) {
@@ -1131,7 +1131,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
private void applyChange(Diff.Change change,
SearchEverywhereContributor<?> contributor,
List<SESearcher.ElementInfo> newItems) {
List<SearchEverywhereFoundElementInfo> newItems) {
int firstItemIndex = contributors().indexOf(contributor);
if (firstItemIndex < 0) {
firstItemIndex = getInsertionPoint(contributor);
@@ -1147,7 +1147,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
}
if (ch.inserted > 0) {
List<SESearcher.ElementInfo> addedItems = newItems.subList(ch.line1, ch.line1 + ch.inserted);
List<SearchEverywhereFoundElementInfo> addedItems = newItems.subList(ch.line1, ch.line1 + ch.inserted);
listElements.addAll(firstItemIndex + ch.line0, addedItems);
fireIntervalAdded(this, firstItemIndex + ch.line0, firstItemIndex + ch.line0 + ch.inserted - 1);
}
@@ -1193,7 +1193,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
if (!alreadyHas && newVal) {
index += 1;
listElements.add(index, new SESearcher.ElementInfo(MORE_ELEMENT, 0, contributor));
listElements.add(index, new SearchEverywhereFoundElementInfo(MORE_ELEMENT, 0, contributor));
fireIntervalAdded(this, index, index);
}
}
@@ -1233,7 +1233,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
return last - first + 1;
}
public Map<SearchEverywhereContributor<?>, Collection<SESearcher.ElementInfo>> getFoundElementsMap() {
public Map<SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> getFoundElementsMap() {
return listElements.stream()
.filter(info -> info.element != MORE_ELEMENT)
.collect(Collectors.groupingBy(o -> o.getContributor(), Collectors.toCollection(ArrayList::new)));
@@ -1523,7 +1523,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
private class SearchListener implements SESearcher.Listener {
@Override
public void elementsAdded(@NotNull List<SESearcher.ElementInfo> list) {
public void elementsAdded(@NotNull List<SearchEverywhereFoundElementInfo> list) {
mySelectionTracker.lock();
myListModel.addElements(list);
mySelectionTracker.unlock();
@@ -1532,7 +1532,7 @@ public class SearchEverywhereUI extends BigPopupUI implements DataProvider, Quic
}
@Override
public void elementsRemoved(@NotNull List<SESearcher.ElementInfo> list) {
public void elementsRemoved(@NotNull List<SearchEverywhereFoundElementInfo> list) {
list.forEach(info -> myListModel.removeElement(info.getElement(), info.getContributor()));
}
@@ -45,7 +45,7 @@ class SingleThreadSearcher implements SESearcher {
}
@Override
public ProgressIndicator findMoreItems(@NotNull Map<? extends SearchEverywhereContributor<?>, Collection<ElementInfo>> alreadyFound,
public ProgressIndicator findMoreItems(@NotNull Map<? extends SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> alreadyFound,
@NotNull String pattern,
boolean useNonProjectItems,
@NotNull SearchEverywhereContributor<?> contributorToExpand,
@@ -63,10 +63,10 @@ class SingleThreadSearcher implements SESearcher {
int newLimit,
String pattern,
boolean useNonProjectItems,
Map<? extends SearchEverywhereContributor<?>, Collection<ElementInfo>> alreadyFound,
Map<? extends SearchEverywhereContributor<?>, Collection<SearchEverywhereFoundElementInfo>> alreadyFound,
Function<? super SearchEverywhereContributor<?>, ? extends SearchEverywhereContributorFilter<?>> filterSupplier,
ProgressIndicator indicator) {
List<ElementInfo> alreadyFoundList = alreadyFound.values()
List<SearchEverywhereFoundElementInfo> alreadyFoundList = alreadyFound.values()
.stream()
.collect(Collector.of(() -> new ArrayList<>(), (list, infos) -> list.addAll(infos), (left, right) -> {
left.addAll(right);
@@ -78,14 +78,14 @@ class SingleThreadSearcher implements SESearcher {
}
private static class UpdateInfo {
private final List<ElementInfo> addedElements = new ArrayList<>();
private final List<ElementInfo> removedElements = new ArrayList<>();
private final List<SearchEverywhereFoundElementInfo> addedElements = new ArrayList<>();
private final List<SearchEverywhereFoundElementInfo> removedElements = new ArrayList<>();
private boolean hasMore = false;
}
private static <T> UpdateInfo calculateUpdates(SearchEverywhereContributor<T> contributor, String pattern, int limit, boolean everywhere,
SearchEverywhereContributorFilter<?> filter, ProgressIndicator progressIndicator,
Collection<ElementInfo> alreadyFound, SEResultsEqualityProvider equalityProvider) {
Collection<SearchEverywhereFoundElementInfo> alreadyFound, SEResultsEqualityProvider equalityProvider) {
UpdateInfo res = new UpdateInfo();
contributor.fetchElements(pattern, everywhere, (SearchEverywhereContributorFilter<T>) filter, progressIndicator, newElement -> {
@@ -99,7 +99,7 @@ class SingleThreadSearcher implements SESearcher {
}
int priority = contributor.getElementPriority(newElement, pattern);
ElementInfo newInfo = new ElementInfo(newElement, priority, contributor);
SearchEverywhereFoundElementInfo newInfo = new SearchEverywhereFoundElementInfo(newElement, priority, contributor);
boolean shouldBeAdded = processSameElements(newInfo, alreadyFound, res, equalityProvider);
if (!shouldBeAdded) {
return true;
@@ -116,19 +116,20 @@ class SingleThreadSearcher implements SESearcher {
/**
* @return true if new element should be added to result or false if it should be skipped
*/
private static boolean processSameElements(ElementInfo newInfo, Collection<ElementInfo> alreadyFound, UpdateInfo res, SEResultsEqualityProvider equalityProvider) {
Map<SEResultsEqualityProvider.Action, Collection<ElementInfo>> sameItemsMap = new EnumMap<>(SEResultsEqualityProvider.Action.class);
sameItemsMap.put(SEResultsEqualityProvider.Action.SKIP, new ArrayList<>());
sameItemsMap.put(SEResultsEqualityProvider.Action.REPLACE, new ArrayList<>());
private static boolean processSameElements(SearchEverywhereFoundElementInfo newInfo, Collection<SearchEverywhereFoundElementInfo> alreadyFound, UpdateInfo res, SEResultsEqualityProvider equalityProvider) {
Map<SEResultsEqualityProvider.SEEqualElementsActionType, Collection<SearchEverywhereFoundElementInfo>> sameItemsMap = new EnumMap<>(
SEResultsEqualityProvider.SEEqualElementsActionType.class);
sameItemsMap.put(SEResultsEqualityProvider.SEEqualElementsActionType.SKIP, new ArrayList<>());
sameItemsMap.put(SEResultsEqualityProvider.SEEqualElementsActionType.REPLACE, new ArrayList<>());
alreadyFound.forEach(info -> {
SEResultsEqualityProvider.Action action = equalityProvider.compareItems(newInfo, info);
if (action != SEResultsEqualityProvider.Action.DO_NOTHING) {
SEResultsEqualityProvider.SEEqualElementsActionType action = equalityProvider.compareItems(newInfo, info);
if (action != SEResultsEqualityProvider.SEEqualElementsActionType.DO_NOTHING) {
sameItemsMap.get(action).add(info);
}
});
Collection<ElementInfo> toReplace = sameItemsMap.get(SEResultsEqualityProvider.Action.REPLACE);
Collection<SearchEverywhereFoundElementInfo> toReplace = sameItemsMap.get(SEResultsEqualityProvider.SEEqualElementsActionType.REPLACE);
if (!toReplace.isEmpty()) {
toReplace.forEach(info -> {
res.removedElements.add(info);
@@ -137,7 +138,7 @@ class SingleThreadSearcher implements SESearcher {
return true;
}
return sameItemsMap.get(SEResultsEqualityProvider.Action.SKIP).isEmpty();
return sameItemsMap.get(SEResultsEqualityProvider.SEEqualElementsActionType.SKIP).isEmpty();
}
private static class SearchTask implements Runnable {
@@ -172,7 +173,7 @@ class SingleThreadSearcher implements SESearcher {
@Override
public void run() {
Map<SearchEverywhereContributor<?>, Boolean> hasMoreContributors = new HashMap<>();
Collection<ElementInfo> alreadyFound = new ArrayList<>();
Collection<SearchEverywhereFoundElementInfo> alreadyFound = new ArrayList<>();
myContributorsAndLimits.entrySet()
.stream()
@@ -196,7 +197,7 @@ class SingleThreadSearcher implements SESearcher {
private final String myPattern;
private final boolean myUseNonProjectItems;
private final SearchEverywhereContributorFilter<F> myFilter;
private final List<ElementInfo> myAlreadyFound;
private final List<SearchEverywhereFoundElementInfo> myAlreadyFound;
private final ProgressIndicator myProgressIndicator;
private final Executor notificationExecutor;
@@ -208,7 +209,7 @@ class SingleThreadSearcher implements SESearcher {
String pattern,
boolean useNonProjectItems,
SearchEverywhereContributorFilter<F> filter,
List<ElementInfo> alreadyFound,
List<SearchEverywhereFoundElementInfo> alreadyFound,
ProgressIndicator indicator,
Executor executor,
Listener listener,
@@ -23,7 +23,7 @@ class ThrottlingListenerWrapper implements MultiThreadSearcher.Listener {
private final Executor myDelegateExecutor;
private final Buffer myBuffer = new Buffer();
private final BiConsumer<List<SESearcher.ElementInfo>, List<SESearcher.ElementInfo>> myFlushConsumer;
private final BiConsumer<List<SearchEverywhereFoundElementInfo>, List<SearchEverywhereFoundElementInfo>> myFlushConsumer;
private final Alarm flushAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
private boolean flushScheduled;
@@ -50,14 +50,14 @@ class ThrottlingListenerWrapper implements MultiThreadSearcher.Listener {
}
@Override
public void elementsAdded(@NotNull List<SESearcher.ElementInfo> list) {
public void elementsAdded(@NotNull List<SearchEverywhereFoundElementInfo> list) {
ApplicationManager.getApplication().assertIsDispatchThread();
myBuffer.addEvent(new Event(Event.ADD, list));
scheduleFlushBuffer();
}
@Override
public void elementsRemoved(@NotNull List<SESearcher.ElementInfo> list) {
public void elementsRemoved(@NotNull List<SearchEverywhereFoundElementInfo> list) {
ApplicationManager.getApplication().assertIsDispatchThread();
myBuffer.addEvent(new Event(Event.REMOVE, list));
scheduleFlushBuffer();
@@ -98,9 +98,9 @@ class ThrottlingListenerWrapper implements MultiThreadSearcher.Listener {
static final int ADD = 1;
final int type;
final List<SESearcher.ElementInfo> items;
final List<SearchEverywhereFoundElementInfo> items;
Event(int type, List<SESearcher.ElementInfo> items) {
Event(int type, List<SearchEverywhereFoundElementInfo> items) {
this.type = type;
this.items = items;
}
@@ -113,9 +113,9 @@ class ThrottlingListenerWrapper implements MultiThreadSearcher.Listener {
myQueue.add(event);
}
public void flush(BiConsumer<List<SESearcher.ElementInfo>, List<SESearcher.ElementInfo>> consumer) {
List<SESearcher.ElementInfo> added = new ArrayList<>();
List<SESearcher.ElementInfo> removed = new ArrayList<>();
public void flush(BiConsumer<List<SearchEverywhereFoundElementInfo>, List<SearchEverywhereFoundElementInfo>> consumer) {
List<SearchEverywhereFoundElementInfo> added = new ArrayList<>();
List<SearchEverywhereFoundElementInfo> removed = new ArrayList<>();
myQueue.forEach(event -> {
if (event.type == Event.ADD) {
added.addAll(event.items);
@@ -9,10 +9,10 @@ public class TrivialElementsEqualityProvider implements SEResultsEqualityProvide
@NotNull
@Override
public Action compareItems(@NotNull SESearcher.ElementInfo newItem, @NotNull SESearcher.ElementInfo alreadyFoundItem) {
public SEEqualElementsActionType compareItems(@NotNull SearchEverywhereFoundElementInfo newItem, @NotNull SearchEverywhereFoundElementInfo alreadyFoundItem) {
if (Objects.equals(newItem.getElement(), alreadyFoundItem.getElement())) {
return newItem.getPriority() > alreadyFoundItem.getPriority() ? Action.REPLACE : Action.SKIP;
return newItem.getPriority() > alreadyFoundItem.getPriority() ? SEEqualElementsActionType.REPLACE : SEEqualElementsActionType.SKIP;
}
return Action.DO_NOTHING;
return SEEqualElementsActionType.DO_NOTHING;
}
}
@@ -125,7 +125,7 @@ public class MultiThreadSearchDeadlockTest extends LightPlatformCodeInsightFixtu
private final CountDownLatch latch = new CountDownLatch(1);
@Override
public void elementsAdded(@NotNull List<SESearcher.ElementInfo> list) {
public void elementsAdded(@NotNull List<SearchEverywhereFoundElementInfo> list) {
list.forEach(info -> {
List<Object> section = resultsMap.computeIfAbsent(info.getContributor().getSearchProviderId(), s -> new ArrayList<>());
section.add(info.getElement());
@@ -133,7 +133,7 @@ public class MultiThreadSearchDeadlockTest extends LightPlatformCodeInsightFixtu
}
@Override
public void elementsRemoved(@NotNull List<SESearcher.ElementInfo> list) {
public void elementsRemoved(@NotNull List<SearchEverywhereFoundElementInfo> list) {
list.forEach(info -> {
List<Object> section = resultsMap.computeIfAbsent(info.getContributor().getSearchProviderId(), s -> new ArrayList<>());
section.remove(info.getElement());
@@ -440,7 +440,7 @@ public class MultiThreadSearchTest extends LightPlatformCodeInsightFixtureTestCa
}
@Override
public void elementsAdded(@NotNull List<SESearcher.ElementInfo> added) {
public void elementsAdded(@NotNull List<SearchEverywhereFoundElementInfo> added) {
added.forEach(info -> {
List<String> list = myMap.computeIfAbsent(info.getContributor().getSearchProviderId(), s -> new ArrayList<>());
list.add((String) info.getElement());
@@ -448,7 +448,7 @@ public class MultiThreadSearchTest extends LightPlatformCodeInsightFixtureTestCa
}
@Override
public void elementsRemoved(@NotNull List<SESearcher.ElementInfo> removed) {
public void elementsRemoved(@NotNull List<SearchEverywhereFoundElementInfo> removed) {
removed.forEach(info -> {
List<String> list = myMap.get(info.getContributor().getSearchProviderId());
Assert.assertNotNull("Trying to remove object, that wasn't added", list);
@@ -26,15 +26,15 @@ public class SearchModelTest extends LightPlatformCodeInsightFixtureTestCase {
// adding to empty -----------------------------------------------------------------------
model.addElements(Arrays.asList(
new SESearcher.ElementInfo("item_2_20", 250, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_3_20", 340, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_1_20", 160, STUB_CONTRIBUTOR_1),
new SESearcher.ElementInfo("item_3_30", 330, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_2_10", 280, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_1_10", 180, STUB_CONTRIBUTOR_1),
new SESearcher.ElementInfo("item_2_30", 230, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_3_10", 350, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_1_30", 140, STUB_CONTRIBUTOR_1)
new SearchEverywhereFoundElementInfo("item_2_20", 250, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_3_20", 340, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_1_20", 160, STUB_CONTRIBUTOR_1),
new SearchEverywhereFoundElementInfo("item_3_30", 330, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_2_10", 280, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_1_10", 180, STUB_CONTRIBUTOR_1),
new SearchEverywhereFoundElementInfo("item_2_30", 230, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_3_10", 350, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_1_30", 140, STUB_CONTRIBUTOR_1)
));
List<Object> actualItems = model.getItems();
@@ -53,16 +53,16 @@ public class SearchModelTest extends LightPlatformCodeInsightFixtureTestCase {
// adding to existing -----------------------------------------------------------------------
model.addElements(Arrays.asList(
new SESearcher.ElementInfo("item_3_03", 370, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_2_23", 250, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_1_35", 130, STUB_CONTRIBUTOR_1),
new SESearcher.ElementInfo("item_2_25", 245, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_1_25", 150, STUB_CONTRIBUTOR_1),
new SESearcher.ElementInfo("item_3_50", 310, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_2_40", 210, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_3_40", 320, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_2_05", 290, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_3_05", 360, STUB_CONTRIBUTOR_3)
new SearchEverywhereFoundElementInfo("item_3_03", 370, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_2_23", 250, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_1_35", 130, STUB_CONTRIBUTOR_1),
new SearchEverywhereFoundElementInfo("item_2_25", 245, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_1_25", 150, STUB_CONTRIBUTOR_1),
new SearchEverywhereFoundElementInfo("item_3_50", 310, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_2_40", 210, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_3_40", 320, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_2_05", 290, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_3_05", 360, STUB_CONTRIBUTOR_3)
));
actualItems = model.getItems();
@@ -74,16 +74,16 @@ public class SearchModelTest extends LightPlatformCodeInsightFixtureTestCase {
// expiring results -----------------------------------------------------------------------
model.expireResults();
model.addElements(Arrays.asList(
new SESearcher.ElementInfo("item_3_50", 310, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_1_20", 160, STUB_CONTRIBUTOR_1),
new SESearcher.ElementInfo("item_3_10", 350, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_2_23", 250, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_3_30", 330, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_2_05", 290, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_2_10", 280, STUB_CONTRIBUTOR_2),
new SESearcher.ElementInfo("item_1_35", 130, STUB_CONTRIBUTOR_1),
new SESearcher.ElementInfo("item_3_20", 340, STUB_CONTRIBUTOR_3),
new SESearcher.ElementInfo("item_1_25", 150, STUB_CONTRIBUTOR_1)
new SearchEverywhereFoundElementInfo("item_3_50", 310, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_1_20", 160, STUB_CONTRIBUTOR_1),
new SearchEverywhereFoundElementInfo("item_3_10", 350, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_2_23", 250, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_3_30", 330, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_2_05", 290, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_2_10", 280, STUB_CONTRIBUTOR_2),
new SearchEverywhereFoundElementInfo("item_1_35", 130, STUB_CONTRIBUTOR_1),
new SearchEverywhereFoundElementInfo("item_3_20", 340, STUB_CONTRIBUTOR_3),
new SearchEverywhereFoundElementInfo("item_1_25", 150, STUB_CONTRIBUTOR_1)
));
model.setHasMore(STUB_CONTRIBUTOR_1, true);
model.setHasMore(STUB_CONTRIBUTOR_2, true);
@@ -1154,7 +1154,6 @@
<searchEverywhereResultsEqualityProvider implementation="com.intellij.ide.actions.searcheverywhere.TrivialElementsEqualityProvider"/>
<searchEverywhereResultsEqualityProvider implementation="com.intellij.ide.actions.searcheverywhere.PsiElementsEqualityProvider"/>
<searchEverywhereResultsEqualityProvider implementation="com.intellij.ide.actions.searcheverywhere.ClassAndFileEqualityProvider"/>
<projectService serviceImplementation="com.intellij.ide.actions.runAnything.RunAnythingCache"/>