GotoSuperActionHandler: convert to .kt

This commit is contained in:
Dmitry Jemerov
2018-01-12 17:22:49 +01:00
parent 690c3433d6
commit cc90dfa65b
@@ -1,144 +1,98 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* * that can be found in the license/LICENSE.txt file.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.idea.codeInsight; package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.codeInsight.CodeInsightActionHandler; import com.intellij.codeInsight.CodeInsightActionHandler
import com.intellij.codeInsight.navigation.NavigationUtil; import com.intellij.codeInsight.navigation.NavigationUtil
import com.intellij.codeInsight.navigation.actions.GotoSuperAction; import com.intellij.codeInsight.navigation.actions.GotoSuperAction
import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.featureStatistics.FeatureUsageTracker
import com.intellij.ide.util.EditSourceUtil; import com.intellij.ide.util.EditSourceUtil
import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.psi.PsiElement
import com.intellij.pom.Navigatable; import com.intellij.psi.PsiFile
import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiUtilCore
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.ContainerUtil
import com.intellij.psi.util.PsiUtilCore; import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isAny
import com.intellij.util.Function; import org.jetbrains.kotlin.descriptors.*
import com.intellij.util.containers.ContainerUtil; import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.idea.KotlinBundle; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.idea.core.DescriptorUtilsKt;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
import org.jetbrains.kotlin.types.KotlinType;
import java.util.Collection; class GotoSuperActionHandler : CodeInsightActionHandler {
import java.util.List; override fun invoke(project: Project, editor: Editor, file: PsiFile) {
FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID)
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isAny; val element = file.findElementAt(editor.caretModel.offset) ?: return
val declaration =
PsiTreeUtil.getParentOfType<KtDeclaration>(
element,
KtNamedFunction::class.java,
KtClass::class.java,
KtProperty::class.java,
KtObjectDeclaration::class.java
) ?: return
public class GotoSuperActionHandler implements CodeInsightActionHandler { val descriptor = declaration.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL)
@Override
public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
FeatureUsageTracker.getInstance().triggerFeatureUsed(GotoSuperAction.FEATURE_ID);
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); val superDeclarations = findSuperDeclarations(descriptor)
if (element == null) return;
@SuppressWarnings("unchecked") KtDeclaration declaration =
PsiTreeUtil.getParentOfType(element,
KtNamedFunction.class,
KtClass.class,
KtProperty.class,
KtObjectDeclaration.class);
if (declaration == null) return;
DeclarationDescriptor descriptor = ResolutionUtils.unsafeResolveToDescriptor(declaration, BodyResolveMode.PARTIAL); if (superDeclarations == null || superDeclarations.isEmpty()) return
if (superDeclarations.size == 1) {
List<PsiElement> superDeclarations = findSuperDeclarations(descriptor); val navigatable = EditSourceUtil.getDescriptor(superDeclarations[0])
if (superDeclarations == null || superDeclarations.isEmpty()) return;
if (superDeclarations.size() == 1) {
Navigatable navigatable = EditSourceUtil.getDescriptor(superDeclarations.get(0));
if (navigatable != null && navigatable.canNavigate()) { if (navigatable != null && navigatable.canNavigate()) {
navigatable.navigate(true); navigatable.navigate(true)
} }
} } else {
else { val message = getTitle(descriptor)
String message = getTitle(descriptor); val superDeclarationsArray = PsiUtilCore.toPsiElementArray(superDeclarations)
PsiElement[] superDeclarationsArray = PsiUtilCore.toPsiElementArray(superDeclarations); val popup = if (descriptor is ClassDescriptor)
JBPopup popup = descriptor instanceof ClassDescriptor NavigationUtil.getPsiElementPopup(superDeclarationsArray, message)
? NavigationUtil.getPsiElementPopup(superDeclarationsArray, message) else
: NavigationUtil.getPsiElementPopup(superDeclarationsArray, NavigationUtil.getPsiElementPopup(
new KtFunctionPsiElementCellRenderer(), message); superDeclarationsArray,
popup.showInBestPositionFor(editor); KtFunctionPsiElementCellRenderer(), message
)
popup.showInBestPositionFor(editor)
} }
} }
@Nullable private fun getTitle(descriptor: DeclarationDescriptor): String? =
private static String getTitle(DeclarationDescriptor descriptor) { when(descriptor) {
if (descriptor instanceof ClassDescriptor) { is ClassDescriptor -> KotlinBundle.message("goto.super.class.chooser.title")
return KotlinBundle.message("goto.super.class.chooser.title"); is PropertyDescriptor -> KotlinBundle.message("goto.super.property.chooser.title")
is SimpleFunctionDescriptor -> KotlinBundle.message("goto.super.function.chooser.title")
else -> null
} }
if (descriptor instanceof PropertyDescriptor) { private fun findSuperDeclarations(descriptor: DeclarationDescriptor): List<PsiElement>? {
return KotlinBundle.message("goto.super.property.chooser.title"); val superDescriptors: Collection<DeclarationDescriptor> = when (descriptor) {
} is ClassDescriptor -> {
val supertypes = descriptor.typeConstructor.supertypes
if (descriptor instanceof SimpleFunctionDescriptor) { val superclasses = supertypes.mapNotNull { type ->
return KotlinBundle.message("goto.super.function.chooser.title"); type.constructor.declarationDescriptor as? ClassDescriptor
}
return null;
}
@Nullable
private static List<PsiElement> findSuperDeclarations(DeclarationDescriptor descriptor) {
Collection<? extends DeclarationDescriptor> superDescriptors;
if (descriptor instanceof ClassDescriptor) {
Collection<KotlinType> supertypes = ((ClassDescriptor) descriptor).getTypeConstructor().getSupertypes();
List<ClassDescriptor> superclasses = ContainerUtil.mapNotNull(supertypes, new Function<KotlinType, ClassDescriptor>() {
@Override
public ClassDescriptor fun(KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof ClassDescriptor) {
return (ClassDescriptor) descriptor;
}
return null;
} }
}); ContainerUtil.removeDuplicates(superclasses)
ContainerUtil.removeDuplicates(superclasses); superclasses
superDescriptors = superclasses;
}
else if (descriptor instanceof CallableMemberDescriptor) {
superDescriptors = DescriptorUtilsKt.getDirectlyOverriddenDeclarations((CallableMemberDescriptor) descriptor);
}
else {
return null;
}
return ContainerUtil.mapNotNull(superDescriptors, new Function<DeclarationDescriptor, PsiElement>() {
@Override
public PsiElement fun(DeclarationDescriptor descriptor) {
if (descriptor instanceof ClassDescriptor && isAny((ClassDescriptor) descriptor)) {
return null;
}
return DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
} }
}); is CallableMemberDescriptor -> descriptor.getDirectlyOverriddenDeclarations()
else -> return null
}
return superDescriptors.mapNotNull { descriptor ->
if (descriptor is ClassDescriptor && isAny(descriptor)) {
null
} else
DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
}
} }
@Override override fun startInWriteAction() = false
public boolean startInWriteAction() {
return false;
}
} }