diff --git a/platform/lang-impl/src/com/intellij/internal/statistic/IntentionFUSCollector.java b/platform/lang-impl/src/com/intellij/internal/statistic/IntentionFUSCollector.java
index 938190067d9c..90d2344ae862 100644
--- a/platform/lang-impl/src/com/intellij/internal/statistic/IntentionFUSCollector.java
+++ b/platform/lang-impl/src/com/intellij/internal/statistic/IntentionFUSCollector.java
@@ -60,10 +60,7 @@ public final class IntentionFUSCollector extends CounterUsagesCollector {
}
}
LocalQuickFix quickFix = QuickFixWrapper.unwrap(action);
- if (quickFix != null) {
- return quickFix.getClass();
- }
- return action.getClass();
+ return ReportingClassSubstitutor.getClassToReport(quickFix != null ? quickFix : action);
}
public static void reportShownIntentions(@NotNull Project project,
diff --git a/platform/statistics/src/com/intellij/internal/statistic/ReportingClassSubstitutor.java b/platform/statistics/src/com/intellij/internal/statistic/ReportingClassSubstitutor.java
new file mode 100644
index 000000000000..a142d6d6bb58
--- /dev/null
+++ b/platform/statistics/src/com/intellij/internal/statistic/ReportingClassSubstitutor.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.internal.statistic;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * ReportingClassSubstitutor is suitable in cases when reporting (e.g. FUS)
+ * has to be performed on behalf of another class.
+ */
+@ApiStatus.Experimental
+public interface ReportingClassSubstitutor {
+ @NotNull Class> getSubstitutedClass();
+
+ static @NotNull Class> getClassToReport(@NotNull Object object) {
+ return object instanceof ReportingClassSubstitutor substitutor ? substitutor.getSubstitutedClass() : object.getClass();
+ }
+}
diff --git a/plugins/kotlin/code-insight/api/kotlin.code-insight.api.iml b/plugins/kotlin/code-insight/api/kotlin.code-insight.api.iml
index 3800a2cfa3c9..3238a35fb15f 100644
--- a/plugins/kotlin/code-insight/api/kotlin.code-insight.api.iml
+++ b/plugins/kotlin/code-insight/api/kotlin.code-insight.api.iml
@@ -38,5 +38,6 @@
+
\ No newline at end of file
diff --git a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspection.kt b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspection.kt
index 25c2d1e25fa4..adfb2cfe705c 100644
--- a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspection.kt
+++ b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspection.kt
@@ -39,6 +39,8 @@ abstract class AbstractKotlinApplicableInspection(
if (!isApplicable) return null
val elementPointer = element.createSmartPointer()
+ val inspectionClass = javaClass
+
val quickFix = object : AbstractKotlinApplicableInspectionQuickFix() {
override fun applyTo(element: ELEMENT) {
apply(element, element.project, element.findExistingEditor())
@@ -47,6 +49,7 @@ abstract class AbstractKotlinApplicableInspection(
override fun shouldApplyInWriteAction(): Boolean = this@AbstractKotlinApplicableInspection.shouldApplyInWriteAction()
override fun getFamilyName(): String = this@AbstractKotlinApplicableInspection.getActionFamilyName()
override fun getName(): String = elementPointer.element?.let { getActionName(it) } ?: familyName
+ override fun getSubstitutedClass(): Class<*> = inspectionClass
}
val description = getProblemDescription(element)
diff --git a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionBase.kt b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionBase.kt
index b0b7cba7c8e7..116e5ce49d3a 100644
--- a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionBase.kt
+++ b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionBase.kt
@@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections
import com.intellij.codeInspection.*
import com.intellij.codeInspection.util.InspectionMessage
import com.intellij.codeInspection.util.IntentionFamilyName
+import com.intellij.internal.statistic.ReportingClassSubstitutor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiFile
@@ -71,7 +72,7 @@ abstract class AbstractKotlinApplicableInspectionBase(
}
}
-internal abstract class AbstractKotlinApplicableInspectionQuickFix : LocalQuickFix {
+internal abstract class AbstractKotlinApplicableInspectionQuickFix : LocalQuickFix, ReportingClassSubstitutor {
abstract fun applyTo(element: ELEMENT)
abstract fun shouldApplyInWriteAction(): Boolean
diff --git a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionWithContext.kt b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionWithContext.kt
index a1e1283ee2bc..66be152b91da 100644
--- a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionWithContext.kt
+++ b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/applicable/inspections/AbstractKotlinApplicableInspectionWithContext.kt
@@ -40,6 +40,7 @@ abstract class AbstractKotlinApplicableInspectionWithContext() {
override fun applyTo(element: ELEMENT) {
apply(element, context, element.project, element.findExistingEditor())
@@ -48,6 +49,7 @@ abstract class AbstractKotlinApplicableInspectionWithContext = inspectionWithContextClass
}
val description = getProblemDescription(element, context)
diff --git a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/AbstractApplicabilityBasedInspection.kt b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/AbstractApplicabilityBasedInspection.kt
index ce2bb2a21709..35d829260d48 100644
--- a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/AbstractApplicabilityBasedInspection.kt
+++ b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/AbstractApplicabilityBasedInspection.kt
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.intention.FileModifier
import com.intellij.codeInspection.*
import com.intellij.codeInspection.util.InspectionMessage
import com.intellij.codeInspection.util.IntentionName
+import com.intellij.internal.statistic.ReportingClassSubstitutor
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
@@ -62,7 +63,7 @@ abstract class AbstractApplicabilityBasedInspection(
private class LocalFix(
@FileModifier.SafeFieldForPreview val inspection: AbstractApplicabilityBasedInspection,
@IntentionName val text: String
- ) : LocalQuickFix {
+ ) : LocalQuickFix, ReportingClassSubstitutor {
override fun startInWriteAction() = inspection.startFixInWriteAction
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@@ -74,5 +75,7 @@ abstract class AbstractApplicabilityBasedInspection(
override fun getFamilyName() = inspection.defaultFixText
override fun getName() = text
+
+ override fun getSubstitutedClass(): Class<*> = inspection.javaClass
}
}
\ No newline at end of file
diff --git a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/IntentionBasedInspection.kt b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/IntentionBasedInspection.kt
index d6c89e34990f..373a6fe13bd0 100644
--- a/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/IntentionBasedInspection.kt
+++ b/plugins/kotlin/code-insight/api/src/org/jetbrains/kotlin/idea/codeinsight/api/classic/inspections/IntentionBasedInspection.kt
@@ -5,11 +5,11 @@ package org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections
import com.intellij.codeInsight.intention.FileModifier
import com.intellij.codeInsight.intention.HighPriorityAction
import com.intellij.codeInsight.intention.IntentionAction
-import com.intellij.codeInsight.intention.IntentionActionDelegate
import com.intellij.codeInsight.intention.LowPriorityAction
import com.intellij.codeInsight.intention.preview.IntentionPreviewUtils
import com.intellij.codeInspection.*
import com.intellij.codeInspection.util.InspectionMessage
+import com.intellij.internal.statistic.ReportingClassSubstitutor
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
@@ -140,11 +140,11 @@ abstract class IntentionBasedInspection private construct
val intention: SelfTargetingRangeIntention,
private val additionalChecker: (TElement, IntentionBasedInspection) -> Boolean,
targetElement: TElement
- ) : LocalQuickFixOnPsiElement(targetElement), IntentionAction, IntentionActionDelegate {
+ ) : LocalQuickFixOnPsiElement(targetElement), IntentionAction, ReportingClassSubstitutor {
private val text = intention.text
- override fun getDelegate(): IntentionAction = intention
+ override fun getSubstitutedClass(): Class<*> = intention.javaClass
// store text into variable because intention instance is shared and may change its text later
override fun getFamilyName() = intention.familyName
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt
index 9fe1ab45e9e9..84a630541caf 100644
--- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt
+++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixWithDelegateFactory.kt
@@ -4,6 +4,7 @@ package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.FileModificationService
import com.intellij.codeInsight.intention.*
+import com.intellij.internal.statistic.ReportingClassSubstitutor
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiFile
@@ -11,7 +12,7 @@ import org.jetbrains.annotations.Nls
open class QuickFixWithDelegateFactory(
delegateFactory: () -> IntentionAction?
-) : IntentionAction, IntentionActionDelegate {
+) : IntentionAction, ReportingClassSubstitutor {
@Nls
private val familyName: String
@Nls
@@ -26,7 +27,7 @@ open class QuickFixWithDelegateFactory(
startInWriteAction = delegate != null && delegate.startInWriteAction()
}
- override fun getDelegate(): IntentionAction = delegate ?: EmptyIntentionAction("")
+ override fun getSubstitutedClass(): Class<*> = delegate?.javaClass ?: javaClass
override fun getFamilyName() = familyName