Fix override navigation from properties defined in primary constructor
EA-91185 - CCE: KotlinLineMarkerProviderKt$OVERRIDDEN_PROPERTY$.browse
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeHighlighting.Pass
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo
|
||||
import com.intellij.codeInsight.daemon.LineMarkerProvider
|
||||
import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator
|
||||
@@ -132,23 +133,47 @@ private val SUBCLASSED_CLASS = MarkerType(
|
||||
}
|
||||
})
|
||||
|
||||
private val OVERRIDDEN_FUNCTION = MarkerType(
|
||||
private val OVERRIDDEN_FUNCTION = object : MarkerType(
|
||||
"OVERRIDDEN_FUNCTION",
|
||||
{ getPsiMethod(it)?.let(::getOverriddenMethodTooltip) },
|
||||
object : LineMarkerNavigator() {
|
||||
override fun browse(e: MouseEvent?, element: PsiElement?) {
|
||||
getPsiMethod(element)?.let { navigateToOverriddenMethod(e, it) }
|
||||
buildNavigateToOverriddenMethodPopup(e, element)?.showPopup(e)
|
||||
}
|
||||
})
|
||||
}) {
|
||||
|
||||
private val OVERRIDDEN_PROPERTY = MarkerType(
|
||||
override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> {
|
||||
val superHandler = super.getNavigationHandler()
|
||||
return object : GutterIconNavigationHandler<PsiElement>, TestableLineMarkerNavigator {
|
||||
override fun navigate(e: MouseEvent?, elt: PsiElement?) {
|
||||
superHandler.navigate(e, elt)
|
||||
}
|
||||
|
||||
override fun getTargetsPopupDescriptor(element: PsiElement?) = buildNavigateToOverriddenMethodPopup(null, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val OVERRIDDEN_PROPERTY = object : MarkerType(
|
||||
"OVERRIDDEN_PROPERTY",
|
||||
{ it?.let { getOverriddenPropertyTooltip(it.parent as KtNamedDeclaration) } },
|
||||
object : LineMarkerNavigator() {
|
||||
override fun browse(e: MouseEvent?, element: PsiElement?) {
|
||||
element?.let { navigateToPropertyOverriddenDeclarations(e, it.parent as KtProperty) }
|
||||
buildNavigateToPropertyOverriddenDeclarationsPopup(e, element)?.showPopup(e)
|
||||
}
|
||||
})
|
||||
}) {
|
||||
|
||||
override fun getNavigationHandler(): GutterIconNavigationHandler<PsiElement> {
|
||||
val superHandler = super.getNavigationHandler()
|
||||
return object : GutterIconNavigationHandler<PsiElement>, TestableLineMarkerNavigator {
|
||||
override fun navigate(e: MouseEvent?, elt: PsiElement?) {
|
||||
superHandler.navigate(e, elt)
|
||||
}
|
||||
|
||||
override fun getTargetsPopupDescriptor(element: PsiElement?) = buildNavigateToPropertyOverriddenDeclarationsPopup(null, element)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val PLATFORM_IMPLEMENTATION = MarkerType(
|
||||
"PLATFORM_IMPLEMENTATION",
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonBundle
|
||||
import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
|
||||
import com.intellij.ide.util.MethodCellRenderer
|
||||
import com.intellij.ide.util.PsiElementListCellRenderer
|
||||
@@ -93,10 +92,12 @@ fun getOverriddenMethodTooltip(method: PsiMethod): String? {
|
||||
return GutterIconTooltipHelper.composeText(overridingJavaMethods, start, " {1}")
|
||||
}
|
||||
|
||||
fun navigateToOverriddenMethod(e: MouseEvent?, method: PsiMethod) {
|
||||
fun buildNavigateToOverriddenMethodPopup(e: MouseEvent?, element: PsiElement?): NavigationPopupDescriptor? {
|
||||
val method = getPsiMethod(element) ?: return null
|
||||
|
||||
if (DumbService.isDumb(method.project)) {
|
||||
DumbService.getInstance(method.project)?.showDumbModeNotification("Navigation to overriding classes is not possible during index update")
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
val processor = PsiElementProcessor.CollectElementsWithLimit<PsiMethod>(2, THashSet<PsiMethod>())
|
||||
@@ -105,11 +106,11 @@ fun navigateToOverriddenMethod(e: MouseEvent?, method: PsiMethod) {
|
||||
OverridingMethodsSearch.search(method, true).forEach(PsiElementProcessorAdapter(processor))
|
||||
},
|
||||
"Searching for overriding declarations", true, method.project, e?.component as JComponent?)) {
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
var overridingJavaMethods = processor.collection.filter { !it.isMethodWithDeclarationInOtherClass() }
|
||||
if (overridingJavaMethods.isEmpty()) return
|
||||
if (overridingJavaMethods.isEmpty()) return null
|
||||
|
||||
val showMethodNames = !PsiUtil.allMethodsHaveSameSignature(overridingJavaMethods.toTypedArray())
|
||||
|
||||
@@ -117,13 +118,11 @@ fun navigateToOverriddenMethod(e: MouseEvent?, method: PsiMethod) {
|
||||
overridingJavaMethods = overridingJavaMethods.sortedWith(renderer.comparator)
|
||||
|
||||
val methodsUpdater = OverridingMethodsUpdater(method, renderer)
|
||||
PsiElementListNavigator.openTargets(
|
||||
e,
|
||||
overridingJavaMethods.toTypedArray(),
|
||||
methodsUpdater.getCaption(overridingJavaMethods.size),
|
||||
"Overriding declarations of " + method.name,
|
||||
renderer,
|
||||
methodsUpdater)
|
||||
return NavigationPopupDescriptor(overridingJavaMethods,
|
||||
methodsUpdater.getCaption(overridingJavaMethods.size),
|
||||
"Overriding declarations of " + method.name,
|
||||
renderer,
|
||||
methodsUpdater)
|
||||
}
|
||||
|
||||
private class OverridingMethodsUpdater(
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper
|
||||
import com.intellij.codeInsight.daemon.impl.MarkerType
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
||||
import com.intellij.ide.util.PsiClassListCellRenderer
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
@@ -76,18 +75,22 @@ fun getOverriddenPropertyTooltip(property: KtNamedDeclaration): String? {
|
||||
return GutterIconTooltipHelper.composeText(collectedClasses.sortedWith(PsiClassListCellRenderer().comparator), start, pattern)
|
||||
}
|
||||
|
||||
fun navigateToPropertyOverriddenDeclarations(e: MouseEvent?, property: KtProperty) {
|
||||
val project = property.project
|
||||
fun buildNavigateToPropertyOverriddenDeclarationsPopup(e: MouseEvent?, element: PsiElement?): NavigationPopupDescriptor? {
|
||||
val propertyOrParameter = element?.parent as? KtNamedDeclaration ?: return null
|
||||
val project = propertyOrParameter.project
|
||||
|
||||
if (DumbService.isDumb(project)) {
|
||||
DumbService.getInstance(project)?.showDumbModeNotification("Navigation to overriding classes is not possible during index update")
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
val psiPropertyMethods = LightClassUtil.getLightClassPropertyMethods(property)
|
||||
|
||||
val psiPropertyMethods = when(propertyOrParameter) {
|
||||
is KtProperty -> LightClassUtil.getLightClassPropertyMethods(propertyOrParameter)
|
||||
is KtParameter -> LightClassUtil.getLightClassPropertyMethods(propertyOrParameter)
|
||||
else -> return null
|
||||
}
|
||||
val elementProcessor = CommonProcessors.CollectUniquesProcessor<PsiElement>()
|
||||
val jetPsiMethodProcessor = Runnable {
|
||||
val ktPsiMethodProcessor = Runnable {
|
||||
KotlinDefinitionsSearcher.processPropertyImplementationsMethods(
|
||||
psiPropertyMethods,
|
||||
GlobalSearchScope.allScope(project),
|
||||
@@ -95,12 +98,12 @@ fun navigateToPropertyOverriddenDeclarations(e: MouseEvent?, property: KtPropert
|
||||
}
|
||||
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
/* runnable */ jetPsiMethodProcessor,
|
||||
/* runnable */ ktPsiMethodProcessor,
|
||||
MarkerType.SEARCHING_FOR_OVERRIDING_METHODS,
|
||||
/* can be canceled */ true,
|
||||
project,
|
||||
e?.component as JComponent?)) {
|
||||
return
|
||||
return null
|
||||
}
|
||||
|
||||
val renderer = DefaultPsiElementCellRenderer()
|
||||
@@ -108,10 +111,9 @@ fun navigateToPropertyOverriddenDeclarations(e: MouseEvent?, property: KtPropert
|
||||
.sortedWith(renderer.comparator)
|
||||
.filterIsInstance<NavigatablePsiElement>()
|
||||
|
||||
PsiElementListNavigator.openTargets(e,
|
||||
navigatingOverrides.toTypedArray(),
|
||||
KotlinBundle.message("navigation.title.overriding.property", property.name),
|
||||
KotlinBundle.message("navigation.findUsages.title.overriding.property", property.name), renderer)
|
||||
return NavigationPopupDescriptor(navigatingOverrides,
|
||||
KotlinBundle.message("navigation.title.overriding.property", propertyOrParameter.name),
|
||||
KotlinBundle.message("navigation.findUsages.title.overriding.property", propertyOrParameter.name), renderer)
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
@@ -8,3 +8,10 @@ open class <lineMarker>C</lineMarker>(
|
||||
class D : C("") {
|
||||
override val <lineMarker>s</lineMarker>: String get() = "q"
|
||||
}
|
||||
|
||||
/*
|
||||
LINEMARKER: <html><body>Is overridden in <br/> D</body></html>
|
||||
TARGETS:
|
||||
PrimaryConstructorOpen.kt
|
||||
override val <1>s: String get() = "q"
|
||||
*/
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.ReferenceUtils
|
||||
@@ -115,9 +114,7 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase()
|
||||
|
||||
val handler = navigateMarker.navigationHandler
|
||||
if (handler is TestableLineMarkerNavigator) {
|
||||
val element = navigateMarker.element as KtDeclaration
|
||||
|
||||
val navigateElements = handler.getTargetsPopupDescriptor(element)?.targets?.sortedBy { ReferenceUtils.renderAsGotoImplementation(it) }
|
||||
val navigateElements = handler.getTargetsPopupDescriptor(navigateMarker.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