Icons are showed for all members from all places

This commit is contained in:
Vladimir Rudev
2012-11-02 00:22:17 +04:00
committed by Nikolay Krasko
parent 98eefd0f1c
commit e17b310411
3 changed files with 66 additions and 35 deletions
@@ -18,15 +18,16 @@ package org.jetbrains.jet.plugin.codeInsight;
import com.intellij.codeInsight.generation.ClassMemberWithElement;
import com.intellij.codeInsight.generation.MemberChooserObject;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMember;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.SimpleColoredComponent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetNamedDeclaration;
import org.jetbrains.jet.plugin.JetDescriptorIconProvider;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import javax.swing.*;
@@ -39,38 +40,45 @@ public class DescriptorClassMember implements ClassMemberWithElement {
public static final String NO_PARENT_FOR = "No parent for ";
@NotNull
private final DeclarationDescriptor myDescriptor;
@NotNull
private final PsiElement myPsiElement;
@Nullable
private final Icon icon;
public DescriptorClassMember(PsiElement element, @NotNull DeclarationDescriptor descriptor) {
public DescriptorClassMember(@NotNull PsiElement element, @NotNull DeclarationDescriptor descriptor) {
myPsiElement = element;
myDescriptor = descriptor;
if (myPsiElement.isValid()) {
boolean isClass = myPsiElement instanceof PsiClass;
int flags = isClass ? 0 : 3;
icon = myPsiElement.getIcon(flags);
}
else {
icon = null;
}
}
@Override
public MemberChooserObject getParentNodeDelegate() {
final DeclarationDescriptor parent = myDescriptor.getContainingDeclaration();
PsiElement declaration = null;
PsiElement declaration;
if (myPsiElement instanceof JetDeclaration) {
// kotlin
declaration = PsiTreeUtil.getStubOrPsiParentOfType(myPsiElement, JetNamedDeclaration.class);
}
else if (myPsiElement != null) {
else {
// java or bytecode
declaration = ((PsiMember) myPsiElement).getContainingClass();
}
assert parent != null : NO_PARENT_FOR + myDescriptor;
assert declaration != null : String.format("No parent of type %s for %s", JetNamedDeclaration.class.getSimpleName(), myPsiElement);
return new DescriptorClassMember(declaration, parent);
}
@Override
public void renderTreeNode(SimpleColoredComponent component, JTree tree) {
component.append(getText());
if (myPsiElement != null && myPsiElement.isValid()) {
component.setIcon(myPsiElement.getIcon(0));
}
else {
component.setIcon(JetDescriptorIconProvider.getBaseIcon(myDescriptor));
}
component.setIcon(icon);
}
@Override
@@ -38,6 +38,7 @@ 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.plugin.references.StandardLibraryReferenceResolver;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.*;
@@ -46,27 +47,43 @@ import java.util.*;
* @author yole
*/
public abstract class OverrideImplementMethodsHandler implements LanguageCodeInsightActionHandler {
public static PsiElement getDeclaration(JetFile file, DeclarationDescriptor descriptor, BindingContext bindingContext) {
Collection<PsiElement> elements = BindingContextUtils.descriptorToDeclarations(bindingContext, descriptor);
if (elements.isEmpty()) {
StandardLibraryReferenceResolver libraryReferenceResolver =
file.getProject().getComponent(StandardLibraryReferenceResolver.class);
elements = libraryReferenceResolver.resolveStandardLibrarySymbol(descriptor);
}
if (!elements.isEmpty()) {
return elements.iterator().next();
}
return null;
}
public static List<DescriptorClassMember> membersFromDescriptors(
Iterable<CallableMemberDescriptor> missingImplementations,
JetFile file, Iterable<CallableMemberDescriptor> missingImplementations,
BindingContext bindingContext
) {
List<DescriptorClassMember> members = new ArrayList<DescriptorClassMember>();
for (CallableMemberDescriptor memberDescriptor : missingImplementations) {
List<PsiElement> psiElements = BindingContextUtils.descriptorToDeclarations(bindingContext, memberDescriptor);
DescriptorClassMember member;
if (psiElements.isEmpty()) {
member = new DescriptorClassMember(null, memberDescriptor);
} else {
member = new DescriptorClassMember(psiElements.get(0), memberDescriptor);
}
PsiElement declaration = getDeclaration(file, memberDescriptor, bindingContext);
assert declaration != null : "Can not find declaration for descriptor " + memberDescriptor;
DescriptorClassMember member = new DescriptorClassMember(declaration, memberDescriptor);
members.add(member);
}
return members;
}
public static void generateMethods(Editor editor,
public static void generateMethods(
Editor editor,
JetClassOrObject classOrObject,
List<DescriptorClassMember> selectedElements) {
List<DescriptorClassMember> selectedElements
) {
final JetClassBody body = classOrObject.getBody();
if (body == null) {
return;
@@ -79,11 +96,11 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
}
List<JetElement> elementsToCompact = new ArrayList<JetElement>();
final JetFile file = (JetFile)classOrObject.getContainingFile();
final JetFile file = (JetFile) classOrObject.getContainingFile();
for (JetElement element : generateOverridingMembers(selectedElements, file)) {
PsiElement added = body.addAfter(element, afterAnchor);
afterAnchor = added;
elementsToCompact.add((JetElement)added);
elementsToCompact.add((JetElement) added);
}
ReferenceToClassesShortening.compactReferenceToClasses(elementsToCompact);
}
@@ -116,10 +133,10 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
for (DescriptorClassMember selectedElement : selectedElements) {
final DeclarationDescriptor descriptor = selectedElement.getDescriptor();
if (descriptor instanceof SimpleFunctionDescriptor) {
overridingMembers.add(overrideFunction(file.getProject(), (SimpleFunctionDescriptor)descriptor));
overridingMembers.add(overrideFunction(file.getProject(), (SimpleFunctionDescriptor) descriptor));
}
else if (descriptor instanceof PropertyDescriptor) {
overridingMembers.add(overrideProperty(file.getProject(), (PropertyDescriptor)descriptor));
overridingMembers.add(overrideProperty(file.getProject(), (PropertyDescriptor) descriptor));
}
}
return overridingMembers;
@@ -176,7 +193,8 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
if (!KotlinBuiltIns.getInstance().getDefaultBound().equals(upperBound)) {
if (firstUpperBound) {
bodyBuilder.append(upperBoundText);
} else {
}
else {
whereRestrictions.add(param.getName() + upperBoundText);
}
}
@@ -262,7 +280,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
private static String displayableVisibility(MemberDescriptor descriptor) {
Visibility visibility = descriptor.getVisibility();
return visibility != Visibilities.INTERNAL ? visibility.toString() + " ": "";
return visibility != Visibilities.INTERNAL ? visibility.toString() + " " : "";
}
@NotNull
@@ -276,8 +294,10 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
protected abstract Set<CallableMemberDescriptor> collectMethodsToGenerate(MutableClassDescriptor descriptor);
private MemberChooser<DescriptorClassMember> showOverrideImplementChooser(Project project,
DescriptorClassMember[] members) {
private MemberChooser<DescriptorClassMember> showOverrideImplementChooser(
Project project,
DescriptorClassMember[] members
) {
final MemberChooser<DescriptorClassMember> chooser = new MemberChooser<DescriptorClassMember>(members, true, true, project);
chooser.setTitle(getChooserTitle());
chooser.show();
@@ -305,15 +325,16 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
assert classOrObject != null : "ClassObject should be checked in isValidFor method";
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile)classOrObject.getContainingFile())
.getBindingContext();
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, bindingContext);
List<DescriptorClassMember> members = membersFromDescriptors((JetFile) file, missingImplementations, bindingContext);
final List<DescriptorClassMember> selectedElements;
if (implementAll) {
@@ -198,8 +198,9 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
final JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, JetClassOrObject.class);
assertNotNull("Caret should be inside class or object", classOrObject);
final JetFile jetFile = (JetFile) classOrObject.getContainingFile();
final BindingContext bindingContext = WholeProjectAnalyzerFacade
.analyzeProjectWithCacheOnAFile((JetFile) classOrObject.getContainingFile())
.analyzeProjectWithCacheOnAFile(jetFile)
.getBindingContext();
final Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
@@ -230,7 +231,7 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
OverrideImplementMethodsHandler.generateMethods(
myFixture.getEditor(), classOrObject,
OverrideImplementMethodsHandler
.membersFromDescriptors(Collections.singletonList(singleToOverride), bindingContext));
.membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride), bindingContext));
}
}.execute();
}
@@ -240,8 +241,9 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
final JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, JetClassOrObject.class);
assertNotNull("Caret should be inside class or object", classOrObject);
final JetFile jetFile = (JetFile) classOrObject.getContainingFile();
final BindingContext bindingContext = WholeProjectAnalyzerFacade
.analyzeProjectWithCacheOnAFile((JetFile) classOrObject.getContainingFile())
.analyzeProjectWithCacheOnAFile(jetFile)
.getBindingContext();
final Set<CallableMemberDescriptor> descriptors = handler.collectMethodsToGenerate(classOrObject, bindingContext);
@@ -258,7 +260,7 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
protected void run(Result result) throws Throwable {
OverrideImplementMethodsHandler.generateMethods(
myFixture.getEditor(), classOrObject,
OverrideImplementMethodsHandler.membersFromDescriptors(descriptorsList, bindingContext));
OverrideImplementMethodsHandler.membersFromDescriptors(jetFile, descriptorsList, bindingContext));
}
}.execute();
}