From ab30275f14c218c5b0a46eb31da129490f392bfc Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 7 Mar 2018 18:09:45 +0300 Subject: [PATCH] Navigation: add expect declarations as supers #KT-16892 Fixed --- .../kotlin/generators/tests/GenerateTests.kt | 2 +- .../codeInsight/GotoSuperActionHandler.kt | 31 +++++++++------- .../multiModule/actualClass/common/common.kt | 3 ++ .../multiModule/actualClass/jvm/jvm.kt | 5 +++ .../actualFunction/common/common.kt | 7 ++++ .../multiModule/actualFunction/jvm/jvm.kt | 10 ++++++ .../actualProperty/common/common.kt | 7 ++++ .../multiModule/actualProperty/jvm/jvm.kt | 10 ++++++ .../navigation/GotoSuperTestGenerated.java | 2 +- .../KotlinGotoSuperMultiModuleTest.kt | 36 +++++++++++++++++++ 10 files changed, 99 insertions(+), 14 deletions(-) create mode 100644 idea/testData/navigation/gotoSuper/multiModule/actualClass/common/common.kt create mode 100644 idea/testData/navigation/gotoSuper/multiModule/actualClass/jvm/jvm.kt create mode 100644 idea/testData/navigation/gotoSuper/multiModule/actualFunction/common/common.kt create mode 100644 idea/testData/navigation/gotoSuper/multiModule/actualFunction/jvm/jvm.kt create mode 100644 idea/testData/navigation/gotoSuper/multiModule/actualProperty/common/common.kt create mode 100644 idea/testData/navigation/gotoSuper/multiModule/actualProperty/jvm/jvm.kt create mode 100644 idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoSuperMultiModuleTest.kt diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 39d5f5dd830..2ca10a53ab2 100755 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -214,7 +214,7 @@ fun main(args: Array) { } testClass { - model("navigation/gotoSuper", extension = "test") + model("navigation/gotoSuper", extension = "test", recursive = false) } testClass { diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.kt b/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.kt index a7791d88835..1c75058c0cf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/GotoSuperActionHandler.kt @@ -22,14 +22,14 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations +import org.jetbrains.kotlin.idea.highlighter.markers.expectedDeclarationIfAny import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class GotoSuperActionHandler : CodeInsightActionHandler { - override fun invoke(project: Project, editor: Editor, file: PsiFile) { - FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID) - - val element = file.findElementAt(editor.caretModel.offset) ?: return + internal fun allSuperDeclarationsAndDescriptor(editor: Editor, file: PsiFile): Pair, DeclarationDescriptor?> { + val element = file.findElementAt(editor.caretModel.offset) ?: return emptyList() to null val declaration = PsiTreeUtil.getParentOfType( element, @@ -37,21 +37,28 @@ class GotoSuperActionHandler : CodeInsightActionHandler { KtClass::class.java, KtProperty::class.java, KtObjectDeclaration::class.java - ) ?: return + ) ?: return emptyList() to null + + val expectDeclaration = if (declaration.hasActualModifier()) declaration.expectedDeclarationIfAny() else null val descriptor = declaration.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) + val superDeclarations = findSuperDeclarations(file.project, descriptor) + return ((superDeclarations ?: emptyList()) + listOfNotNull(expectDeclaration)) to descriptor + } - val superDeclarations = findSuperDeclarations(project, descriptor) + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID) - if (superDeclarations == null || superDeclarations.isEmpty()) return - if (superDeclarations.size == 1) { - val navigatable = EditSourceUtil.getDescriptor(superDeclarations[0]) + val (allDeclarations, descriptor) = allSuperDeclarationsAndDescriptor(editor, file) + if (allDeclarations.isEmpty()) return + if (allDeclarations.size == 1) { + val navigatable = EditSourceUtil.getDescriptor(allDeclarations[0]) if (navigatable != null && navigatable.canNavigate()) { navigatable.navigate(true) } } else { - val message = getTitle(descriptor) - val superDeclarationsArray = PsiUtilCore.toPsiElementArray(superDeclarations) + val message = getTitle(descriptor!!) + val superDeclarationsArray = PsiUtilCore.toPsiElementArray(allDeclarations) val popup = if (descriptor is ClassDescriptor) NavigationUtil.getPsiElementPopup(superDeclarationsArray, message) else @@ -64,7 +71,7 @@ class GotoSuperActionHandler : CodeInsightActionHandler { } private fun getTitle(descriptor: DeclarationDescriptor): String? = - when(descriptor) { + when (descriptor) { is ClassDescriptor -> KotlinBundle.message("goto.super.class.chooser.title") is PropertyDescriptor -> KotlinBundle.message("goto.super.property.chooser.title") is SimpleFunctionDescriptor -> KotlinBundle.message("goto.super.function.chooser.title") diff --git a/idea/testData/navigation/gotoSuper/multiModule/actualClass/common/common.kt b/idea/testData/navigation/gotoSuper/multiModule/actualClass/common/common.kt new file mode 100644 index 00000000000..38e2c17336d --- /dev/null +++ b/idea/testData/navigation/gotoSuper/multiModule/actualClass/common/common.kt @@ -0,0 +1,3 @@ +package test + +expect class Expected diff --git a/idea/testData/navigation/gotoSuper/multiModule/actualClass/jvm/jvm.kt b/idea/testData/navigation/gotoSuper/multiModule/actualClass/jvm/jvm.kt new file mode 100644 index 00000000000..d37f8494bee --- /dev/null +++ b/idea/testData/navigation/gotoSuper/multiModule/actualClass/jvm/jvm.kt @@ -0,0 +1,5 @@ +package test + +actual class Expected + +// REF: [common] (test).Expected diff --git a/idea/testData/navigation/gotoSuper/multiModule/actualFunction/common/common.kt b/idea/testData/navigation/gotoSuper/multiModule/actualFunction/common/common.kt new file mode 100644 index 00000000000..0e4e3d373d5 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/multiModule/actualFunction/common/common.kt @@ -0,0 +1,7 @@ +package test + +expect class Expected { + fun foo(): Int + + val bar: String +} diff --git a/idea/testData/navigation/gotoSuper/multiModule/actualFunction/jvm/jvm.kt b/idea/testData/navigation/gotoSuper/multiModule/actualFunction/jvm/jvm.kt new file mode 100644 index 00000000000..a0d99674b8e --- /dev/null +++ b/idea/testData/navigation/gotoSuper/multiModule/actualFunction/jvm/jvm.kt @@ -0,0 +1,10 @@ +package test + +actual class Expected { + actual fun foo() = 42 + + actual val bar = "Hello" +} + +// REF: [common] (in test.Expected).foo() + diff --git a/idea/testData/navigation/gotoSuper/multiModule/actualProperty/common/common.kt b/idea/testData/navigation/gotoSuper/multiModule/actualProperty/common/common.kt new file mode 100644 index 00000000000..0e4e3d373d5 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/multiModule/actualProperty/common/common.kt @@ -0,0 +1,7 @@ +package test + +expect class Expected { + fun foo(): Int + + val bar: String +} diff --git a/idea/testData/navigation/gotoSuper/multiModule/actualProperty/jvm/jvm.kt b/idea/testData/navigation/gotoSuper/multiModule/actualProperty/jvm/jvm.kt new file mode 100644 index 00000000000..672fc471e0d --- /dev/null +++ b/idea/testData/navigation/gotoSuper/multiModule/actualProperty/jvm/jvm.kt @@ -0,0 +1,10 @@ +package test + +actual class Expected { + actual fun foo() = 42 + + actual val bar = "Hello" +} + +// REF: [common] (in test.Expected).bar + diff --git a/idea/tests/org/jetbrains/kotlin/idea/navigation/GotoSuperTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/navigation/GotoSuperTestGenerated.java index 8dd99f06ccd..23a7d809267 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/navigation/GotoSuperTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/navigation/GotoSuperTestGenerated.java @@ -22,7 +22,7 @@ import java.util.regex.Pattern; @RunWith(JUnit3RunnerWithInners.class) public class GotoSuperTestGenerated extends AbstractGotoSuperTest { public void testAllFilesPresentInGotoSuper() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/navigation/gotoSuper"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY, true); + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/navigation/gotoSuper"), Pattern.compile("^(.+)\\.test$"), TargetBackend.ANY, false); } @TestMetadata("BadPositionLambdaParameter.test") diff --git a/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoSuperMultiModuleTest.kt b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoSuperMultiModuleTest.kt new file mode 100644 index 00000000000..26836faffe0 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/navigation/KotlinGotoSuperMultiModuleTest.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.navigation + +import com.intellij.codeInsight.navigation.GotoTargetHandler +import com.intellij.openapi.editor.Editor +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.idea.codeInsight.GotoSuperActionHandler +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import java.io.File + +class KotlinGotoSuperMultiModuleTest : AbstractKotlinNavigationMultiModuleTest() { + override fun doNavigate(editor: Editor, file: PsiFile): GotoTargetHandler.GotoData { + val gotoAction = GotoSuperActionHandler() + val (superDeclarations, _) = gotoAction.allSuperDeclarationsAndDescriptor(editor, file) + return GotoTargetHandler.GotoData(file.findElementAt(editor.caretModel.offset)!!, superDeclarations.toTypedArray(), emptyList()) + } + + override fun getTestDataPath() = + File(PluginTestCaseBase.getTestDataPathBase(), "/navigation/gotoSuper/multiModule").path + File.separator + + fun testActualClass() { + doMultiPlatformTest("jvm.kt") + } + + fun testActualFunction() { + doMultiPlatformTest("jvm.kt") + } + + fun testActualProperty() { + doMultiPlatformTest("jvm.kt") + } +} \ No newline at end of file