GotoSuperActionHandler: minor refactoring
This commit is contained in:
@@ -28,28 +28,60 @@ 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 {
|
||||||
internal fun allSuperDeclarationsAndDescriptor(editor: Editor, file: PsiFile): Pair<List<PsiElement>, DeclarationDescriptor?> {
|
internal data class SuperDeclarationsAndDescriptor(val supers: List<PsiElement>, val descriptor: DeclarationDescriptor?) {
|
||||||
val element = file.findElementAt(editor.caretModel.offset) ?: return emptyList<PsiElement>() to null
|
constructor() : this(emptyList(), null)
|
||||||
val declaration =
|
|
||||||
PsiTreeUtil.getParentOfType<KtDeclaration>(
|
|
||||||
element,
|
|
||||||
KtNamedFunction::class.java,
|
|
||||||
KtClass::class.java,
|
|
||||||
KtProperty::class.java,
|
|
||||||
KtObjectDeclaration::class.java
|
|
||||||
) ?: return emptyList<PsiElement>() to null
|
|
||||||
|
|
||||||
val expectDeclaration = if (declaration.hasActualModifier()) declaration.expectedDeclarationIfAny() else null
|
companion object {
|
||||||
|
fun forDeclarationAtCaret(editor: Editor, file: PsiFile): SuperDeclarationsAndDescriptor {
|
||||||
|
val element = file.findElementAt(editor.caretModel.offset) ?: return SuperDeclarationsAndDescriptor()
|
||||||
|
val declaration =
|
||||||
|
PsiTreeUtil.getParentOfType<KtDeclaration>(
|
||||||
|
element,
|
||||||
|
KtNamedFunction::class.java,
|
||||||
|
KtClass::class.java,
|
||||||
|
KtProperty::class.java,
|
||||||
|
KtObjectDeclaration::class.java
|
||||||
|
) ?: return SuperDeclarationsAndDescriptor()
|
||||||
|
|
||||||
val descriptor = declaration.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL)
|
val expectDeclaration = if (declaration.hasActualModifier()) declaration.expectedDeclarationIfAny() else null
|
||||||
val superDeclarations = findSuperDeclarations(file.project, descriptor)
|
|
||||||
return ((superDeclarations ?: emptyList()) + listOfNotNull(expectDeclaration)) to descriptor
|
val descriptor = declaration.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL)
|
||||||
|
val superDeclarations = findSuperDeclarations(file.project, descriptor)
|
||||||
|
return SuperDeclarationsAndDescriptor(
|
||||||
|
supers = (superDeclarations ?: emptyList()) + listOfNotNull(expectDeclaration),
|
||||||
|
descriptor = descriptor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findSuperDeclarations(project: Project, descriptor: DeclarationDescriptor): List<PsiElement>? {
|
||||||
|
val superDescriptors: Collection<DeclarationDescriptor> = when (descriptor) {
|
||||||
|
is ClassDescriptor -> {
|
||||||
|
val supertypes = descriptor.typeConstructor.supertypes
|
||||||
|
val superclasses = supertypes.mapNotNull { type ->
|
||||||
|
type.constructor.declarationDescriptor as? ClassDescriptor
|
||||||
|
}
|
||||||
|
ContainerUtil.removeDuplicates(superclasses)
|
||||||
|
superclasses
|
||||||
|
}
|
||||||
|
is CallableMemberDescriptor -> descriptor.getDirectlyOverriddenDeclarations()
|
||||||
|
else -> return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return superDescriptors.mapNotNull { superDescriptor ->
|
||||||
|
if (superDescriptor is ClassDescriptor && isAny(superDescriptor)) {
|
||||||
|
null
|
||||||
|
} else
|
||||||
|
DescriptorToSourceUtilsIde.getAnyDeclaration(project, superDescriptor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor, file: PsiFile) {
|
override fun invoke(project: Project, editor: Editor, file: PsiFile) {
|
||||||
FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID)
|
FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID)
|
||||||
|
|
||||||
val (allDeclarations, descriptor) = allSuperDeclarationsAndDescriptor(editor, file)
|
val (allDeclarations, descriptor) = SuperDeclarationsAndDescriptor.forDeclarationAtCaret(editor, file)
|
||||||
if (allDeclarations.isEmpty()) return
|
if (allDeclarations.isEmpty()) return
|
||||||
if (allDeclarations.size == 1) {
|
if (allDeclarations.size == 1) {
|
||||||
val navigatable = EditSourceUtil.getDescriptor(allDeclarations[0])
|
val navigatable = EditSourceUtil.getDescriptor(allDeclarations[0])
|
||||||
@@ -78,27 +110,5 @@ class GotoSuperActionHandler : CodeInsightActionHandler {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findSuperDeclarations(project: Project, descriptor: DeclarationDescriptor): List<PsiElement>? {
|
|
||||||
val superDescriptors: Collection<DeclarationDescriptor> = when (descriptor) {
|
|
||||||
is ClassDescriptor -> {
|
|
||||||
val supertypes = descriptor.typeConstructor.supertypes
|
|
||||||
val superclasses = supertypes.mapNotNull { type ->
|
|
||||||
type.constructor.declarationDescriptor as? ClassDescriptor
|
|
||||||
}
|
|
||||||
ContainerUtil.removeDuplicates(superclasses)
|
|
||||||
superclasses
|
|
||||||
}
|
|
||||||
is CallableMemberDescriptor -> descriptor.getDirectlyOverriddenDeclarations()
|
|
||||||
else -> return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return superDescriptors.mapNotNull { descriptor ->
|
|
||||||
if (descriptor is ClassDescriptor && isAny(descriptor)) {
|
|
||||||
null
|
|
||||||
} else
|
|
||||||
DescriptorToSourceUtilsIde.getAnyDeclaration(project, descriptor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun startInWriteAction() = false
|
override fun startInWriteAction() = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ import java.io.File
|
|||||||
|
|
||||||
class KotlinGotoSuperMultiModuleTest : AbstractKotlinNavigationMultiModuleTest() {
|
class KotlinGotoSuperMultiModuleTest : AbstractKotlinNavigationMultiModuleTest() {
|
||||||
override fun doNavigate(editor: Editor, file: PsiFile): GotoTargetHandler.GotoData {
|
override fun doNavigate(editor: Editor, file: PsiFile): GotoTargetHandler.GotoData {
|
||||||
val gotoAction = GotoSuperActionHandler()
|
val (superDeclarations, _) = GotoSuperActionHandler.SuperDeclarationsAndDescriptor.forDeclarationAtCaret(editor, file)
|
||||||
val (superDeclarations, _) = gotoAction.allSuperDeclarationsAndDescriptor(editor, file)
|
|
||||||
return GotoTargetHandler.GotoData(file.findElementAt(editor.caretModel.offset)!!, superDeclarations.toTypedArray(), emptyList())
|
return GotoTargetHandler.GotoData(file.findElementAt(editor.caretModel.offset)!!, superDeclarations.toTypedArray(), emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user