Quick info added in the editor, for debugging purposes
This commit is contained in:
@@ -24,5 +24,6 @@
|
|||||||
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.SoftKeywordsAnnotator"/>
|
<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.LabelsAnnotator"/>
|
||||||
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.JetPsiChecker"/>
|
<annotator language="jet" implementationClass="org.jetbrains.jet.lang.annotations.JetPsiChecker"/>
|
||||||
|
<documentationProvider implementation="org.jetbrains.jet.plugin.JetQuickDocumentationProvider"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.TextRange;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiReference;
|
import com.intellij.psi.PsiReference;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
import com.intellij.psi.tree.TokenSet;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import com.intellij.util.IncorrectOperationException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -61,12 +62,12 @@ public class JetReferenceExpression extends JetExpression {
|
|||||||
@Override
|
@Override
|
||||||
public PsiElement resolve() {
|
public PsiElement resolve() {
|
||||||
PsiElement element = getElement();
|
PsiElement element = getElement();
|
||||||
while (element != null && false == element instanceof JetFile) {
|
JetFile file = PsiTreeUtil.getParentOfType(element, JetFile.class);
|
||||||
element = element.getParent();
|
|
||||||
}
|
|
||||||
JetFile file = (JetFile) element;
|
|
||||||
BindingContext bindingContext = AnalyzingUtils.analyzeFile(file, ErrorHandler.DO_NOTHING);
|
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
|
@NotNull
|
||||||
@@ -87,7 +88,7 @@ public class JetReferenceExpression extends JetExpression {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isReferenceTo(PsiElement element) {
|
public boolean isReferenceTo(PsiElement element) {
|
||||||
return false;
|
return resolve() == element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -51,4 +51,14 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
|
|||||||
public DeclarationDescriptor getOriginal() {
|
public DeclarationDescriptor getOriginal() {
|
||||||
return original.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() {
|
public WritableScope getUnsubstitutedMemberScope() {
|
||||||
return unsubstitutedMemberScope;
|
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.Attribute;
|
||||||
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.types.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.types.DeclarationDescriptorVisitor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class MutableDeclarationDescriptor implements DeclarationDescriptor {
|
public abstract class MutableDeclarationDescriptor implements DeclarationDescriptor {
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -29,4 +30,9 @@ public class MutableDeclarationDescriptor implements DeclarationDescriptor {
|
|||||||
public DeclarationDescriptor getOriginal() {
|
public DeclarationDescriptor getOriginal() {
|
||||||
return this;
|
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);
|
Map<TypeConstructor,TypeProjection> substitutionContext = TypeSubstitutor.INSTANCE.buildSubstitutionContext(typeConstructor.getParameters(), typeArguments);
|
||||||
return new SubstitutingScope(memberDeclarations, substitutionContext);
|
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
|
* returns <code>this</code> object if the current descriptor is original itself
|
||||||
*/
|
*/
|
||||||
DeclarationDescriptor getOriginal();
|
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() {
|
public DeclarationDescriptor getOriginal() {
|
||||||
return this;
|
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;
|
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() {
|
public DeclarationDescriptor getOriginal() {
|
||||||
return propertyDescriptor.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();
|
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;
|
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() {
|
public Type getType() {
|
||||||
return type;
|
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() {
|
public String toString() {
|
||||||
return typeConstructor.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("<", "<");
|
||||||
|
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(" (...)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user