Show expect / actual for parameters & enum entries in drop-box
#KT-26957 Fixed
This commit is contained in:
@@ -46,6 +46,9 @@ class KtClassBody : KtElementImplStub<KotlinPlaceHolderStub<KtClassBody>>, KtDec
|
||||
val properties: List<KtProperty>
|
||||
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.PROPERTY)
|
||||
|
||||
val enumEntries: List<KtEnumEntry>
|
||||
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.ENUM_ENTRY).filterIsInstance<KtEnumEntry>()
|
||||
|
||||
val allCompanionObjects: List<KtObjectDeclaration>
|
||||
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.OBJECT_DECLARATION).filter { it.isCompanion() }
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ fun getPlatformActualTooltip(declaration: KtDeclaration): String? {
|
||||
}
|
||||
|
||||
fun navigateToPlatformActual(e: MouseEvent?, declaration: KtDeclaration) {
|
||||
val actualDeclarations = declaration.actualsForExpected()
|
||||
val actualDeclarations =
|
||||
declaration.actualsForExpected() + declaration.findMarkerBoundDeclarations().flatMap { it.actualsForExpected() }
|
||||
if (actualDeclarations.isEmpty()) return
|
||||
|
||||
val renderer = object : DefaultPsiElementCellRenderer() {
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.project.implementedDescriptors
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||
@@ -23,6 +26,7 @@ import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||
import org.jetbrains.kotlin.idea.util.expectedDeclarationIfAny
|
||||
import org.jetbrains.kotlin.idea.util.hasDeclarationOf
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import java.awt.event.MouseEvent
|
||||
|
||||
fun getExpectedDeclarationTooltip(declaration: KtDeclaration): String? {
|
||||
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return null
|
||||
@@ -34,6 +38,20 @@ fun getExpectedDeclarationTooltip(declaration: KtDeclaration): String? {
|
||||
return "Has declaration in common module"
|
||||
}
|
||||
|
||||
fun navigateToExpectedDeclaration(declaration: KtDeclaration) {
|
||||
declaration.expectedDeclarationIfAny()?.navigate(/* request focus = */true)
|
||||
fun navigateToExpectedDeclaration(e: MouseEvent?, declaration: KtDeclaration) {
|
||||
val expectedDeclarations =
|
||||
listOfNotNull(declaration.expectedDeclarationIfAny()) +
|
||||
declaration.findMarkerBoundDeclarations().mapNotNull { it.expectedDeclarationIfAny() }
|
||||
if (expectedDeclarations.isEmpty()) return
|
||||
|
||||
val renderer = object : DefaultPsiElementCellRenderer() {
|
||||
override fun getContainerText(element: PsiElement?, name: String?) = ""
|
||||
}
|
||||
PsiElementListNavigator.openTargets(
|
||||
e,
|
||||
expectedDeclarations.toTypedArray(),
|
||||
"Choose expected for ${declaration.name}",
|
||||
"Expected for ${declaration.name}",
|
||||
renderer
|
||||
)
|
||||
}
|
||||
@@ -216,7 +216,7 @@ private val EXPECTED_DECLARATION = MarkerType(
|
||||
{ element -> element?.markerDeclaration?.let { getExpectedDeclarationTooltip(it) } },
|
||||
object : LineMarkerNavigator() {
|
||||
override fun browse(e: MouseEvent?, element: PsiElement?) {
|
||||
element?.markerDeclaration?.let { navigateToExpectedDeclaration(it) }
|
||||
element?.markerDeclaration?.let { navigateToExpectedDeclaration(e, it) }
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -343,30 +343,42 @@ private fun collectMultiplatformMarkers(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Document?.areAnchorsOnOneLine(
|
||||
private fun Document.areAnchorsOnOneLine(
|
||||
first: KtNamedDeclaration,
|
||||
second: KtNamedDeclaration?
|
||||
): Boolean {
|
||||
if (this == null || second == null) return false
|
||||
if (second == null) return false
|
||||
val firstAnchor = first.expectOrActualAnchor
|
||||
val secondAnchor = second.expectOrActualAnchor
|
||||
return firstAnchor.startLine(this) == secondAnchor.startLine(this)
|
||||
}
|
||||
|
||||
private fun KtNamedDeclaration.requiresNoMarkers(): Boolean {
|
||||
val document = PsiDocumentManager.getInstance(project).getDocument(containingFile)
|
||||
private fun KtNamedDeclaration.requiresNoMarkers(
|
||||
document: Document? = PsiDocumentManager.getInstance(project).getDocument(containingFile)
|
||||
): Boolean {
|
||||
when (this) {
|
||||
is KtPrimaryConstructor -> {
|
||||
return true
|
||||
}
|
||||
is KtParameter,
|
||||
is KtEnumEntry -> if (document.areAnchorsOnOneLine(this, containingClassOrObject)) {
|
||||
is KtEnumEntry -> if (document?.areAnchorsOnOneLine(this, containingClassOrObject) == true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.findMarkerBoundDeclarations(): List<KtNamedDeclaration> {
|
||||
if (this !is KtClass) return emptyList()
|
||||
val result = mutableListOf<KtNamedDeclaration>()
|
||||
val document = PsiDocumentManager.getInstance(project).getDocument(containingFile)
|
||||
result += primaryConstructor?.valueParameters?.filter { it.hasValOrVar() && it.requiresNoMarkers(document) }.orEmpty()
|
||||
if (this.isEnum()) {
|
||||
result += this.body?.enumEntries?.filter { it.requiresNoMarkers(document) }.orEmpty()
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun collectActualMarkers(
|
||||
declaration: KtNamedDeclaration,
|
||||
result: MutableCollection<LineMarkerInfo<*>>
|
||||
|
||||
Reference in New Issue
Block a user