Quick info added in the editor, for debugging purposes

This commit is contained in:
Andrey Breslav
2011-03-10 20:10:42 +03:00
parent c1677055b0
commit 72d7cf0d4d
18 changed files with 233 additions and 44 deletions
+1
View File
@@ -24,5 +24,6 @@
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.SoftKeywordsAnnotator"/>
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.LabelsAnnotator"/>
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.JetPsiChecker"/>
<documentationProvider implementation="org.jetbrains.jet.plugin.JetQuickDocumentationProvider"/>
</extensions>
</idea-plugin>
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -61,12 +62,12 @@ public class JetReferenceExpression extends JetExpression {
@Override
public PsiElement resolve() {
PsiElement element = getElement();
while (element != null && false == element instanceof JetFile) {
element = element.getParent();
}
JetFile file = (JetFile) element;
JetFile file = PsiTreeUtil.getParentOfType(element, JetFile.class);
BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, ErrorHandler.DO_NOTHING);
return bindingContext.resolveToDeclarationPsiElement(JetReferenceExpression.this);
PsiElement psiElement = bindingContext.resolveToDeclarationPsiElement(JetReferenceExpression.this);
return psiElement == null
? file
: psiElement;
}
@NotNull
@@ -87,7 +88,7 @@ public class JetReferenceExpression extends JetExpression {
@Override
public boolean isReferenceTo(PsiElement element) {
return false;
return resolve() == element;
}
@NotNull
@@ -51,4 +51,14 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
public DeclarationDescriptor getOriginal() {
return original.getOriginal();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
throw new UnsupportedOperationException(); // TODO
}
}
@@ -37,4 +37,9 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
public WritableScope getUnsubstitutedMemberScope() {
return unsubstitutedMemberScope;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
}
}
@@ -2,13 +2,14 @@ package org.jetbrains.jet.lang.resolve;
import org.jetbrains.jet.lang.types.Attribute;
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
import org.jetbrains.jet.lang.types.DeclarationDescriptorVisitor;
import java.util.List;
/**
* @author abreslav
*/
public class MutableDeclarationDescriptor implements DeclarationDescriptor {
public abstract class MutableDeclarationDescriptor implements DeclarationDescriptor {
private String name;
@Override
@@ -29,4 +30,9 @@ public class MutableDeclarationDescriptor implements DeclarationDescriptor {
public DeclarationDescriptor getOriginal() {
return this;
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
accept(visitor, null);
}
}
@@ -1,37 +0,0 @@
package org.jetbrains.jet.lang.resolve;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.types.FunctionDescriptor;
import org.jetbrains.jet.lang.types.Type;
import org.jetbrains.jet.lang.types.TypeParameterDescriptor;
import org.jetbrains.jet.lang.types.ValueParameterDescriptor;
import java.util.List;
/**
* @author abreslav
*/
public class MutableFunctionDescriptor extends MutableDeclarationDescriptor implements FunctionDescriptor {
@NotNull
@Override
public List<TypeParameterDescriptor> getTypeParameters() {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public List<ValueParameterDescriptor> getUnsubstitutedValueParameters() {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public Type getUnsubstitutedReturnType() {
throw new UnsupportedOperationException(); // TODO
}
@Override
public FunctionDescriptor getOriginal() {
throw new UnsupportedOperationException(); // TODO
}
}
@@ -45,4 +45,9 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
Map<TypeConstructor,TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
return new SubstitutingScope(memberDeclarations, substitutionContext);
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassDescriptor(this, data);
}
}
@@ -11,4 +11,7 @@ public interface DeclarationDescriptor extends Annotated, Named {
* returns <code>this</code> object if the current descriptor is original itself
*/
DeclarationDescriptor getOriginal();
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor);
}
@@ -23,4 +23,9 @@ public abstract class DeclarationDescriptorImpl extends AnnotatedImpl implements
public DeclarationDescriptor getOriginal() {
return this;
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
accept(visitor, null);
}
}
@@ -0,0 +1,28 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.jet.lang.resolve.LazySubstitutingClassDescriptor;
/**
* @author abreslav
*/
public class DeclarationDescriptorVisitor<R, D> {
public R visitPropertyDescriptor(PropertyDescriptor descriptor, D data) {
return null;
}
public R visitFunctionDescriptor(FunctionDescriptor descriptor, D data) {
return null;
}
public R visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, D data) {
return null;
}
public R visitNamespaceDescriptor(NamespaceDescriptor namespaceDescriptor, D data) {
return null;
}
public R visitClassDescriptor(ClassDescriptor descriptor, D data) {
return null;
}
}
@@ -55,4 +55,8 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
return original;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitFunctionDescriptor(this, data);
}
}
@@ -41,4 +41,14 @@ public class LazySubstitutedPropertyDescriptorImpl implements PropertyDescriptor
public DeclarationDescriptor getOriginal() {
return propertyDescriptor.getOriginal();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitPropertyDescriptor(this, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
accept(visitor, null);
}
}
@@ -74,6 +74,14 @@ public class LazySubstitutingFunctionDescriptor implements FunctionDescriptor {
return functionDescriptor.getName();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitFunctionDescriptor(this, data);
}
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
accept(visitor, null);
}
}
@@ -26,4 +26,9 @@ public class NamespaceDescriptor extends DeclarationDescriptorImpl {
}
return namespaceType;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitNamespaceDescriptor(this, data);
}
}
@@ -17,4 +17,9 @@ public class PropertyDescriptorImpl extends DeclarationDescriptorImpl implements
public Type getType() {
return type;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitPropertyDescriptor(this, data);
}
}
@@ -45,4 +45,9 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl {
public String toString() {
return typeConstructor.toString();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitTypeParameterDescriptor(this, data);
}
}
@@ -0,0 +1,34 @@
package org.jetbrains.jet.plugin;
import com.intellij.lang.documentation.QuickDocumentationProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.jet.lang.ErrorHandler;
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.lang.types.DeclarationDescriptor;
import org.jetbrains.jet.resolve.DescriptorUtil;
/**
* @author abreslav
*/
public class JetQuickDocumentationProvider extends QuickDocumentationProvider {
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
JetReferenceExpression ref = PsiTreeUtil.getParentOfType(originalElement, JetReferenceExpression.class);
if (ref != null) {
BindingContext bindingContext = AnalyzingUtils.analyzeFile(PsiTreeUtil.getParentOfType(originalElement, JetFile.class), ErrorHandler.DO_NOTHING);
DeclarationDescriptor declarationDescriptor = bindingContext.resolveReferenceExpression(ref);
if (declarationDescriptor != null) {
String text = DescriptorUtil.renderPresentableText(declarationDescriptor);
text = text.replaceAll("<", "&lt;");
return text;
}
return "Unresolved";
}
return "Not a reference";
}
}
@@ -0,0 +1,91 @@
package org.jetbrains.jet.resolve;
import org.jetbrains.jet.lang.types.*;
import java.util.Iterator;
import java.util.List;
/**
* @author abreslav
*/
public class DescriptorUtil {
public static String renderPresentableText(DeclarationDescriptor declarationDescriptor) {
StringBuilder stringBuilder = new StringBuilder();
declarationDescriptor.accept(
new DeclarationDescriptorVisitor<Void, StringBuilder>() {
@Override
public Void visitPropertyDescriptor(PropertyDescriptor descriptor, StringBuilder builder) {
Type type = descriptor.getType();
builder.append(descriptor.getName()).append(" : ").append(type);
return super.visitPropertyDescriptor(descriptor, builder);
}
@Override
public Void visitFunctionDescriptor(FunctionDescriptor descriptor, StringBuilder builder) {
builder.append("fun ").append(descriptor.getName());
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeParameters();
renderTypeParameters(typeParameters, builder);
builder.append("(");
for (Iterator<ValueParameterDescriptor> iterator = descriptor.getUnsubstitutedValueParameters().iterator(); iterator.hasNext(); ) {
ValueParameterDescriptor parameterDescriptor = iterator.next();
visitPropertyDescriptor(parameterDescriptor, builder);
if (iterator.hasNext()) {
builder.append(", ");
}
}
builder.append(") : ").append(descriptor.getUnsubstitutedReturnType());
return super.visitFunctionDescriptor(descriptor, builder);
}
private void renderTypeParameters(List<TypeParameterDescriptor> typeParameters, StringBuilder builder) {
if (!typeParameters.isEmpty()) {
builder.append("<");
for (Iterator<TypeParameterDescriptor> iterator = typeParameters.iterator(); iterator.hasNext(); ) {
TypeParameterDescriptor typeParameterDescriptor = iterator.next();
renderTypeParameter(typeParameterDescriptor, builder);
if (iterator.hasNext()) {
builder.append(", ");
}
}
builder.append(">");
}
}
@Override
public Void visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, StringBuilder builder) {
builder.append("<");
renderTypeParameter(descriptor, builder);
builder.append(">");
return super.visitTypeParameterDescriptor(descriptor, builder);
}
@Override
public Void visitNamespaceDescriptor(NamespaceDescriptor namespaceDescriptor, StringBuilder builder) {
builder.append("namespace ").append(namespaceDescriptor.getName());
return super.visitNamespaceDescriptor(namespaceDescriptor, builder);
}
@Override
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
builder.append("class ").append(descriptor.getName());
renderTypeParameters(descriptor.getTypeConstructor().getParameters(), builder);
return super.visitClassDescriptor(descriptor, builder);
}
},
stringBuilder);
return stringBuilder.toString();
}
private static void renderTypeParameter(TypeParameterDescriptor descriptor, StringBuilder builder) {
builder.append(descriptor.getName());
if (!descriptor.getUpperBounds().isEmpty()) {
Type bound = descriptor.getUpperBounds().iterator().next();
if (bound != JetStandardClasses.getAnyType()) {
builder.append(" : ").append(bound);
if (descriptor.getUpperBounds().size() > 1) {
builder.append(" (...)");
}
}
}
}
}