diff --git a/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/EssentialContributor.java b/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/EssentialContributor.java new file mode 100644 index 000000000000..e9d847f6b835 --- /dev/null +++ b/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/EssentialContributor.java @@ -0,0 +1,18 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.ide.actions.searcheverywhere; + +/** + * This is marker interface for an Essential Contributor. During the search process, it is guaranteed + * that results are not displayed until all contributions marked as Essential have returned items + * (or have completed processing with no results). + */ +public interface EssentialContributor { + + default boolean isEssential() { + return true; + } + + static boolean checkEssential(SearchEverywhereContributor contributor) { + return (contributor instanceof EssentialContributor ic) && ic.isEssential(); + } +} diff --git a/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/PossibleSlowContributor.java b/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/PossibleSlowContributor.java index 827f62510deb..9c81251597d2 100644 --- a/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/PossibleSlowContributor.java +++ b/platform/lang-api/src/com/intellij/ide/actions/searcheverywhere/PossibleSlowContributor.java @@ -1,6 +1,14 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.actions.searcheverywhere; +/** + * This marker interface represents contributors that may process items slowly. The search process can start + * displaying initial results without waiting for input from such contributors. + * + * Currently, this interface is not in use. By default, all contributors are + * assumed slow unless they are explicitly marked as an {@link EssentialContributor}. + * Nevertheless, this interface may be repurposed and applied for enhanced checks in the future. + */ public interface PossibleSlowContributor { default boolean isSlow() { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/ClassSearchEverywhereContributor.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/ClassSearchEverywhereContributor.java index 7c0247c561ab..b641feb00b5d 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/ClassSearchEverywhereContributor.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/ClassSearchEverywhereContributor.java @@ -41,7 +41,7 @@ import static com.intellij.ide.actions.searcheverywhere.footer.ExtendedInfoImplK /** * @author Konstantin Bulenkov */ -public class ClassSearchEverywhereContributor extends AbstractGotoSEContributor { +public class ClassSearchEverywhereContributor extends AbstractGotoSEContributor implements EssentialContributor { private static final Pattern ourPatternToDetectMembers = Pattern.compile("(.+)(#)(.*)"); private final PersistentSearchEverywhereContributorFilter filter; diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/FileSearchEverywhereContributor.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/FileSearchEverywhereContributor.java index cd0c340d1c59..fc2b287a8334 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/FileSearchEverywhereContributor.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/FileSearchEverywhereContributor.java @@ -41,7 +41,7 @@ import static com.intellij.ide.actions.searcheverywhere.footer.ExtendedInfoImplK * @author Konstantin Bulenkov * @author Mikhail Sokolov */ -public class FileSearchEverywhereContributor extends AbstractGotoSEContributor { +public class FileSearchEverywhereContributor extends AbstractGotoSEContributor implements EssentialContributor { private static final Logger LOG = Logger.getInstance(FileSearchEverywhereContributor.class); private final GotoFileModel myModelForRenderer; private final PersistentSearchEverywhereContributorFilter myFilter; diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/PSIPresentationBgRendererWrapper.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/PSIPresentationBgRendererWrapper.java index ae75fa8ae386..34c51739ef34 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/PSIPresentationBgRendererWrapper.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/PSIPresentationBgRendererWrapper.java @@ -33,7 +33,7 @@ import java.util.List; import java.util.function.Function; public final class PSIPresentationBgRendererWrapper implements WeightedSearchEverywhereContributor, ScopeSupporting, - AutoCompletionContributor, PossibleSlowContributor, + AutoCompletionContributor, PossibleSlowContributor, EssentialContributor, SearchEverywhereExtendedInfoProvider { private final AbstractGotoSEContributor myDelegate; @@ -51,6 +51,11 @@ public final class PSIPresentationBgRendererWrapper implements WeightedSearchEve return PossibleSlowContributor.checkSlow(myDelegate); } + @Override + public boolean isEssential() { + return EssentialContributor.checkEssential(myDelegate); + } + public static WeightedSearchEverywhereContributor wrapIfNecessary(AbstractGotoSEContributor delegate) { if (Registry.is("psi.element.list.cell.renderer.background")) { return new PSIPresentationBgRendererWrapper(delegate); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SlowContributorDetector.kt b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SlowContributorDetector.kt index c5a6be58f2a0..5a78bea3356f 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SlowContributorDetector.kt +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SlowContributorDetector.kt @@ -57,7 +57,7 @@ class SlowContributorDetector: SearchListener { private fun logContributorFinished(contributor: SearchEverywhereContributor<*>) { if (finishedContributors.containsKey(contributor.searchProviderId)) return - if (PossibleSlowContributor.checkSlow(contributor)) return //don't worry about contributors already marked as slow + if (!EssentialContributor.checkEssential(contributor)) return //don't worry about contributors which are not essential finishedContributors[contributor.searchProviderId] = System.currentTimeMillis() - startTimestamp!! } @@ -81,7 +81,7 @@ class SlowContributorDetector: SearchListener { private fun reportSlowContributor(id: String, delay: Long) { - LOG.warn("Contributor [$id] is too slow (took $delay ms to finish). Slow contributors should implement PossibleSlowContributor interface") + LOG.warn("Contributor [$id] is too slow (took $delay ms to finish). But it is marked as EssentialContributor and can slow down the search process") } private fun calculatePercentileEdge(delays: Collection): Long { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/WaitForContributorsListenerWrapper.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/WaitForContributorsListenerWrapper.java index 8a805a8af491..5138cfe1f07b 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/WaitForContributorsListenerWrapper.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/WaitForContributorsListenerWrapper.java @@ -150,7 +150,7 @@ public final class WaitForContributorsListenerWrapper implements SearchListener, cancelAllFlushTasks(); buffer.clearBuffer(); Map, Boolean> map = contributors.stream() - .filter(c -> !PossibleSlowContributor.checkSlow(c)) + .filter(EssentialContributor::checkEssential) .collect(Collectors.toMap(Function.identity(), c -> false)); contributorsMap.clear(); contributorsMap.putAll(map); diff --git a/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SETestUtil.kt b/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SETestUtil.kt index 34a59447625b..d9b56c7f5286 100644 --- a/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SETestUtil.kt +++ b/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SETestUtil.kt @@ -6,8 +6,8 @@ import com.intellij.util.Processor import javax.swing.JPanel import javax.swing.ListCellRenderer -fun createDumbContributor(id: String, showTab: Boolean = false, slow: Boolean = false): SearchEverywhereContributor = - object : SearchEverywhereContributor, PossibleSlowContributor { +fun createDumbContributor(id: String, showTab: Boolean = false, essential: Boolean = false): SearchEverywhereContributor = + object : SearchEverywhereContributor, EssentialContributor { override fun getSearchProviderId(): String = id override fun getGroupName(): String = id override fun getSortWeight(): Int = 0 @@ -18,7 +18,7 @@ fun createDumbContributor(id: String, showTab: Boolean = false, slow: Boolean = override fun processSelectedItem(selected: Unit, modifiers: Int, searchText: String): Boolean = false override fun fetchElements(pattern: String, progressIndicator: ProgressIndicator, consumer: Processor) {} - override fun isSlow(): Boolean = slow + override fun isEssential(): Boolean = essential override fun toString(): String = id } \ No newline at end of file diff --git a/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SearchBufferedListenersTest.kt b/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SearchBufferedListenersTest.kt index a6fb066463c7..b5f6fb94de9a 100644 --- a/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SearchBufferedListenersTest.kt +++ b/platform/lang-impl/testSources/com/intellij/ide/actions/searcheverywhere/SearchBufferedListenersTest.kt @@ -20,9 +20,9 @@ class SearchBufferedListenersTest : BasePlatformTestCase() { private var myMockery: Mockery? = null - private val contributor1 = createDumbContributor("Test1") - private val contributor2 = createDumbContributor("Test2") - private val contributor3 = createDumbContributor("Test3(slow)", slow = true) + private val contributor1 = createDumbContributor("Test1", essential = true) + private val contributor2 = createDumbContributor("Test2", essential = true) + private val contributor3 = createDumbContributor("Test3(slow)") private val c1_e1 = SearchEverywhereFoundElementInfoTest("c1_e1", contributor1) private val c1_e2 = SearchEverywhereFoundElementInfoTest("c1_e2", contributor1)