提交 a6b31b6c 编写于 作者: A Andrey Breslav

Beautified line icons and display function signatures

上级 e087b080
......@@ -13,7 +13,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
......@@ -588,7 +588,7 @@ public class ExpressionCodegen extends JetVisitor {
methodDescriptor = typeMapper.mapSignature((JetFunction) declarationPsiElement);
if (functionParent instanceof NamespaceDescriptorImpl && declarationPsiElement instanceof JetFunction) {
pushMethodArguments(expression, methodDescriptor);
final String owner = NamespaceCodegen.getJVMClassName(DescriptorUtil.getFQName(functionParent));
final String owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
v.invokestatic(owner, methodDescriptor.getName(), methodDescriptor.getDescriptor());
}
else if (functionParent instanceof ClassDescriptor && declarationPsiElement instanceof JetFunction) {
......
......@@ -8,7 +8,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method;
......@@ -87,11 +87,11 @@ public class JetTypeMapper {
}
static String jvmName(NamespaceDescriptor namespace) {
return NamespaceCodegen.getJVMClassName(DescriptorUtil.getFQName(namespace));
return NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(namespace));
}
public static String jvmNameForInterface(ClassDescriptor descriptor) {
return DescriptorUtil.getFQName(descriptor).replace('.', '/');
return DescriptorRenderer.getFQName(descriptor).replace('.', '/');
}
public static String jvmNameForImplementation(ClassDescriptor descriptor) {
......
......@@ -16,18 +16,20 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Function;
import com.intellij.util.Icons;
import com.intellij.util.PsiNavigateUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
......@@ -46,69 +48,78 @@ public class JetLineMarkerProvider implements LineMarkerProvider {
JetFile file = PsiTreeUtil.getParentOfType(element, JetFile.class);
assert file != null;
final BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file);
FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(jetFunction);
final FunctionDescriptor functionDescriptor = bindingContext.getFunctionDescriptor(jetFunction);
if (functionDescriptor == null) return null;
final Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenFunctions();
if (!overriddenFunctions.isEmpty()) {
return new LineMarkerInfo<JetFunction>(
jetFunction, jetFunction.getTextOffset(), OVERRIDING_FUNCTION, Pass.UPDATE_ALL,
new Function<JetFunction, String>() {
@Override
public String fun(JetFunction jetFunction) {
StringBuilder builder = new StringBuilder();
for (Iterator<? extends FunctionDescriptor> iterator = overriddenFunctions.iterator(); iterator.hasNext(); ) {
FunctionDescriptor overriddenFunction = iterator.next();
builder.append(DescriptorUtil.renderPresentableText(overriddenFunction).replace("<", "&lt;"));
if (iterator.hasNext()) {
builder.append("<br/>");
}
}
return builder.toString();
Icon icon = isMember(functionDescriptor) ? (overriddenFunctions.isEmpty() ? Icons.METHOD_ICON : OVERRIDING_FUNCTION) : Icons.FUNCTION_ICON;
return new LineMarkerInfo<JetFunction>(
jetFunction, jetFunction.getTextOffset(), icon, Pass.UPDATE_ALL,
new Function<JetFunction, String>() {
@Override
public String fun(JetFunction jetFunction) {
StringBuilder builder = new StringBuilder();
builder.append(DescriptorRenderer.HTML.render(functionDescriptor));
int overrideCount = overriddenFunctions.size();
if (overrideCount >= 1) {
builder.append(" overrides ").append(DescriptorRenderer.HTML.render(overriddenFunctions.iterator().next()));
}
},
new GutterIconNavigationHandler<JetFunction>() {
@Override
public void navigate(MouseEvent event, JetFunction elt) {
final List<PsiElement> list = Lists.newArrayList();
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(overriddenFunction);
list.add(declarationPsiElement);
}
if (list.isEmpty()) {
String myEmptyText = "empty text";
final JComponent renderer = HintUtil.createErrorLabel(myEmptyText);
final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(renderer, renderer).createPopup();
if (event != null) {
popup.show(new RelativePoint(event));
}
return;
if (overrideCount > 1) {
int count = overrideCount - 1;
builder.append(" and ").append(count).append(" other function");
if (count > 1) {
builder.append("s");
}
if (list.size() == 1) {
PsiNavigateUtil.navigate(list.iterator().next());
}
return builder.toString();
}
},
new GutterIconNavigationHandler<JetFunction>() {
@Override
public void navigate(MouseEvent event, JetFunction elt) {
final List<PsiElement> list = Lists.newArrayList();
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
PsiElement declarationPsiElement = bindingContext.getDeclarationPsiElement(overriddenFunction);
list.add(declarationPsiElement);
}
if (list.isEmpty()) {
String myEmptyText = "empty text";
final JComponent renderer = HintUtil.createErrorLabel(myEmptyText);
final JBPopup popup = JBPopupFactory.getInstance().createComponentPopupBuilder(renderer, renderer).createPopup();
if (event != null) {
popup.show(new RelativePoint(event));
}
else {
final JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilBase.toPsiElementArray(list), new DefaultPsiElementCellRenderer() {
@Override
public String getElementText(PsiElement element) {
if (element instanceof JetFunction) {
JetFunction function = (JetFunction) element;
return DescriptorUtil.renderPresentableText(bindingContext.getFunctionDescriptor(function));
}
return super.getElementText(element);
return;
}
if (list.size() == 1) {
PsiNavigateUtil.navigate(list.iterator().next());
}
else {
final JBPopup popup = NavigationUtil.getPsiElementPopup(PsiUtilBase.toPsiElementArray(list), new DefaultPsiElementCellRenderer() {
@Override
public String getElementText(PsiElement element) {
if (element instanceof JetFunction) {
JetFunction function = (JetFunction) element;
return DescriptorRenderer.HTML.render(bindingContext.getFunctionDescriptor(function));
}
}, "title");
if (event != null) {
popup.show(new RelativePoint(event));
}
return super.getElementText(element);
}
}, DescriptorRenderer.HTML.render(functionDescriptor));
if (event != null) {
popup.show(new RelativePoint(event));
}
}
}
);
}
}
);
}
return null;
}
private boolean isMember(@NotNull FunctionDescriptor functionDescriptor) {
return functionDescriptor.getContainingDeclaration().getOriginal() instanceof ClassifierDescriptor;
}
@Override
public void collectSlowLineMarkers(List<PsiElement> elements, Collection<LineMarkerInfo> result) {
}
......
......@@ -2,7 +2,7 @@ package org.jetbrains.jet.lang.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.List;
......@@ -44,6 +44,6 @@ public abstract class DeclarationDescriptorImpl extends AnnotatedImpl implements
@Override
public String toString() {
return DescriptorUtil.renderPresentableText(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]";
return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]";
}
}
......@@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.List;
import java.util.Map;
......@@ -176,6 +176,6 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@Override
public String toString() {
return DescriptorUtil.renderPresentableText(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]";
return DescriptorRenderer.TEXT.render(this) + "[" + getClass().getCanonicalName() + "@" + System.identityHashCode(this) + "]";
}
}
......@@ -13,7 +13,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lexer.JetTokens;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.*;
......@@ -245,7 +245,7 @@ public class JetTypeInferrer {
case SINGLE_FUNCTION_ARGUMENT_MISMATCH:
if (argumentList != null) {
// TODO : More helpful message. NOTE: there's a separate handling for this for constructors
trace.getErrorHandler().genericError(argumentList.getNode(), "Arguments do not match " + DescriptorUtil.renderPresentableText(resolutionResult.getFunctionDescriptor()));
trace.getErrorHandler().genericError(argumentList.getNode(), "Arguments do not match " + DescriptorRenderer.TEXT.render(resolutionResult.getFunctionDescriptor()));
}
else {
trace.getErrorHandler().unresolvedReference(referenceExpression);
......
......@@ -9,7 +9,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.resolve.DescriptorUtil;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import java.util.Collections;
import java.util.List;
......@@ -49,9 +49,7 @@ public class JetQuickDocumentationProvider implements DocumentationProvider {
}
private String render(DeclarationDescriptor declarationDescriptor) {
String text = DescriptorUtil.renderPresentableText(declarationDescriptor);
text = text.replaceAll("<", "&lt;");
return text;
return DescriptorRenderer.HTML.render(declarationDescriptor);
}
@Override
......
......@@ -10,39 +10,69 @@ import java.util.List;
/**
* @author abreslav
*/
public class DescriptorUtil {
public class DescriptorRenderer {
private static final DeclarationDescriptorVisitor<Void, StringBuilder> rootVisitor = new RenderDeclarationDescriptorVisitor();
private static final DeclarationDescriptorVisitor<Void, StringBuilder> subVisitor = new RenderDeclarationDescriptorVisitor() {
public static String getFQName(DeclarationDescriptor descriptor) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container != null && !(container instanceof ModuleDescriptor)) {
String baseName = getFQName(container);
if (!baseName.isEmpty()) return baseName + "." + descriptor.getName();
}
return descriptor.getName();
}
public static final DescriptorRenderer TEXT = new DescriptorRenderer();
public static final DescriptorRenderer HTML = new DescriptorRenderer() {
@Override
protected String escape(String s) {
return s.replaceAll("<", "&lt;");
}
@Override
public String renderKeyword(String keyword) {
return "<b>" + keyword + "</b>";
}
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private final DeclarationDescriptorVisitor<Void, StringBuilder> rootVisitor = new RenderDeclarationDescriptorVisitor();
private final DeclarationDescriptorVisitor<Void, StringBuilder> subVisitor = new RenderDeclarationDescriptorVisitor() {
@Override
protected void renderName(DeclarationDescriptor descriptor, StringBuilder stringBuilder) {
stringBuilder.append(descriptor.getName());
}
};
public static String renderPresentableText(DeclarationDescriptor declarationDescriptor) {
if (declarationDescriptor == null) return "<null>";
StringBuilder stringBuilder = new StringBuilder();
declarationDescriptor.accept(rootVisitor, stringBuilder);
return stringBuilder.toString();
private DescriptorRenderer() {}
protected String renderKeyword(String keyword) {
return keyword;
}
public static String getFQName(DeclarationDescriptor descriptor) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container != null && !(container instanceof ModuleDescriptor)) {
String baseName = getFQName(container);
if (!baseName.isEmpty()) return baseName + "." + descriptor.getName();
}
protected String escape(String s) {
return s;
}
return descriptor.getName();
private String lt() {
return escape("<");
}
private DescriptorUtil() {}
public String render(DeclarationDescriptor declarationDescriptor) {
if (declarationDescriptor == null) return lt() + "null>";
StringBuilder stringBuilder = new StringBuilder();
declarationDescriptor.accept(rootVisitor, stringBuilder);
return stringBuilder.toString();
}
private static class RenderDeclarationDescriptorVisitor extends DeclarationDescriptorVisitor<Void, StringBuilder> {
private class RenderDeclarationDescriptorVisitor extends DeclarationDescriptorVisitor<Void, StringBuilder> {
@Override
public Void visitValueParameterDescriptor(ValueParameterDescriptor descriptor, StringBuilder builder) {
builder.append("value-parameter ");
builder.append(renderKeyword("value-parameter")).append(" ");
return super.visitValueParameterDescriptor(descriptor, builder);
}
......@@ -50,32 +80,32 @@ public class DescriptorUtil {
public Void visitVariableDescriptor(VariableDescriptor descriptor, StringBuilder builder) {
JetType outType = descriptor.getOutType();
JetType inType = descriptor.getInType();
String typeString = "<no type>";
String typeString = lt() + "no type>";
if (inType != null && outType != null) {
builder.append("var ");
builder.append(renderKeyword("var")).append(" ");
if (inType.equals(outType)) {
typeString = outType.toString();
}
else {
typeString = "<in " + inType + " out " + outType + ">";
typeString = "<" + renderKeyword("in") + ": " + inType + " " + renderKeyword("out") + ": " + outType + ">";
}
}
else if (outType != null) {
builder.append("val ");
builder.append(renderKeyword("val")).append(" ");
typeString = outType.toString();
}
else if (inType != null) {
builder.append("<write-only> ");
builder.append(lt()).append("write-only> ");
typeString = inType.toString();
}
renderName(descriptor, builder);
builder.append(" : ").append(typeString);
builder.append(" : ").append(escape(typeString));
return super.visitVariableDescriptor(descriptor, builder);
}
@Override
public Void visitFunctionDescriptor(FunctionDescriptor descriptor, StringBuilder builder) {
builder.append("fun ");
builder.append(renderKeyword("fun")).append(" ");
renderName(descriptor, builder);
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeParameters();
renderTypeParameters(typeParameters, builder);
......@@ -87,13 +117,13 @@ public class DescriptorUtil {
builder.append(", ");
}
}
builder.append(") : ").append(descriptor.getUnsubstitutedReturnType());
builder.append(") : ").append(escape(descriptor.getUnsubstitutedReturnType().toString()));
return super.visitFunctionDescriptor(descriptor, builder);
}
private void renderTypeParameters(List<TypeParameterDescriptor> typeParameters, StringBuilder builder) {
if (!typeParameters.isEmpty()) {
builder.append("<");
builder.append(lt());
for (Iterator<TypeParameterDescriptor> iterator = typeParameters.iterator(); iterator.hasNext(); ) {
TypeParameterDescriptor typeParameterDescriptor = iterator.next();
typeParameterDescriptor.accept(subVisitor, builder);
......@@ -107,7 +137,7 @@ public class DescriptorUtil {
@Override
public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, StringBuilder builder) {
builder.append("<");
builder.append(lt());
renderTypeParameter(descriptor, builder);
builder.append(">");
return super.visitTypeParameterDescriptor(descriptor, builder);
......@@ -115,14 +145,14 @@ public class DescriptorUtil {
@Override
public Void visitNamespaceDescriptor(NamespaceDescriptor namespaceDescriptor, StringBuilder builder) {
builder.append("namespace ");
builder.append(renderKeyword("namespace")).append(" ");
renderName(namespaceDescriptor, builder);
return super.visitNamespaceDescriptor(namespaceDescriptor, builder);
}
@Override
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
builder.append("class ");
builder.append(renderKeyword("class")).append(" ");
renderName(descriptor, builder);
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
Collection<? extends JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
......@@ -145,7 +175,7 @@ public class DescriptorUtil {
renderName(containingDeclaration, stringBuilder);
stringBuilder.append("::");
}
stringBuilder.append(descriptor.getName());
stringBuilder.append(escape(descriptor.getName()));
}
private void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder) {
......
......@@ -120,7 +120,7 @@ public class ExpectedResolveData {
assertTrue(
"Must have been unresolved: " +
renderReferenceInContext(referenceExpression) +
" but was resolved to " + DescriptorUtil.renderPresentableText(bindingContext.resolveReferenceExpression(referenceExpression)),
" but was resolved to " + DescriptorRenderer.TEXT.render(bindingContext.resolveReferenceExpression(referenceExpression)),
unresolvedReferences.contains(referenceExpression));
continue;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册