From a2b07c94187ed141001470232e3cedbcc8e019e5 Mon Sep 17 00:00:00 2001 From: Vladimir Dolzhenko Date: Fri, 14 Jul 2023 11:22:54 +0200 Subject: [PATCH] [kotlin] Provide more valuable intention class name in FUS #KTIJ-389 Fixed GitOrigin-RevId: 78962bfab92e848047cc1cba45097f573b639e74 --- .../statistic/IntentionFUSCollector.java | 5 +---- .../statistic/ReportingClassSubstitutor.java | 18 ++++++++++++++++++ .../api/kotlin.code-insight.api.iml | 1 + .../AbstractKotlinApplicableInspection.kt | 3 +++ .../AbstractKotlinApplicableInspectionBase.kt | 3 ++- ...actKotlinApplicableInspectionWithContext.kt | 2 ++ .../AbstractApplicabilityBasedInspection.kt | 5 ++++- .../inspections/IntentionBasedInspection.kt | 6 +++--- .../quickfix/QuickFixWithDelegateFactory.kt | 5 +++-- 9 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 platform/statistics/src/com/intellij/internal/statistic/ReportingClassSubstitutor.java 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