More generic solution for testing line marker navigation
This commit is contained in:
@@ -21,17 +21,22 @@ import com.intellij.codeInsight.daemon.LineMarkerInfo
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider
|
||||
import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator
|
||||
import com.intellij.codeInsight.daemon.impl.MarkerType
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.psi.NavigatablePsiElement
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiNameIdentifierOwner
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||
@@ -42,6 +47,7 @@ import org.jetbrains.kotlin.psi.psiUtil.isOverridable
|
||||
import java.awt.event.MouseEvent
|
||||
import java.util.*
|
||||
import javax.swing.Icon
|
||||
import javax.swing.ListCellRenderer
|
||||
|
||||
class KotlinLineMarkerProvider : LineMarkerProvider {
|
||||
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<PsiElement>? {
|
||||
@@ -101,6 +107,22 @@ private val IMPLEMENTING_MARK: Icon = AllIcons.Gutter.ImplementingMethod
|
||||
private val OVERRIDDEN_MARK: Icon = AllIcons.Gutter.OverridenMethod
|
||||
private val IMPLEMENTED_MARK: Icon = AllIcons.Gutter.ImplementedMethod
|
||||
|
||||
data class NavigationPopupDescriptor(
|
||||
val targets: Collection<NavigatablePsiElement>,
|
||||
val title: String,
|
||||
val findUsagesTitle: String,
|
||||
val renderer: ListCellRenderer<*>,
|
||||
val updater: ListBackgroundUpdaterTask? = null
|
||||
) {
|
||||
fun showPopup(e: MouseEvent?) {
|
||||
PsiElementListNavigator.openTargets(e, targets.toTypedArray(), title, findUsagesTitle, renderer, updater)
|
||||
}
|
||||
}
|
||||
|
||||
interface TestableLineMarkerNavigator {
|
||||
fun getTargetsPopupDescriptor(element: PsiElement?): NavigationPopupDescriptor?
|
||||
}
|
||||
|
||||
private val SUBCLASSED_CLASS = MarkerType(
|
||||
"SUBCLASSED_CLASS",
|
||||
{ getPsiClass(it)?.let { MarkerType.getSubclassedClassTooltip(it) } },
|
||||
|
||||
@@ -17,11 +17,9 @@
|
||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.psi.NavigatablePsiElement
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.Function
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
@@ -65,20 +63,16 @@ object SuperDeclarationMarkerTooltip: Function<KtDeclaration, String> {
|
||||
}
|
||||
}
|
||||
|
||||
class SuperDeclarationMarkerNavigationHandler : GutterIconNavigationHandler<KtDeclaration> {
|
||||
private var testNavigableElements: List<NavigatablePsiElement>? = null
|
||||
|
||||
@TestOnly fun getNavigationElements(): List<NavigatablePsiElement> {
|
||||
val navigationResult = testNavigableElements!!
|
||||
testNavigableElements = null
|
||||
return navigationResult
|
||||
class SuperDeclarationMarkerNavigationHandler : GutterIconNavigationHandler<KtDeclaration>, TestableLineMarkerNavigator {
|
||||
override fun navigate(e: MouseEvent?, element: KtDeclaration?) {
|
||||
getTargetsPopupDescriptor(element)?.showPopup(e)
|
||||
}
|
||||
|
||||
override fun navigate(e: MouseEvent?, element: KtDeclaration?) {
|
||||
if (element == null) return
|
||||
override fun getTargetsPopupDescriptor(element: PsiElement?): NavigationPopupDescriptor? {
|
||||
if (element !is KtDeclaration) return null
|
||||
|
||||
val (elementDescriptor, overriddenDescriptors) = resolveDeclarationWithParents(element)
|
||||
if (overriddenDescriptors.isEmpty()) return
|
||||
if (overriddenDescriptors.isEmpty()) return null
|
||||
|
||||
val superDeclarations = ArrayList<NavigatablePsiElement>()
|
||||
for (overriddenMember in overriddenDescriptors) {
|
||||
@@ -90,20 +84,11 @@ class SuperDeclarationMarkerNavigationHandler : GutterIconNavigationHandler<KtDe
|
||||
}
|
||||
}
|
||||
|
||||
if (!ApplicationManager.getApplication()!!.isUnitTestMode) {
|
||||
val elementName = elementDescriptor!!.name
|
||||
|
||||
PsiElementListNavigator.openTargets(
|
||||
e,
|
||||
superDeclarations.toTypedArray(),
|
||||
KotlinBundle.message("navigation.title.super.declaration", elementName),
|
||||
KotlinBundle.message("navigation.findUsages.title.super.declaration", elementName),
|
||||
KtFunctionPsiElementCellRenderer())
|
||||
}
|
||||
else {
|
||||
// Only store elements for retrieve in test
|
||||
testNavigableElements = superDeclarations
|
||||
}
|
||||
val elementName = elementDescriptor!!.name
|
||||
return NavigationPopupDescriptor(superDeclarations,
|
||||
KotlinBundle.message("navigation.title.super.declaration", elementName),
|
||||
KotlinBundle.message("navigation.findUsages.title.super.declaration", elementName),
|
||||
KtFunctionPsiElementCellRenderer())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.PlatformTestUtil
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.idea.highlighter.markers.SuperDeclarationMarkerNavigationHandler
|
||||
import org.jetbrains.kotlin.idea.highlighter.markers.TestableLineMarkerNavigator
|
||||
import org.jetbrains.kotlin.idea.navigation.NavigationTestUtils
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.test.ReferenceUtils
|
||||
import org.jetbrains.kotlin.test.TagsTestDataUtil
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
@@ -115,19 +114,10 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase()
|
||||
navigateMarker)
|
||||
|
||||
val handler = navigateMarker.navigationHandler
|
||||
if (handler is SuperDeclarationMarkerNavigationHandler) {
|
||||
if (handler is TestableLineMarkerNavigator) {
|
||||
val element = navigateMarker.element as KtDeclaration
|
||||
|
||||
handler.navigate(null, element)
|
||||
val navigateElements = handler.getNavigationElements()
|
||||
|
||||
Collections.sort(navigateElements) { first, second ->
|
||||
val elementFirstStr = ReferenceUtils.renderAsGotoImplementation(first)
|
||||
val elementSecondStr = ReferenceUtils.renderAsGotoImplementation(second)
|
||||
|
||||
elementFirstStr.compareTo(elementSecondStr)
|
||||
}
|
||||
|
||||
val navigateElements = handler.getTargetsPopupDescriptor(element)?.targets?.sortedBy { ReferenceUtils.renderAsGotoImplementation(it) }
|
||||
val actualNavigationData = NavigationTestUtils.getNavigateElementsText(myFixture.project, navigateElements)
|
||||
|
||||
UsefulTestCase.assertSameLines(getExpectedNavigationText(navigationComment), actualNavigationData)
|
||||
|
||||
Reference in New Issue
Block a user