Implemented "Go to super method/class" for Kotlin.
#KT-1266 fixed
This commit is contained in:
@@ -91,6 +91,8 @@
|
||||
|
||||
<codeInsight.parameterInfo language="jet" implementationClass="org.jetbrains.jet.plugin.parameterInfo.JetFunctionParameterInfoHandler"/>
|
||||
|
||||
<codeInsight.gotoSuper language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.GotoSuperActionHandler" />
|
||||
|
||||
<completion.contributor language="jet" id="JetKeywordCompletionContributor" order="first"
|
||||
implementationClass="org.jetbrains.jet.plugin.completion.JetKeywordCompletionContributor"/>
|
||||
|
||||
|
||||
@@ -34,6 +34,10 @@ specify.type.explicitly.add.return.type.action.name=Specify Return Type Explicit
|
||||
specify.type.explicitly.add.action.name=Specify Type Explicitly
|
||||
specify.type.explicitly.remove.action.name=Remove Explicitly Specified Type
|
||||
|
||||
goto.super.function.chooser.title=Choose super function
|
||||
goto.super.property.chooser.title=Choose super property
|
||||
goto.super.class.chooser.title=Choose super class or interface
|
||||
|
||||
livetemplate.description.main=main() function
|
||||
livetemplate.description.soutp=Prints function parameter names and values to System.out
|
||||
livetemplate.description.iter=Iterate over elements of iterable
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2010-2012 JetBrains s.r.o.
|
||||
*
|
||||
* 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.jet.plugin.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.codeInsight.navigation.actions.GotoSuperAction;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.ide.util.EditSourceUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Evgeny Gerashchenko
|
||||
* @since 06.05.12
|
||||
*/
|
||||
public class GotoSuperActionHandler implements CodeInsightActionHandler {
|
||||
@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());
|
||||
if (element == null) return;
|
||||
@SuppressWarnings("unchecked") JetNamedDeclaration funOrClass =
|
||||
PsiTreeUtil.getParentOfType(element, JetNamedFunction.class, JetClass.class, JetProperty.class);
|
||||
if (funOrClass == null) return;
|
||||
|
||||
final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) file).getBindingContext();
|
||||
|
||||
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, funOrClass);
|
||||
|
||||
|
||||
Collection<? extends DeclarationDescriptor> superDescriptors;
|
||||
String message;
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
Collection<? extends JetType> supertypes = ((ClassDescriptor) descriptor).getTypeConstructor().getSupertypes();
|
||||
List<ClassDescriptor> superclasses = ContainerUtil.mapNotNull(supertypes, new Function<JetType, ClassDescriptor>() {
|
||||
@Override
|
||||
public ClassDescriptor fun(JetType type) {
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return (ClassDescriptor) descriptor;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
ContainerUtil.removeDuplicates(superclasses);
|
||||
superDescriptors = superclasses;
|
||||
message = JetBundle.message("goto.super.class.chooser.title");
|
||||
}
|
||||
else if (descriptor instanceof CallableMemberDescriptor) {
|
||||
superDescriptors = ((CallableMemberDescriptor) descriptor).getOverriddenDescriptors();
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
message = JetBundle.message("goto.super.property.chooser.title");
|
||||
}
|
||||
else if (descriptor instanceof SimpleFunctionDescriptor) {
|
||||
message = JetBundle.message("goto.super.function.chooser.title");
|
||||
}
|
||||
else
|
||||
throw new IllegalStateException("Unknown member type: " + descriptor.getClass().getName());
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
List<PsiElement> superDeclarations = ContainerUtil.mapNotNull(superDescriptors, new Function<DeclarationDescriptor, PsiElement>() {
|
||||
@Override
|
||||
public PsiElement fun(DeclarationDescriptor descriptor) {
|
||||
if (JetStandardClasses.getAny() == descriptor) {
|
||||
return null;
|
||||
}
|
||||
return BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||
}
|
||||
});
|
||||
if (superDeclarations.isEmpty()) return;
|
||||
if (superDeclarations.size() == 1) {
|
||||
Navigatable navigatable = EditSourceUtil.getDescriptor(superDeclarations.get(0));
|
||||
if (navigatable != null && navigatable.canNavigate()) {
|
||||
navigatable.navigate(true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiElement[] superDeclarationsArray = PsiUtilCore.toPsiElementArray(superDeclarations);
|
||||
JBPopup popup = descriptor instanceof ClassDescriptor
|
||||
? NavigationUtil.getPsiElementPopup(superDeclarationsArray, message)
|
||||
: NavigationUtil.getPsiElementPopup(superDeclarationsArray,
|
||||
new JetFunctionPsiElementCellRenderer(bindingContext), message);
|
||||
popup.showInBestPositionFor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user