From 208c3e8d2b69b72d690c33aab0ebd69252267850 Mon Sep 17 00:00:00 2001 From: Andrey Cherkasov Date: Mon, 15 Apr 2024 22:51:44 +0400 Subject: [PATCH] [kotlin] SpecifyOverrideExplicitlyFix: fix false negative with object declaration ^KTIJ-26891 GitOrigin-RevId: 8691331d6b01d4b66fb337631e997995dbaf200b --- .../SpecifyOverrideExplicitlyFixFactory.kt | 15 +++++++++----- .../fixes/HighLevelQuickFixTestGenerated.java | 5 +++++ .../quickfix/K1QuickFixTestGenerated.java | 5 +++++ .../objectDeclaration.kt | 16 +++++++++++++++ .../objectDeclaration.kt.after | 20 +++++++++++++++++++ 5 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt create mode 100644 plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt.after diff --git a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifyOverrideExplicitlyFixFactory.kt b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifyOverrideExplicitlyFixFactory.kt index c5f499ae0cb8..ac44da2cd89b 100644 --- a/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifyOverrideExplicitlyFixFactory.kt +++ b/plugins/kotlin/code-insight/fixes-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/SpecifyOverrideExplicitlyFixFactory.kt @@ -4,8 +4,7 @@ package org.jetbrains.kotlin.idea.k2.codeinsight.fixes import com.intellij.modcommand.ActionContext import com.intellij.modcommand.ModPsiUpdater import com.intellij.psi.SmartPsiElementPointer -import org.jetbrains.kotlin.analysis.api.calls.successfulVariableAccessCall -import org.jetbrains.kotlin.analysis.api.calls.symbol +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KtFirDiagnostic import org.jetbrains.kotlin.analysis.api.renderer.declarations.KtCallableReturnTypeFilter import org.jetbrains.kotlin.analysis.api.renderer.declarations.impl.KtDeclarationRendererForSource @@ -13,6 +12,7 @@ import org.jetbrains.kotlin.analysis.api.renderer.declarations.modifiers.rendere import org.jetbrains.kotlin.analysis.api.renderer.declarations.renderers.callables.KtValueParameterSymbolRenderer import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol +import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol import org.jetbrains.kotlin.idea.base.analysis.api.utils.shortenReferences import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinPsiUpdateModCommandAction @@ -41,9 +41,7 @@ internal object SpecifyOverrideExplicitlyFixFactory { for (specifier in ktClass.superTypeListEntries) { if (specifier is KtDelegatedSuperTypeEntry) { - val delegateExpression = specifier.delegateExpression as? KtNameReferenceExpression - val resolvedCall = delegateExpression?.resolveCall()?.successfulVariableAccessCall() - val delegateTargetSymbol = resolvedCall?.partiallyAppliedSymbol?.symbol ?: return@ModCommandBased emptyList() + val delegateTargetSymbol = specifier.getSymbol() ?: return@ModCommandBased emptyList() if (delegateTargetSymbol is KtValueParameterSymbol && delegateTargetSymbol.getContainingSymbol().let { @@ -85,6 +83,13 @@ internal object SpecifyOverrideExplicitlyFixFactory { listOf(SpecifyOverrideExplicitlyFix(ktClass, elementContext)) } + context(KtAnalysisSession) + private fun KtDelegatedSuperTypeEntry.getSymbol(): KtNamedSymbol? { + val nameReferenceExpression = delegateExpression as? KtNameReferenceExpression ?: return null + val declaration = nameReferenceExpression.reference?.resolve() as? KtDeclaration ?: return null + return declaration.getSymbol() as? KtNamedSymbol + } + private val renderer = KtDeclarationRendererForSource.WITH_SHORT_NAMES.with { returnTypeFilter = KtCallableReturnTypeFilter.ALWAYS valueParameterRenderer = KtValueParameterSymbolRenderer.TYPE_ONLY diff --git a/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java b/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java index 5bee3f39e081..db363a9dc508 100644 --- a/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java +++ b/plugins/kotlin/code-insight/fixes-k2/tests/test/org/jetbrains/kotlin/idea/k2/codeinsight/fixes/HighLevelQuickFixTestGenerated.java @@ -5374,6 +5374,11 @@ public abstract class HighLevelQuickFixTestGenerated extends AbstractHighLevelQu runTest("../../../idea/tests/testData/quickfix/specifyOverrideExplicitly/notPossible.kt"); } + @TestMetadata("objectDeclaration.kt") + public void testObjectDeclaration() throws Exception { + runTest("../../../idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt"); + } + @TestMetadata("outer.kt") public void testOuter() throws Exception { runTest("../../../idea/tests/testData/quickfix/specifyOverrideExplicitly/outer.kt"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java index 8d0f7572245b..e21054916071 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/K1QuickFixTestGenerated.java @@ -14145,6 +14145,11 @@ public abstract class K1QuickFixTestGenerated extends AbstractK1QuickFixTest { runTest("testData/quickfix/specifyOverrideExplicitly/notPossible.kt"); } + @TestMetadata("objectDeclaration.kt") + public void testObjectDeclaration() throws Exception { + runTest("testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt"); + } + @TestMetadata("outer.kt") public void testOuter() throws Exception { runTest("testData/quickfix/specifyOverrideExplicitly/outer.kt"); diff --git a/plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt b/plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt new file mode 100644 index 000000000000..53a73c985b98 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt @@ -0,0 +1,16 @@ +// "Specify override for 'foo(): Unit' explicitly" "true" +interface A { + fun foo() +} + +open class B : A { + override fun foo() {} +} + +object Obj : A { + override fun foo() {} +} + +class Derived : B(), A by Obj +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.SpecifyOverrideExplicitlyFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.SpecifyOverrideExplicitlyFixFactory$SpecifyOverrideExplicitlyFix \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt.after b/plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt.after new file mode 100644 index 000000000000..8eca6b2f858f --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/specifyOverrideExplicitly/objectDeclaration.kt.after @@ -0,0 +1,20 @@ +// "Specify override for 'foo(): Unit' explicitly" "true" +interface A { + fun foo() +} + +open class B : A { + override fun foo() {} +} + +object Obj : A { + override fun foo() {} +} + +class Derived : B(), A by Obj { + override fun foo() { + Obj.foo() + } +} +// FUS_QUICKFIX_NAME: org.jetbrains.kotlin.idea.quickfix.SpecifyOverrideExplicitlyFix +// FUS_K2_QUICKFIX_NAME: org.jetbrains.kotlin.idea.k2.codeinsight.fixes.SpecifyOverrideExplicitlyFixFactory$SpecifyOverrideExplicitlyFix \ No newline at end of file