Navigation: add expect declarations as supers #KT-16892 Fixed
This commit is contained in:
@@ -214,7 +214,7 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractGotoSuperTest> {
|
testClass<AbstractGotoSuperTest> {
|
||||||
model("navigation/gotoSuper", extension = "test")
|
model("navigation/gotoSuper", extension = "test", recursive = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
testClass<AbstractGotoTypeDeclarationTest> {
|
testClass<AbstractGotoTypeDeclarationTest> {
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
|
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.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
class GotoSuperActionHandler : CodeInsightActionHandler {
|
class GotoSuperActionHandler : CodeInsightActionHandler {
|
||||||
override fun invoke(project: Project, editor: Editor, file: PsiFile) {
|
internal fun allSuperDeclarationsAndDescriptor(editor: Editor, file: PsiFile): Pair<List<PsiElement>, DeclarationDescriptor?> {
|
||||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID)
|
val element = file.findElementAt(editor.caretModel.offset) ?: return emptyList<PsiElement>() to null
|
||||||
|
|
||||||
val element = file.findElementAt(editor.caretModel.offset) ?: return
|
|
||||||
val declaration =
|
val declaration =
|
||||||
PsiTreeUtil.getParentOfType<KtDeclaration>(
|
PsiTreeUtil.getParentOfType<KtDeclaration>(
|
||||||
element,
|
element,
|
||||||
@@ -37,21 +37,28 @@ class GotoSuperActionHandler : CodeInsightActionHandler {
|
|||||||
KtClass::class.java,
|
KtClass::class.java,
|
||||||
KtProperty::class.java,
|
KtProperty::class.java,
|
||||||
KtObjectDeclaration::class.java
|
KtObjectDeclaration::class.java
|
||||||
) ?: return
|
) ?: return emptyList<PsiElement>() to null
|
||||||
|
|
||||||
|
val expectDeclaration = if (declaration.hasActualModifier()) declaration.expectedDeclarationIfAny() else null
|
||||||
|
|
||||||
val descriptor = declaration.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL)
|
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
|
val (allDeclarations, descriptor) = allSuperDeclarationsAndDescriptor(editor, file)
|
||||||
if (superDeclarations.size == 1) {
|
if (allDeclarations.isEmpty()) return
|
||||||
val navigatable = EditSourceUtil.getDescriptor(superDeclarations[0])
|
if (allDeclarations.size == 1) {
|
||||||
|
val navigatable = EditSourceUtil.getDescriptor(allDeclarations[0])
|
||||||
if (navigatable != null && navigatable.canNavigate()) {
|
if (navigatable != null && navigatable.canNavigate()) {
|
||||||
navigatable.navigate(true)
|
navigatable.navigate(true)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val message = getTitle(descriptor)
|
val message = getTitle(descriptor!!)
|
||||||
val superDeclarationsArray = PsiUtilCore.toPsiElementArray(superDeclarations)
|
val superDeclarationsArray = PsiUtilCore.toPsiElementArray(allDeclarations)
|
||||||
val popup = if (descriptor is ClassDescriptor)
|
val popup = if (descriptor is ClassDescriptor)
|
||||||
NavigationUtil.getPsiElementPopup(superDeclarationsArray, message)
|
NavigationUtil.getPsiElementPopup(superDeclarationsArray, message)
|
||||||
else
|
else
|
||||||
@@ -64,7 +71,7 @@ class GotoSuperActionHandler : CodeInsightActionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getTitle(descriptor: DeclarationDescriptor): String? =
|
private fun getTitle(descriptor: DeclarationDescriptor): String? =
|
||||||
when(descriptor) {
|
when (descriptor) {
|
||||||
is ClassDescriptor -> KotlinBundle.message("goto.super.class.chooser.title")
|
is ClassDescriptor -> KotlinBundle.message("goto.super.class.chooser.title")
|
||||||
is PropertyDescriptor -> KotlinBundle.message("goto.super.property.chooser.title")
|
is PropertyDescriptor -> KotlinBundle.message("goto.super.property.chooser.title")
|
||||||
is SimpleFunctionDescriptor -> KotlinBundle.message("goto.super.function.chooser.title")
|
is SimpleFunctionDescriptor -> KotlinBundle.message("goto.super.function.chooser.title")
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
expect class Expected
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
actual class <caret>Expected
|
||||||
|
|
||||||
|
// REF: [common] (test).Expected
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
expect class Expected {
|
||||||
|
fun foo(): Int
|
||||||
|
|
||||||
|
val bar: String
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
actual class Expected {
|
||||||
|
actual fun <caret>foo() = 42
|
||||||
|
|
||||||
|
actual val bar = "Hello"
|
||||||
|
}
|
||||||
|
|
||||||
|
// REF: [common] (in test.Expected).foo()
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
expect class Expected {
|
||||||
|
fun foo(): Int
|
||||||
|
|
||||||
|
val bar: String
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
actual class Expected {
|
||||||
|
actual fun foo() = 42
|
||||||
|
|
||||||
|
actual val <caret>bar = "Hello"
|
||||||
|
}
|
||||||
|
|
||||||
|
// REF: [common] (in test.Expected).bar
|
||||||
|
|
||||||
+1
-1
@@ -22,7 +22,7 @@ import java.util.regex.Pattern;
|
|||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class GotoSuperTestGenerated extends AbstractGotoSuperTest {
|
public class GotoSuperTestGenerated extends AbstractGotoSuperTest {
|
||||||
public void testAllFilesPresentInGotoSuper() throws Exception {
|
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")
|
@TestMetadata("BadPositionLambdaParameter.test")
|
||||||
|
|||||||
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user