From c06a2a961f1e5c237abc8196fd099311997a888b Mon Sep 17 00:00:00 2001 From: Iurii Akatov Date: Fri, 7 Jun 2024 20:21:29 +0000 Subject: [PATCH] ML4SE-698 Implement features in plugin - Added new plugin to collect initial data for future Federated Compute model - Based on https://jetbrains.team/p/ij/reviews/133737/timeline Merge-request: IJ-MR-135570 Merged-by: Iurii Akatov GitOrigin-RevId: b2bff07b4abcf82198564707809cb56379d0084f --- .../messages/ApplicationBundle.properties | 2 + .../SearchEverywhereMlService.kt | 3 +- .../searcheverywhere/SearchEverywhereUI.java | 2 +- .../impl/logs/ComponentAsFusEventRegister.kt | 41 +++++++++++++++++-- .../platform/ml/impl/logs/eventFields.kt | 11 ++++- .../advanced/AdvancedSettingsConfigurable.kt | 2 + .../src/META-INF/PlatformExtensions.xml | 1 + .../core/SearchEverywhereMlRankingService.kt | 3 +- .../SearchEverywhereItemSelectedListener.kt | 3 +- .../SearchEverywhereMlServiceImpl.kt | 7 ++-- 10 files changed, 62 insertions(+), 13 deletions(-) diff --git a/platform/ide-core/resources/messages/ApplicationBundle.properties b/platform/ide-core/resources/messages/ApplicationBundle.properties index be2d4bf6f83f..d7186082174b 100644 --- a/platform/ide-core/resources/messages/ApplicationBundle.properties +++ b/platform/ide-core/resources/messages/ApplicationBundle.properties @@ -910,6 +910,8 @@ advanced.setting.search.everywhere.wait.for.contributors.description=Enabling th advanced.setting.search.everywhere.contributors.wait.timeout=Contributors waiting timeout (ms) advanced.setting.search.everywhere.recent.at.top=Show recent files at the top of results list advanced.setting.search.everywhere.recent.at.top.description=When enabled, recent files are always displayed at the top of the results list. Therefore, even if these files match the search pattern less precisely than other results, they will remain at the top. +advanced.setting.search.everywhere.send.search.history.statistics=Contribute anonymous data for Federated Compute project research +advanced.setting.search.everywhere.send.search.history.statistics.description=By enabling this option, you, as a JetBrains employee, agree to provide anonymous data for research in the Federated Compute project. This process will only involve JetBrains employees from the @jetbrains.com domain. Please note that this data will be used responsibly for enhancing the system and overall user experience. advanced.setting.floating.codeToolbar.hide=Hide floating toolbar for code editing group.advanced.settings.other=Other group.advanced.settings.ide=IDE diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereMlService.kt b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereMlService.kt index 00f9462a334d..21238e9546b5 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereMlService.kt +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereMlService.kt @@ -54,7 +54,8 @@ interface SearchEverywhereMlService { fun onItemSelected(project: Project?, tabId: String, indexes: IntArray, selectedItems: List, elementsProvider: () -> List, - closePopup: Boolean) + closePopup: Boolean, + query: String) fun onSearchFinished(project: Project?, elementsProvider: () -> List) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java index 2ca652298df5..a15810553b6c 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/searcheverywhere/SearchEverywhereUI.java @@ -1334,7 +1334,7 @@ public final class SearchEverywhereUI extends BigPopupUI implements DataProvider if (myMlService != null) { var tabId = myHeader.getSelectedTab().getID(); - myMlService.onItemSelected(myProject, tabId, indexes, selectedItems, () -> myListModel.getFoundElementsInfo(), closePopup); + myMlService.onItemSelected(myProject, tabId, indexes, selectedItems, () -> myListModel.getFoundElementsInfo(), closePopup, searchText); } if (closePopup) { diff --git a/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/ComponentAsFusEventRegister.kt b/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/ComponentAsFusEventRegister.kt index e5647904cb41..4a7bdc6191af 100644 --- a/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/ComponentAsFusEventRegister.kt +++ b/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/ComponentAsFusEventRegister.kt @@ -29,6 +29,7 @@ import com.intellij.internal.statistic.eventLog.events.ObjectEventData as IJObje import com.intellij.internal.statistic.eventLog.events.ObjectEventField as IJObjectEventField import com.intellij.internal.statistic.eventLog.events.ObjectListEventField as IJObjectListEventField import com.intellij.internal.statistic.eventLog.events.StringEventField as IJStringEventField +import com.intellij.platform.ml.impl.logs.CustomEventField as MLCustomEventField import com.intellij.platform.ml.impl.logs.LanguageEventField as MLLanguageEventField import com.intellij.platform.ml.impl.logs.VersionEventField as MLVersionEventField import com.intellij.platform.ml.logs.schema.BooleanEventField as MLBooleanEventField @@ -68,7 +69,11 @@ class ComponentAsFusEventRegister(private val baseEventGroup: IJEventLogGroup) : @Suppress("UNCHECKED_CAST") private fun createConverter(mlEventField: MLEventField): IJEventPairConverter = when (mlEventField) { - is MLObjectEventField -> ConverterOfObject(mlEventField.name, mlEventField.description, mlEventField.objectDescription) as IJEventPairConverter + is MLObjectEventField -> ConverterOfObject( + mlEventField.name, + mlEventField.description, + mlEventField.objectDescription + ) as IJEventPairConverter is MLBooleanEventField -> ConverterOfPrimitiveType(mlEventField) { n, d -> IJBooleanEventField(n, d) } as IJEventPairConverter is MLIntEventField -> ConverterOfPrimitiveType(mlEventField) { n, d -> IJIntEventField(n, d) } as IJEventPairConverter is MLLongEventField -> ConverterOfPrimitiveType(mlEventField) { n, d -> IJLongEventField(n, d) } as IJEventPairConverter @@ -80,11 +85,38 @@ private fun createConverter(mlEventField: MLEventField): IJEventPairConve is MLVersionEventField -> ConverterOfVersion(mlEventField) as IJEventPairConverter is MLLanguageEventField -> ConverterOfLanguage(mlEventField) as IJEventPairConverter is MLStringEventField -> ConverterOfString(mlEventField) as IJEventPairConverter - else -> throw NotImplementedError("Implement converter for the ${mlEventField.javaClass.simpleName}") + + is IJSpecificEventField<*> -> { + when (mlEventField) { + is MLCustomEventField -> ConverterOfCustom(mlEventField) + is MLLanguageEventField -> ConverterOfLanguage(mlEventField) as IJEventPairConverter + is MLVersionEventField -> ConverterOfVersion(mlEventField) as IJEventPairConverter + } + } + + else -> throw IllegalArgumentException( + """ + Conversion of ${mlEventField.javaClass.simpleName} is not possible. + If you want to create your own field, you must add an inheritor of + ${MLCustomEventField::class.qualifiedName} + """.trimIndent() + ) +} + +private class ConverterOfCustom(mlEventField: MLCustomEventField) : IJEventPairConverter { + override val ijEventField: IJEventField = mlEventField.baseIJEventField + + override fun buildEventPair(mlEventPair: EventPair): IJEventPair { + return ijEventField with mlEventPair.data + } } private class ConverterOfString(mlEventField: MLStringEventField) : IJEventPairConverter { - override val ijEventField: IJEventField = IJStringEventField.ValidatedByAllowedValues(mlEventField.name, allowedValues = mlEventField.possibleValues, description = mlEventField.description) + override val ijEventField: IJEventField = IJStringEventField.ValidatedByAllowedValues( + mlEventField.name, + allowedValues = mlEventField.possibleValues, + description = mlEventField.description + ) override fun buildEventPair(mlEventPair: EventPair): IJEventPair { return ijEventField with mlEventPair.data @@ -116,7 +148,8 @@ private class ConverterOfVersion(mlEventField: MLVersionEventField) : IJEventPai } } -private class ConvertObjectList(mlEventField: MLObjectListEventField) : IJEventPairConverter, List> { +private class ConvertObjectList(mlEventField: MLObjectListEventField) : + IJEventPairConverter, List> { private val innerObjectConverter = ConverterOfObject(mlEventField.name, mlEventField.description, mlEventField.internalObjectDescription) // FIXME: description is not passed diff --git a/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/eventFields.kt b/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/eventFields.kt index 5a3a3d8e8f37..413d81d81c1d 100644 --- a/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/eventFields.kt +++ b/platform/ml-impl/src/com/intellij/platform/ml/impl/logs/eventFields.kt @@ -5,9 +5,16 @@ import com.intellij.lang.Language import com.intellij.openapi.util.Version import com.intellij.platform.ml.logs.schema.CustomRuleEventField import org.jetbrains.annotations.ApiStatus +import com.intellij.internal.statistic.eventLog.events.EventField as IJEventField @ApiStatus.Internal -class VersionEventField(name: String, description: String?) : CustomRuleEventField(name, description) +sealed class IJSpecificEventField(name: String, description: String?) : CustomRuleEventField(name, description) @ApiStatus.Internal -class LanguageEventField(name: String, description: String?) : CustomRuleEventField(name, description) +class VersionEventField(name: String, description: String?) : IJSpecificEventField(name, description) + +@ApiStatus.Internal +class LanguageEventField(name: String, description: String?) : IJSpecificEventField(name, description) + +@ApiStatus.Internal +open class CustomEventField(val baseIJEventField: IJEventField) : IJSpecificEventField(baseIJEventField.name, baseIJEventField.description) diff --git a/platform/platform-impl/src/com/intellij/openapi/options/advanced/AdvancedSettingsConfigurable.kt b/platform/platform-impl/src/com/intellij/openapi/options/advanced/AdvancedSettingsConfigurable.kt index 945853981e9f..17c6ffbb879a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/options/advanced/AdvancedSettingsConfigurable.kt +++ b/platform/platform-impl/src/com/intellij/openapi/options/advanced/AdvancedSettingsConfigurable.kt @@ -7,6 +7,7 @@ import com.intellij.ide.ui.search.SearchableOptionsRegistrar import com.intellij.internal.statistic.collectors.fus.ui.SettingsCounterUsagesCollector import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.application.ApplicationBundle +import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.options.Configurable import com.intellij.openapi.options.DslConfigurableBase import com.intellij.openapi.options.SearchableConfigurable @@ -154,6 +155,7 @@ class AdvancedSettingsConfigurable : DslConfigurableBase(), SearchableConfigurab private fun AdvancedSettingBean.isApplicable(): Boolean = when (id) { "project.view.do.not.autoscroll.to.libraries" -> !ProjectJdkTable.getInstance().allJdks.isEmpty() + "search.everywhere.send.search.history.statistics" -> ApplicationManager.getApplication().isEAP && ApplicationManager.getApplication().isInternal else -> true } diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index e540d1e58b0d..8fbc820c34ee 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -1632,6 +1632,7 @@ + diff --git a/plugins/search-everywhere-ml/ranking/core/src/com/intellij/searchEverywhereMl/ranking/core/SearchEverywhereMlRankingService.kt b/plugins/search-everywhere-ml/ranking/core/src/com/intellij/searchEverywhereMl/ranking/core/SearchEverywhereMlRankingService.kt index c52881485ae1..92885e562996 100644 --- a/plugins/search-everywhere-ml/ranking/core/src/com/intellij/searchEverywhereMl/ranking/core/SearchEverywhereMlRankingService.kt +++ b/plugins/search-everywhere-ml/ranking/core/src/com/intellij/searchEverywhereMl/ranking/core/SearchEverywhereMlRankingService.kt @@ -143,7 +143,8 @@ class SearchEverywhereMlRankingService : SearchEverywhereMlService { override fun onItemSelected(project: Project?, tabId: String, indexes: IntArray, selectedItems: List, elementsProvider: () -> List, - closePopup: Boolean) { + closePopup: Boolean, + query: String) { getCurrentSession()?.onItemSelected(project, experiment, indexes, selectedItems, closePopup, mapElementsProvider(elementsProvider)) } diff --git a/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereItemSelectedListener.kt b/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereItemSelectedListener.kt index eb90107adf17..738755e281cd 100644 --- a/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereItemSelectedListener.kt +++ b/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereItemSelectedListener.kt @@ -9,5 +9,6 @@ interface SearchEverywhereItemSelectedListener { indexes: IntArray, selectedItems: List, elementsProvider: () -> List, - closePopup: Boolean) + closePopup: Boolean, + query: String) } diff --git a/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereMlServiceImpl.kt b/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereMlServiceImpl.kt index d7fbb63e3d02..c380f97fe332 100644 --- a/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereMlServiceImpl.kt +++ b/plugins/search-everywhere-ml/src/com/intellij/searchEverywhereMl/SearchEverywhereMlServiceImpl.kt @@ -21,8 +21,9 @@ class SearchEverywhereMlServiceImpl : SearchEverywhereMlService by RANKING_SERVI indexes: IntArray, selectedItems: List, elementsProvider: () -> List, - closePopup: Boolean) { - RANKING_SERVICE.onItemSelected(project, tabId, indexes, selectedItems, elementsProvider, closePopup) - ITEM_SELECTED_LISTENERS.forEach { it.onItemSelected(project, tabId, indexes, selectedItems, elementsProvider, closePopup) } + closePopup: Boolean, + query: String) { + RANKING_SERVICE.onItemSelected(project, tabId, indexes, selectedItems, elementsProvider, closePopup, query) + ITEM_SELECTED_LISTENERS.forEach { it.onItemSelected(project, tabId, indexes, selectedItems, elementsProvider, closePopup, query) } } }