sometimes descriptor has more than one declaration
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.resolve;
|
package org.jetbrains.jet.lang.resolve;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -31,6 +32,8 @@ import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
|
|||||||
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
import org.jetbrains.jet.util.slicedmap.ReadOnlySlice;
|
||||||
import org.jetbrains.jet.util.slicedmap.Slices;
|
import org.jetbrains.jet.util.slicedmap.Slices;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,6 +86,27 @@ public class BindingContextUtils {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<PsiElement> resolveToDeclarationPsiElements(@NotNull BindingContext bindingContext, @Nullable JetReferenceExpression referenceExpression) {
|
||||||
|
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, referenceExpression);
|
||||||
|
if (declarationDescriptor == null) {
|
||||||
|
return Lists.newArrayList(bindingContext.get(BindingContext.LABEL_TARGET, referenceExpression));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PsiElement> elements = descriptorToDeclarations(bindingContext, declarationDescriptor);
|
||||||
|
if (elements.size() > 0) {
|
||||||
|
return elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Need to have a valid stubs for standard classes
|
||||||
|
if (referenceExpression != null && JetStandardClasses.getAllStandardClasses().contains(declarationDescriptor)) {
|
||||||
|
return Lists.<PsiElement>newArrayList(referenceExpression.getContainingFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull BindingContext bindingContext, @Nullable JetElement element, boolean onlyReference) {
|
public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull BindingContext bindingContext, @Nullable JetElement element, boolean onlyReference) {
|
||||||
DeclarationDescriptor descriptor = null;
|
DeclarationDescriptor descriptor = null;
|
||||||
@@ -131,6 +155,21 @@ public class BindingContextUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<PsiElement> descriptorToDeclarations(@NotNull BindingContext context, @NotNull DeclarationDescriptor descriptor) {
|
||||||
|
if (descriptor instanceof CallableMemberDescriptor) {
|
||||||
|
return callableDescriptorToDeclarations(context, (CallableMemberDescriptor) descriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PsiElement psiElement = descriptorToDeclaration(context, descriptor);
|
||||||
|
if (psiElement != null) {
|
||||||
|
return Lists.newArrayList(psiElement);
|
||||||
|
} else {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static PsiElement callableDescriptorToDeclaration(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) {
|
public static PsiElement callableDescriptorToDeclaration(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) {
|
||||||
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
@@ -148,6 +187,19 @@ public class BindingContextUtils {
|
|||||||
return doGetDescriptorToDeclaration(context, callable.getOriginal());
|
return doGetDescriptorToDeclaration(context, callable.getOriginal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<PsiElement> callableDescriptorToDeclarations(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) {
|
||||||
|
if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
|
List<PsiElement> r = new ArrayList<PsiElement>();
|
||||||
|
Set<? extends CallableMemberDescriptor> overridenDescriptors = callable.getOverriddenDescriptors();
|
||||||
|
for (CallableMemberDescriptor overriden : overridenDescriptors) {
|
||||||
|
r.addAll(callableDescriptorToDeclarations(context, overriden));
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
PsiElement psiElement = doGetDescriptorToDeclaration(context, callable);
|
||||||
|
return psiElement != null ? Lists.newArrayList(psiElement) : Lists.<PsiElement>newArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static PsiElement classDescriptorToDeclaration(@NotNull BindingContext context, @NotNull ClassDescriptor clazz) {
|
public static PsiElement classDescriptorToDeclaration(@NotNull BindingContext context, @NotNull ClassDescriptor clazz) {
|
||||||
return doGetDescriptorToDeclaration(context, clazz);
|
return doGetDescriptorToDeclaration(context, clazz);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET;
|
||||||
|
|
||||||
@@ -102,9 +103,12 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
|||||||
protected PsiElement doResolve() {
|
protected PsiElement doResolve() {
|
||||||
JetFile file = (JetFile) getElement().getContainingFile();
|
JetFile file = (JetFile) getElement().getContainingFile();
|
||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext();
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file).getBindingContext();
|
||||||
PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(bindingContext, myExpression);
|
List<PsiElement> psiElement = BindingContextUtils.resolveToDeclarationPsiElements(bindingContext, myExpression);
|
||||||
if (psiElement != null) {
|
if (psiElement.size() == 1) {
|
||||||
return psiElement;
|
return psiElement.iterator().next();
|
||||||
|
}
|
||||||
|
if (psiElement.size() > 1) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
Collection<? extends DeclarationDescriptor> declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression);
|
||||||
if (declarationDescriptors != null) return null;
|
if (declarationDescriptors != null) return null;
|
||||||
@@ -123,13 +127,17 @@ public abstract class JetPsiReference implements PsiPolyVariantReference {
|
|||||||
ArrayList<ResolveResult> results = new ArrayList<ResolveResult>(declarationDescriptors.size());
|
ArrayList<ResolveResult> results = new ArrayList<ResolveResult>(declarationDescriptors.size());
|
||||||
|
|
||||||
for (DeclarationDescriptor descriptor : declarationDescriptors) {
|
for (DeclarationDescriptor descriptor : declarationDescriptors) {
|
||||||
PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
List<PsiElement> elements = BindingContextUtils.descriptorToDeclarations(bindingContext, descriptor);
|
||||||
if (element == null) {
|
if (elements.isEmpty()) {
|
||||||
// TODO: Need a better resolution for Intrinsic function (KT-975)
|
// TODO: Need a better resolution for Intrinsic function (KT-975)
|
||||||
element = file;
|
results.add(new PsiElementResolveResult(file, true));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (PsiElement element : elements) {
|
||||||
|
results.add(new PsiElementResolveResult(element, true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results.add(new PsiElementResolveResult(element, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results.toArray(new ResolveResult[results.size()]);
|
return results.toArray(new ResolveResult[results.size()]);
|
||||||
|
|||||||
Reference in New Issue
Block a user