More generic solution for testing line marker navigation

This commit is contained in:
Dmitry Jemerov
2017-04-27 15:18:11 +02:00
parent f9bca06e33
commit c22e0d88f0
3 changed files with 38 additions and 41 deletions
@@ -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)