Simplistic navigation supported in the editor (for debugging purposes)

This commit is contained in:
Andrey Breslav
2011-03-01 13:33:11 +03:00
parent 9b12696cb3
commit ecc2300f79
10 changed files with 170 additions and 43 deletions
@@ -27,7 +27,14 @@ public class JetPsiChecker implements Annotator {
for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) { for (JetDelegationSpecifier specifier : klass.getDelegationSpecifiers()) {
JetTypeReference typeReference = specifier.getTypeReference(); JetTypeReference typeReference = specifier.getTypeReference();
Type type = bindingContext.resolveTypeReference(typeReference); Type type = bindingContext.resolveTypeReference(typeReference);
holder.createInfoAnnotation(typeReference, type.toString()); holder.createWeakWarningAnnotation(typeReference, type.toString());
}
}
@Override
public void visitNamespace(JetNamespace namespace) {
for (JetDeclaration declaration : namespace.getDeclarations()) {
declaration.accept(this);
} }
} }
}); });
@@ -1,9 +1,16 @@
package org.jetbrains.jet.lang.psi; package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
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.tree.TokenSet;
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;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
/** /**
@@ -33,4 +40,68 @@ public class JetReferenceExpression extends JetExpression {
public void accept(JetVisitor visitor) { public void accept(JetVisitor visitor) {
visitor.visitReferenceExpression(this); visitor.visitReferenceExpression(this);
} }
@Override
public PsiReference findReferenceAt(int offset) {
return getReference();
}
@Override
public PsiReference getReference() {
return new PsiReference() {
@Override
public PsiElement getElement() {
return findChildByType(REFERENCE_TOKENS);
}
@Override
public TextRange getRangeInElement() {
return new TextRange(0, getElement().getTextLength());
}
@Override
public PsiElement resolve() {
PsiElement element = getElement();
while (element != null && false == element instanceof JetFile) {
element = element.getParent();
}
JetFile file = (JetFile) element;
JetSemanticServices semanticServices = new JetSemanticServices(element.getProject());
BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
return bindingContext.resolveToDeclarationPsiElement(JetReferenceExpression.this);
}
@NotNull
@Override
public String getCanonicalText() {
throw new UnsupportedOperationException(); // TODO
}
@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
throw new UnsupportedOperationException(); // TODO
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
throw new UnsupportedOperationException(); // TODO
}
@Override
public boolean isReferenceTo(PsiElement element) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
public Object[] getVariants() {
throw new UnsupportedOperationException(); // TODO
}
@Override
public boolean isSoft() {
throw new UnsupportedOperationException(); // TODO
}
};
}
} }
@@ -1,20 +1,50 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface BindingContext { public class BindingContext {
NamespaceDescriptor getNamespaceDescriptor(JetNamespace declaration); public NamespaceDescriptor getNamespaceDescriptor(JetNamespace declaration) {
ClassDescriptor getClassDescriptor(JetClass declaration); return null;
FunctionDescriptor getFunctionDescriptor(JetFunction declaration); }
PropertyDescriptor getPropertyDescriptor(JetProperty declaration);
Type getExpressionType(JetExpression expression); public ClassDescriptor getClassDescriptor(JetClass declaration) {
JetScope getTopLevelScope(); return null;
}
public FunctionDescriptor getFunctionDescriptor(JetFunction declaration) {
return null;
}
public PropertyDescriptor getPropertyDescriptor(JetProperty declaration) {
return null;
}
public Type getExpressionType(JetExpression expression) {
return null;
}
public JetScope getTopLevelScope() {
return null;
}
public DeclarationDescriptor resolveReferenceExpression(JetReferenceExpression referenceExpression) {
return null;
}
public Type resolveTypeReference(JetTypeReference typeReference) {
return null;
}
public PsiElement resolveToDeclarationPsiElement(JetReferenceExpression referenceExpression) {
return null;
}
DeclarationDescriptor resolveReferenceExpression(JetReferenceExpression referenceExpression);
Type resolveTypeReference(JetTypeReference typeReference);
} }
@@ -16,10 +16,12 @@ public class ClassDescriptorResolver {
private final JetSemanticServices semanticServices; private final JetSemanticServices semanticServices;
private final TypeResolver typeResolver; private final TypeResolver typeResolver;
private final BindingTrace trace;
public ClassDescriptorResolver(JetSemanticServices semanticServices, BindingTrace trace) { public ClassDescriptorResolver(JetSemanticServices semanticServices, BindingTrace trace) {
this.semanticServices = semanticServices; this.semanticServices = semanticServices;
this.typeResolver = new TypeResolver(trace); this.typeResolver = new TypeResolver(trace);
this.trace = trace;
} }
@Nullable @Nullable
@@ -72,6 +74,8 @@ public class ClassDescriptorResolver {
typeParameters, typeParameters,
superclasses) superclasses)
); );
trace.recordDeclarationResolution(classElement, descriptor);
} }
private WritableScope resolveMembers( private WritableScope resolveMembers(
@@ -165,6 +169,7 @@ public class ClassDescriptorResolver {
// TODO : Default values??? // TODO : Default values???
result.add(valueParameterDescriptor); result.add(valueParameterDescriptor);
trace.recordDeclarationResolution(valueParameter, valueParameterDescriptor);
parameterScope.addPropertyDescriptor(valueParameterDescriptor); parameterScope.addPropertyDescriptor(valueParameterDescriptor);
} }
return result; return result;
@@ -1,15 +1,14 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import org.jetbrains.jet.lang.types.Annotated;
import org.jetbrains.jet.lang.types.Attribute; import org.jetbrains.jet.lang.types.Attribute;
import org.jetbrains.jet.lang.types.Named; import org.jetbrains.jet.lang.types.DeclarationDescriptor;
import java.util.List; import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public class MutableDeclarationDescriptor implements Annotated, Named { public class MutableDeclarationDescriptor implements DeclarationDescriptor {
private String name; private String name;
@Override @Override
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.resolve; package org.jetbrains.jet.lang.resolve;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
@@ -14,13 +15,15 @@ public class TopDownAnalyzer {
private final Map<JetClass, MutableClassDescriptor> classes = new LinkedHashMap<JetClass, MutableClassDescriptor>(); private final Map<JetClass, MutableClassDescriptor> classes = new LinkedHashMap<JetClass, MutableClassDescriptor>();
private final Map<JetFunction, FunctionDescriptor> functions = new HashMap<JetFunction, FunctionDescriptor>(); private final Map<JetFunction, FunctionDescriptor> functions = new HashMap<JetFunction, FunctionDescriptor>();
private Map<JetProperty, PropertyDescriptor> properties = new HashMap<JetProperty, PropertyDescriptor>();
private final Map<JetDeclaration, WritableScope> declaringScopes = new HashMap<JetDeclaration, WritableScope>(); private final Map<JetDeclaration, WritableScope> declaringScopes = new HashMap<JetDeclaration, WritableScope>();
private Map<JetExpression, Type> expressionTypes = new HashMap<JetExpression, Type>(); private final Map<JetProperty, PropertyDescriptor> properties = new HashMap<JetProperty, PropertyDescriptor>();
private Map<JetReferenceExpression,DeclarationDescriptor> resolutionResults = new HashMap<JetReferenceExpression, DeclarationDescriptor>(); private final Map<JetExpression, Type> expressionTypes = new HashMap<JetExpression, Type>();
private final Map<JetReferenceExpression, DeclarationDescriptor> resolutionResults = new HashMap<JetReferenceExpression, DeclarationDescriptor>();
private final Map<JetTypeReference, Type> types = new HashMap<JetTypeReference, Type>();
private final Map<DeclarationDescriptor, JetDeclaration> descriptorToDeclarations = new HashMap<DeclarationDescriptor, JetDeclaration>();
private final JetSemanticServices semanticServices; private final JetSemanticServices semanticServices;
private Map<JetTypeReference, Type> types = new HashMap<JetTypeReference, Type>();
private final ClassDescriptorResolver classDescriptorResolver; private final ClassDescriptorResolver classDescriptorResolver;
public TopDownAnalyzer(JetSemanticServices semanticServices) { public TopDownAnalyzer(JetSemanticServices semanticServices) {
@@ -28,18 +31,23 @@ public class TopDownAnalyzer {
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, new BindingTrace() { this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, new BindingTrace() {
@Override @Override
public void recordExpressionType(JetExpression expression, Type type) { public void recordExpressionType(JetExpression expression, Type type) {
throw new UnsupportedOperationException(); // TODO expressionTypes.put(expression, type);
} }
@Override @Override
public void recordResolutionResult(JetReferenceExpression expression, DeclarationDescriptor descriptor) { public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
throw new UnsupportedOperationException(); // TODO resolutionResults.put(expression, descriptor);
} }
@Override @Override
public void recordTypeResoltion(JetTypeReference typeReference, Type type) { public void recordTypeResolution(JetTypeReference typeReference, Type type) {
types.put(typeReference, type); types.put(typeReference, type);
} }
@Override
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
descriptorToDeclarations.put(descriptor, declaration);
}
}); });
} }
@@ -90,6 +98,11 @@ public class TopDownAnalyzer {
public JetScope getTopLevelScope() { public JetScope getTopLevelScope() {
return toplevelScope; return toplevelScope;
} }
@Override
public PsiElement resolveToDeclarationPsiElement(JetReferenceExpression referenceExpression) {
return descriptorToDeclarations.get(resolveReferenceExpression(referenceExpression));
}
}; };
} }
@@ -237,14 +250,19 @@ public class TopDownAnalyzer {
} }
@Override @Override
public void recordResolutionResult(JetReferenceExpression expression, DeclarationDescriptor descriptor) { public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
resolutionResults.put(expression, descriptor); resolutionResults.put(expression, descriptor);
} }
@Override @Override
public void recordTypeResoltion(JetTypeReference typeReference, Type type) { public void recordTypeResolution(JetTypeReference typeReference, Type type) {
types.put(typeReference, type); types.put(typeReference, type);
} }
@Override
public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
throw new IllegalStateException();
}
}).getType(scope, expression, preferBlock); }).getType(scope, expression, preferBlock);
} }
@@ -27,7 +27,7 @@ public class TypeResolver {
JetTypeElement typeElement = typeReference.getTypeElement(); JetTypeElement typeElement = typeReference.getTypeElement();
Type type = resolveTypeElement(scope, attributes, typeElement, false); Type type = resolveTypeElement(scope, attributes, typeElement, false);
trace.recordTypeResoltion(typeReference, type); trace.recordTypeResolution(typeReference, type);
return type; return type;
} }
@@ -37,6 +37,7 @@ public class TypeResolver {
@Override @Override
public void visitUserType(JetUserType type) { public void visitUserType(JetUserType type) {
ClassDescriptor classDescriptor = resolveClass(scope, type); ClassDescriptor classDescriptor = resolveClass(scope, type);
trace.recordReferenceResolution(type.getReferenceExpression(), classDescriptor);
if (classDescriptor != null) { if (classDescriptor != null) {
TypeConstructor typeConstructor = classDescriptor.getTypeConstructor(); TypeConstructor typeConstructor = classDescriptor.getTypeConstructor();
List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments()); List<TypeProjection> arguments = resolveTypeProjections(scope, typeConstructor, type.getTypeArguments());
@@ -1,5 +1,6 @@
package org.jetbrains.jet.lang.types; package org.jetbrains.jet.lang.types;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.psi.JetTypeReference; import org.jetbrains.jet.lang.psi.JetTypeReference;
@@ -7,26 +8,21 @@ import org.jetbrains.jet.lang.psi.JetTypeReference;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface BindingTrace { public class BindingTrace {
BindingTrace DUMMY = new BindingTrace() { public static final BindingTrace DUMMY = new BindingTrace();
@Override
public void recordExpressionType(JetExpression expression, Type type) {
}
@Override public void recordExpressionType(JetExpression expression, Type type) {
public void recordResolutionResult(JetReferenceExpression expression, DeclarationDescriptor descriptor) { }
} public void recordReferenceResolution(JetReferenceExpression expression, DeclarationDescriptor descriptor) {
@Override }
public void recordTypeResoltion(JetTypeReference typeReference, Type type) {
} public void recordDeclarationResolution(JetDeclaration declaration, DeclarationDescriptor descriptor) {
};
void recordExpressionType(JetExpression expression, Type type); }
void recordResolutionResult(JetReferenceExpression expression, DeclarationDescriptor descriptor); public void recordTypeResolution(JetTypeReference typeReference, Type type) {
void recordTypeResoltion(JetTypeReference typeReference, Type type); }
} }
@@ -8,7 +8,7 @@ import java.util.List;
/** /**
* @author abreslav * @author abreslav
*/ */
public interface ClassDescriptor extends Annotated, Named { public interface ClassDescriptor extends DeclarationDescriptor {
@NotNull @NotNull
TypeConstructor getTypeConstructor(); TypeConstructor getTypeConstructor();
@@ -50,7 +50,7 @@ public class JetTypeInferrer {
// TODO : other members // TODO : other members
// TODO : type substitutions??? // TODO : type substitutions???
PropertyDescriptor property = scope.getProperty(expression.getReferencedName()); PropertyDescriptor property = scope.getProperty(expression.getReferencedName());
trace.recordResolutionResult(expression, property); trace.recordReferenceResolution(expression, property);
if (property != null) { if (property != null) {
result[0] = property.getType(); result[0] = property.getType();
} }
@@ -396,14 +396,14 @@ public class JetTypeInferrer {
@Override @Override
public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<Type> typeArguments, @NotNull Map<String, Type> valueArgumentTypes, @Nullable Type functionLiteralArgumentType) { public FunctionDescriptor getFunctionDescriptorForNamedArguments(@NotNull List<Type> typeArguments, @NotNull Map<String, Type> valueArgumentTypes, @Nullable Type functionLiteralArgumentType) {
FunctionDescriptor descriptor = result[0].getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType); FunctionDescriptor descriptor = result[0].getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
trace.recordResolutionResult(reference[0], descriptor); trace.recordReferenceResolution(reference[0], descriptor);
return descriptor; return descriptor;
} }
@Override @Override
public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) { public FunctionDescriptor getFunctionDescriptorForPositionedArguments(@NotNull List<Type> typeArguments, @NotNull List<Type> positionedValueArgumentTypes) {
FunctionDescriptor descriptor = result[0].getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes); FunctionDescriptor descriptor = result[0].getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
trace.recordResolutionResult(reference[0], descriptor); trace.recordReferenceResolution(reference[0], descriptor);
return descriptor; return descriptor;
} }
}; };