Add icons to override/implements dialog
#KT-1817 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
6feceaa161
commit
dc379ad96d
@@ -16,10 +16,14 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.generation.ClassMember;
|
||||
import com.intellij.codeInsight.generation.ClassMemberWithElement;
|
||||
import com.intellij.codeInsight.generation.MemberChooserObject;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.util.PsiIconUtil;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -27,22 +31,27 @@ import javax.swing.*;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class DescriptorClassMember implements ClassMember {
|
||||
public class DescriptorClassMember implements ClassMemberWithElement {
|
||||
private final DeclarationDescriptor myDescriptor;
|
||||
private final PsiElement myPsiElement;
|
||||
|
||||
public DescriptorClassMember(DeclarationDescriptor descriptor) {
|
||||
public DescriptorClassMember(PsiElement element, DeclarationDescriptor descriptor) {
|
||||
myPsiElement = element;
|
||||
myDescriptor = descriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberChooserObject getParentNodeDelegate() {
|
||||
final DeclarationDescriptor parent = myDescriptor.getContainingDeclaration();
|
||||
return new DescriptorClassMember(parent);
|
||||
return new DescriptorClassMember(PsiTreeUtil.getParentOfType(myPsiElement, JetNamedDeclaration.class), parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTreeNode(SimpleColoredComponent component, JTree tree) {
|
||||
component.append(getText());
|
||||
if (myPsiElement.isValid()) {
|
||||
component.setIcon(PsiIconUtil.getProvidersIcon(myPsiElement, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,4 +79,9 @@ public class DescriptorClassMember implements ClassMember {
|
||||
public int hashCode() {
|
||||
return myDescriptor != null ? myDescriptor.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return myPsiElement;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-24
@@ -33,41 +33,31 @@ import org.jetbrains.annotations.Nullable;
|
||||
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.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public abstract class OverrideImplementMethodsHandler implements LanguageCodeInsightActionHandler {
|
||||
public static List<DescriptorClassMember> membersFromDescriptors(Iterable<CallableMemberDescriptor> missingImplementations) {
|
||||
public static List<DescriptorClassMember> membersFromDescriptors(
|
||||
Iterable<CallableMemberDescriptor> missingImplementations,
|
||||
BindingContext bindingContext
|
||||
) {
|
||||
List<DescriptorClassMember> members = new ArrayList<DescriptorClassMember>();
|
||||
for (CallableMemberDescriptor memberDescriptor : missingImplementations) {
|
||||
members.add(new DescriptorClassMember(memberDescriptor));
|
||||
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, memberDescriptor);
|
||||
members.add(new DescriptorClassMember(psiElement, memberDescriptor));
|
||||
}
|
||||
return members;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<CallableMemberDescriptor> collectMethodsToGenerate(@NotNull JetClassOrObject classOrObject) {
|
||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile)classOrObject.getContainingFile())
|
||||
.getBindingContext();
|
||||
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject);
|
||||
if (descriptor instanceof MutableClassDescriptor) {
|
||||
return collectMethodsToGenerate((MutableClassDescriptor)descriptor);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
protected abstract Set<CallableMemberDescriptor> collectMethodsToGenerate(MutableClassDescriptor descriptor);
|
||||
|
||||
public static void generateMethods(Editor editor,
|
||||
JetClassOrObject classOrObject,
|
||||
List<DescriptorClassMember> selectedElements) {
|
||||
@@ -92,7 +82,6 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
|
||||
ReferenceToClassesShortening.compactReferenceToClasses(elementsToCompact);
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static PsiElement findInsertAfterAnchor(Editor editor, final JetClassBody body) {
|
||||
PsiElement afterAnchor = body.getLBrace();
|
||||
@@ -243,8 +232,8 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
|
||||
}
|
||||
|
||||
private static void addReceiverParameter(CallableDescriptor descriptor, StringBuilder bodyBuilder) {
|
||||
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
|
||||
if (receiverParameter != null) {
|
||||
ReceiverDescriptor receiverParameter = descriptor.getReceiverParameter();
|
||||
if (receiverParameter.exists()) {
|
||||
bodyBuilder.append(receiverParameter.getType()).append(".");
|
||||
}
|
||||
}
|
||||
@@ -270,6 +259,17 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
|
||||
return visibility != Visibilities.INTERNAL ? visibility.toString() + " ": "";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Set<CallableMemberDescriptor> collectMethodsToGenerate(@NotNull JetClassOrObject classOrObject, BindingContext bindingContext) {
|
||||
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, classOrObject);
|
||||
if (descriptor instanceof MutableClassDescriptor) {
|
||||
return collectMethodsToGenerate((MutableClassDescriptor) descriptor);
|
||||
}
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
protected abstract Set<CallableMemberDescriptor> collectMethodsToGenerate(MutableClassDescriptor descriptor);
|
||||
|
||||
private MemberChooser<DescriptorClassMember> showOverrideImplementChooser(Project project,
|
||||
DescriptorClassMember[] members) {
|
||||
final MemberChooser<DescriptorClassMember> chooser = new MemberChooser<DescriptorClassMember>(members, true, true, project);
|
||||
@@ -299,12 +299,15 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
|
||||
|
||||
assert classOrObject != null : "ClassObject should be checked in isValidFor method";
|
||||
|
||||
Set<CallableMemberDescriptor> missingImplementations = collectMethodsToGenerate(classOrObject);
|
||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile)classOrObject.getContainingFile())
|
||||
.getBindingContext();
|
||||
|
||||
Set<CallableMemberDescriptor> missingImplementations = collectMethodsToGenerate(classOrObject, bindingContext);
|
||||
if (missingImplementations.isEmpty() && !implementAll) {
|
||||
HintManager.getInstance().showErrorHint(editor, getNoMethodsFoundHint());
|
||||
return;
|
||||
}
|
||||
List<DescriptorClassMember> members = membersFromDescriptors(missingImplementations);
|
||||
List<DescriptorClassMember> members = membersFromDescriptors(missingImplementations, bindingContext);
|
||||
|
||||
final List<DescriptorClassMember> selectedElements;
|
||||
if (implementAll) {
|
||||
|
||||
@@ -26,8 +26,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -70,7 +73,7 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testJavaParameters() {
|
||||
doImplementDirectoryTest();
|
||||
}
|
||||
|
||||
|
||||
public void testGenericMethod() {
|
||||
doImplementFileTest();
|
||||
}
|
||||
@@ -194,7 +197,11 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
|
||||
final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset());
|
||||
final JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, JetClassOrObject.class);
|
||||
assertNotNull("Caret should be inside class or object", classOrObject);
|
||||
final Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject);
|
||||
|
||||
final BindingContext bindingContext = WholeProjectAnalyzerFacade
|
||||
.analyzeProjectWithCacheOnAFile((JetFile) classOrObject.getContainingFile())
|
||||
.getBindingContext();
|
||||
final Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
|
||||
|
||||
final CallableMemberDescriptor singleToOverride;
|
||||
if (memberToOverride == null) {
|
||||
@@ -222,7 +229,8 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
|
||||
protected void run(Result result) throws Throwable {
|
||||
OverrideImplementMethodsHandler.generateMethods(
|
||||
myFixture.getEditor(), classOrObject,
|
||||
OverrideImplementMethodsHandler.membersFromDescriptors(Collections.singletonList(singleToOverride)));
|
||||
OverrideImplementMethodsHandler
|
||||
.membersFromDescriptors(Collections.singletonList(singleToOverride), bindingContext));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@@ -231,7 +239,11 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
|
||||
final PsiElement elementAtCaret = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset());
|
||||
final JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, JetClassOrObject.class);
|
||||
assertNotNull("Caret should be inside class or object", classOrObject);
|
||||
final Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject);
|
||||
|
||||
final BindingContext bindingContext = WholeProjectAnalyzerFacade
|
||||
.analyzeProjectWithCacheOnAFile((JetFile) classOrObject.getContainingFile())
|
||||
.getBindingContext();
|
||||
final Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
|
||||
|
||||
final ArrayList<CallableMemberDescriptor> descriptorsList = new ArrayList<CallableMemberDescriptor>(descriptors);
|
||||
Collections.sort(descriptorsList, new Comparator<CallableMemberDescriptor>() {
|
||||
@@ -246,7 +258,7 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
|
||||
protected void run(Result result) throws Throwable {
|
||||
OverrideImplementMethodsHandler.generateMethods(
|
||||
myFixture.getEditor(), classOrObject,
|
||||
OverrideImplementMethodsHandler.membersFromDescriptors(descriptorsList));
|
||||
OverrideImplementMethodsHandler.membersFromDescriptors(descriptorsList, bindingContext));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user