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
|
||||
|
||||
class GotoSuperActionHandler : CodeInsightActionHandler {
|
||||
internal fun allSuperDeclarationsAndDescriptor(editor: Editor, file: PsiFile): Pair<List<PsiElement>, DeclarationDescriptor?> {
|
||||
val element = file.findElementAt(editor.caretModel.offset) ?: return emptyList<PsiElement>() to null
|
||||
val declaration =
|
||||
PsiTreeUtil.getParentOfType<KtDeclaration>(
|
||||
element,
|
||||
KtNamedFunction::class.java,
|
||||
KtClass::class.java,
|
||||
KtProperty::class.java,
|
||||
KtObjectDeclaration::class.java
|
||||
) ?: return emptyList<PsiElement>() to null
|
||||
internal data class SuperDeclarationsAndDescriptor(val supers: List<PsiElement>, val descriptor: DeclarationDescriptor?) {
|
||||
constructor() : this(emptyList(), 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 superDeclarations = findSuperDeclarations(file.project, descriptor)
|
||||
return ((superDeclarations ?: emptyList()) + listOfNotNull(expectDeclaration)) to descriptor
|
||||
val expectDeclaration = if (declaration.hasActualModifier()) declaration.expectedDeclarationIfAny() else null
|
||||
|
||||
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) {
|
||||
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.size == 1) {
|
||||
val navigatable = EditSourceUtil.getDescriptor(allDeclarations[0])
|
||||
@@ -78,27 +110,5 @@ class GotoSuperActionHandler : CodeInsightActionHandler {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -14,8 +14,7 @@ import java.io.File
|
||||
|
||||
class KotlinGotoSuperMultiModuleTest : AbstractKotlinNavigationMultiModuleTest() {
|
||||
override fun doNavigate(editor: Editor, file: PsiFile): GotoTargetHandler.GotoData {
|
||||
val gotoAction = GotoSuperActionHandler()
|
||||
val (superDeclarations, _) = gotoAction.allSuperDeclarationsAndDescriptor(editor, file)
|
||||
val (superDeclarations, _) = GotoSuperActionHandler.SuperDeclarationsAndDescriptor.forDeclarationAtCaret(editor, file)
|
||||
return GotoTargetHandler.GotoData(file.findElementAt(editor.caretModel.offset)!!, superDeclarations.toTypedArray(), emptyList())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user