KT-984 Make structure window work with kotlin files
This commit is contained in:
@@ -5,7 +5,6 @@ import com.google.common.collect.Sets;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
||||||
@@ -188,5 +187,4 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||||
return visitor.visitFunctionDescriptor(this, data);
|
return visitor.visitFunctionDescriptor(this, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ public class JetIconProvider extends IconProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Icon getIcon(@NotNull PsiElement psiElement, int flags) {
|
public Icon getIcon(@NotNull PsiElement psiElement, int flags) {
|
||||||
|
if (psiElement instanceof JetFile) {
|
||||||
|
return KOTLIN_ICON;
|
||||||
|
}
|
||||||
if (psiElement instanceof JetNamespaceHeader) {
|
if (psiElement instanceof JetNamespaceHeader) {
|
||||||
return (flags & Iconable.ICON_FLAG_OPEN) != 0 ? PlatformIcons.PACKAGE_OPEN_ICON : PlatformIcons.PACKAGE_ICON;
|
return (flags & Iconable.ICON_FLAG_OPEN) != 0 ? PlatformIcons.PACKAGE_OPEN_ICON : PlatformIcons.PACKAGE_ICON;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,16 @@ import com.intellij.navigation.ItemPresentation;
|
|||||||
import com.intellij.openapi.util.Iconable;
|
import com.intellij.openapi.util.Iconable;
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.psi.NavigatablePsiElement;
|
import com.intellij.psi.NavigatablePsiElement;
|
||||||
|
import com.intellij.util.Function;
|
||||||
import com.intellij.util.PsiIconUtil;
|
import com.intellij.util.PsiIconUtil;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -19,8 +27,17 @@ import java.util.List;
|
|||||||
public class JetStructureViewElement implements StructureViewTreeElement {
|
public class JetStructureViewElement implements StructureViewTreeElement {
|
||||||
private final NavigatablePsiElement myElement;
|
private final NavigatablePsiElement myElement;
|
||||||
|
|
||||||
public JetStructureViewElement(NavigatablePsiElement element) {
|
// For file context will be updated after each construction
|
||||||
|
// For other tree sub-elements it's immutable.
|
||||||
|
private BindingContext context;
|
||||||
|
|
||||||
|
public JetStructureViewElement(NavigatablePsiElement element, BindingContext context) {
|
||||||
myElement = element;
|
myElement = element;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JetStructureViewElement(JetFile fileElement) {
|
||||||
|
myElement = fileElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -48,13 +65,29 @@ public class JetStructureViewElement implements StructureViewTreeElement {
|
|||||||
return new ItemPresentation() {
|
return new ItemPresentation() {
|
||||||
@Override
|
@Override
|
||||||
public String getPresentableText() {
|
public String getPresentableText() {
|
||||||
String name = myElement.getName();
|
String text = "";
|
||||||
if (StringUtil.isEmpty(name)) {
|
|
||||||
|
// Try to find text in correspondent descriptor
|
||||||
|
// if (myElement instanceof JetDeclaration) {
|
||||||
|
// JetDeclaration declaration = (JetDeclaration) myElement;
|
||||||
|
// final DeclarationDescriptor descriptor =
|
||||||
|
// context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
|
||||||
|
//
|
||||||
|
// if (descriptor != null) {
|
||||||
|
// text = getDescriptorTreeText(descriptor);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (StringUtil.isEmpty(text)) {
|
||||||
|
text = myElement.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtil.isEmpty(text)) {
|
||||||
if (myElement instanceof JetClassInitializer) {
|
if (myElement instanceof JetClassInitializer) {
|
||||||
return "<class initializer>";
|
return "<class initializer>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return name;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,20 +97,26 @@ public class JetStructureViewElement implements StructureViewTreeElement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Icon getIcon(boolean open) {
|
public Icon getIcon(boolean open) {
|
||||||
return myElement.isValid()
|
if (myElement.isValid()) {
|
||||||
? PsiIconUtil.getProvidersIcon(myElement, open ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED)
|
return PsiIconUtil.getProvidersIcon(
|
||||||
: null;
|
myElement,
|
||||||
|
open ? Iconable.ICON_FLAG_OPEN : Iconable.ICON_FLAG_CLOSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TreeElement[] getChildren() {
|
public TreeElement[] getChildren() {
|
||||||
if (myElement instanceof JetFile) {
|
if (myElement instanceof JetFile) {
|
||||||
return new TreeElement[] { new JetStructureViewElement(myElement) };
|
final JetFile jetFile = (JetFile) myElement;
|
||||||
}
|
|
||||||
else if (myElement instanceof JetFile) {
|
// TODO: Understand why it significantly reduce responsibility of IDEA during typing
|
||||||
return wrapDeclarations(((JetFile) myElement).getDeclarations());
|
// context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(jetFile);
|
||||||
|
|
||||||
|
return wrapDeclarations(jetFile.getDeclarations());
|
||||||
}
|
}
|
||||||
else if (myElement instanceof JetClass) {
|
else if (myElement instanceof JetClass) {
|
||||||
JetClass jetClass = (JetClass) myElement;
|
JetClass jetClass = (JetClass) myElement;
|
||||||
@@ -89,19 +128,68 @@ public class JetStructureViewElement implements StructureViewTreeElement {
|
|||||||
}
|
}
|
||||||
declarations.addAll(jetClass.getDeclarations());
|
declarations.addAll(jetClass.getDeclarations());
|
||||||
return wrapDeclarations(declarations);
|
return wrapDeclarations(declarations);
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (myElement instanceof JetClassOrObject) {
|
else if (myElement instanceof JetClassOrObject) {
|
||||||
return wrapDeclarations(((JetClassOrObject) myElement).getDeclarations());
|
return wrapDeclarations(((JetClassOrObject) myElement).getDeclarations());
|
||||||
}
|
}
|
||||||
return new TreeElement[0];
|
return new TreeElement[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TreeElement[] wrapDeclarations(List<JetDeclaration> declarations) {
|
private TreeElement[] wrapDeclarations(List<JetDeclaration> declarations) {
|
||||||
TreeElement[] result = new TreeElement[declarations.size()];
|
TreeElement[] result = new TreeElement[declarations.size()];
|
||||||
for (int i = 0; i < declarations.size(); i++) {
|
for (int i = 0; i < declarations.size(); i++) {
|
||||||
result[i] = new JetStructureViewElement(declarations.get(i));
|
result[i] = new JetStructureViewElement(declarations.get(i), context);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getDescriptorTreeText(@NotNull DeclarationDescriptor descriptor) {
|
||||||
|
StringBuilder textBuilder;
|
||||||
|
|
||||||
|
if (descriptor instanceof FunctionDescriptor) {
|
||||||
|
textBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||||
|
ReceiverDescriptor receiver = functionDescriptor.getReceiverParameter();
|
||||||
|
if (receiver.exists()) {
|
||||||
|
textBuilder.append(DescriptorRenderer.TEXT.renderType(receiver.getType())).append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
textBuilder.append(functionDescriptor.getName());
|
||||||
|
|
||||||
|
String parametersString = StringUtil.join(
|
||||||
|
functionDescriptor.getValueParameters(),
|
||||||
|
new Function<ValueParameterDescriptor, String>() {
|
||||||
|
@Override
|
||||||
|
public String fun(ValueParameterDescriptor valueParameterDescriptor) {
|
||||||
|
return valueParameterDescriptor.getName() + ":" +
|
||||||
|
DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
",");
|
||||||
|
|
||||||
|
textBuilder.append("(").append(parametersString).append(")");
|
||||||
|
|
||||||
|
JetType returnType = functionDescriptor.getReturnType();
|
||||||
|
textBuilder.append(":").append(DescriptorRenderer.TEXT.renderType(returnType));
|
||||||
|
}
|
||||||
|
else if (descriptor instanceof VariableDescriptor) {
|
||||||
|
JetType outType = ((VariableDescriptor) descriptor).getOutType();
|
||||||
|
|
||||||
|
textBuilder = new StringBuilder(descriptor.getName());
|
||||||
|
textBuilder.append(":").append(DescriptorRenderer.TEXT.renderType(outType));
|
||||||
|
}
|
||||||
|
else if (descriptor instanceof ClassDescriptor) {
|
||||||
|
textBuilder = new StringBuilder(descriptor.getName());
|
||||||
|
textBuilder
|
||||||
|
.append(" (")
|
||||||
|
.append(DescriptorUtils.getFQName(descriptor.getContainingDeclaration()))
|
||||||
|
.append(")");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return DescriptorRenderer.TEXT.render(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return textBuilder.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
|
|||||||
import com.intellij.lang.PsiStructureViewFactory;
|
import com.intellij.lang.PsiStructureViewFactory;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -13,12 +14,18 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public class JetStructureViewFactory implements PsiStructureViewFactory {
|
public class JetStructureViewFactory implements PsiStructureViewFactory {
|
||||||
@Override
|
@Override
|
||||||
public StructureViewBuilder getStructureViewBuilder(final PsiFile psiFile) {
|
public StructureViewBuilder getStructureViewBuilder(final PsiFile psiFile) {
|
||||||
return new TreeBasedStructureViewBuilder() {
|
if (psiFile instanceof JetFile) {
|
||||||
@NotNull
|
final JetFile file = (JetFile) psiFile;
|
||||||
@Override
|
|
||||||
public StructureViewModel createStructureViewModel() {
|
return new TreeBasedStructureViewBuilder() {
|
||||||
return new JetStructureViewModel(psiFile);
|
@NotNull
|
||||||
}
|
@Override
|
||||||
};
|
public StructureViewModel createStructureViewModel() {
|
||||||
|
return new JetStructureViewModel(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package org.jetbrains.jet.plugin.structureView;
|
package org.jetbrains.jet.plugin.structureView;
|
||||||
|
|
||||||
import com.intellij.ide.structureView.StructureViewModelBase;
|
import com.intellij.ide.structureView.StructureViewModelBase;
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public class JetStructureViewModel extends StructureViewModelBase {
|
public class JetStructureViewModel extends StructureViewModelBase {
|
||||||
public JetStructureViewModel(@NotNull PsiFile psiFile) {
|
public JetStructureViewModel(@NotNull JetFile jetFile) {
|
||||||
super(psiFile, new JetStructureViewElement(psiFile));
|
super(jetFile, new JetStructureViewElement(jetFile));
|
||||||
withSuitableClasses(JetDeclaration.class);
|
withSuitableClasses(JetDeclaration.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user