Extracted from getSourceProperty() part which would be common for finding functions and properties.

This commit is contained in:
Evgeny Gerashchenko
2012-03-14 21:24:15 +04:00
parent a2f7df4fcd
commit 888a69b26a
@@ -32,14 +32,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.ModuleConfiguration; import org.jetbrains.jet.lang.ModuleConfiguration;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory; import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.resolve.DescriptorRenderer;
@@ -130,47 +128,53 @@ public class JetSourceNavigationHelper {
} }
@Nullable @Nullable
public static JetDeclaration getSourceProperty(final @NotNull JetProperty decompiledProperty) { private static <Decl extends JetDeclaration, Descr extends CallableDescriptor> JetDeclaration
String propertyName = decompiledProperty.getName(); getSourcePropertyOrFunction(final @NotNull Decl decompiledDeclaration,
if (propertyName == null) { JetTypeReference receiverType,
Matcher<Decl, Descr> matcher) {
String entityName = decompiledDeclaration.getName();
if (entityName == null) {
return null; return null;
} }
PsiElement propertyContainer = decompiledProperty.getParent(); PsiElement declarationContainer = decompiledDeclaration.getParent();
if (propertyContainer instanceof JetFile) { if (declarationContainer instanceof JetFile) {
Tuple2<BindingContext, NamespaceDescriptor> bindingContextAndNamespaceDescriptor = getBindingContextAndNamespaceDescriptor((JetFile) propertyContainer); Tuple2<BindingContext, NamespaceDescriptor> bindingContextAndNamespaceDescriptor = getBindingContextAndNamespaceDescriptor((JetFile) declarationContainer);
if (bindingContextAndNamespaceDescriptor == null) return null; if (bindingContextAndNamespaceDescriptor == null) return null;
BindingContext bindingContext = bindingContextAndNamespaceDescriptor._1; BindingContext bindingContext = bindingContextAndNamespaceDescriptor._1;
NamespaceDescriptor namespaceDescriptor = bindingContextAndNamespaceDescriptor._2; NamespaceDescriptor namespaceDescriptor = bindingContextAndNamespaceDescriptor._2;
JetTypeReference receiverType = decompiledProperty.getReceiverTypeRef();
if (receiverType == null) { if (receiverType == null) {
// non-extension property // non-extension property
Set<VariableDescriptor> properties = namespaceDescriptor.getMemberScope().getProperties(propertyName); for (Descr candidate : matcher.getCandidatesFromScope(namespaceDescriptor.getMemberScope(), entityName)) {
assert properties.size() <= 1; if (candidate.getReceiverParameter() == ReceiverDescriptor.NO_RECEIVER) {
if (properties.size() > 0) { if (matcher.areSame(decompiledDeclaration, candidate)) {
return (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, properties.iterator().next()); return (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, candidate);
}
}
} }
} else { } else {
// extension property // extension property
String expectedTypeString = receiverType.getText(); String expectedTypeString = receiverType.getText();
for (VariableDescriptor vd : namespaceDescriptor.getMemberScope().getProperties(propertyName)) { for (Descr candidate : matcher.getCandidatesFromScope(namespaceDescriptor.getMemberScope(), entityName)) {
if (vd.getReceiverParameter() != ReceiverDescriptor.NO_RECEIVER) { if (candidate.getReceiverParameter() != ReceiverDescriptor.NO_RECEIVER) {
String thisReceiverType = DescriptorRenderer.TEXT.renderType(vd.getReceiverParameter().getType()); String thisReceiverType = DescriptorRenderer.TEXT.renderType(candidate.getReceiverParameter().getType());
if (expectedTypeString.equals(thisReceiverType)) { if (expectedTypeString.equals(thisReceiverType)) {
return (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, vd); if (matcher.areSame(decompiledDeclaration, candidate)) {
return (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, candidate);
}
} }
} }
} }
} }
} }
else if (propertyContainer instanceof JetClassBody) { else if (declarationContainer instanceof JetClassBody) {
Tuple2<BindingContext, ClassDescriptor> bindingContextAndClassDescriptor = getBindingContextAndClassDescriptor((JetClass) propertyContainer.getParent()); Tuple2<BindingContext, ClassDescriptor> bindingContextAndClassDescriptor = getBindingContextAndClassDescriptor((JetClass) declarationContainer.getParent());
if (bindingContextAndClassDescriptor != null) { if (bindingContextAndClassDescriptor != null) {
BindingContext bindingContext = bindingContextAndClassDescriptor._1; BindingContext bindingContext = bindingContextAndClassDescriptor._1;
ClassDescriptor classDescriptor = bindingContextAndClassDescriptor._2; ClassDescriptor classDescriptor = bindingContextAndClassDescriptor._2;
for (VariableDescriptor vd : classDescriptor.getDefaultType().getMemberScope().getProperties(propertyName)) { for (Descr candidate : matcher.getCandidatesFromScope(classDescriptor.getDefaultType().getMemberScope(), entityName)) {
if (vd.getContainingDeclaration() == classDescriptor) { if (candidate.getContainingDeclaration() == classDescriptor) {
JetDeclaration property = (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, vd); JetDeclaration property = (JetDeclaration) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, candidate);
if (property != null) { if (property != null) {
return property; return property;
} }
@@ -180,4 +184,25 @@ public class JetSourceNavigationHelper {
} }
return null; return null;
} }
@Nullable
public static JetDeclaration getSourceProperty(final @NotNull JetProperty decompiledProperty) {
return getSourcePropertyOrFunction(decompiledProperty, decompiledProperty.getReceiverTypeRef(), new Matcher<JetProperty, VariableDescriptor>() {
@Override
public boolean areSame(JetProperty declaration, VariableDescriptor descriptor) {
return true;
}
@Override
public Set<VariableDescriptor> getCandidatesFromScope(JetScope scope, String name) {
return scope.getProperties(name);
}
});
}
private interface Matcher<Decl extends JetDeclaration, Descr extends CallableDescriptor> {
boolean areSame(Decl declaration, Descr descriptor);
Set<Descr> getCandidatesFromScope(JetScope scope, String name);
}
} }