Use resolve session for checking comparability of descriptors

This commit is contained in:
Nikolay Krasko
2012-08-14 20:28:23 +04:00
parent 84a6c63d07
commit b186064130
6 changed files with 51 additions and 34 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.jetbrains.jet.plugin.JetDescriptorIconProvider; import org.jetbrains.jet.plugin.JetDescriptorIconProvider;
@@ -53,11 +54,11 @@ public final class DescriptorLookupConverter {
private DescriptorLookupConverter() {} private DescriptorLookupConverter() {}
@NotNull @NotNull
public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, public static LookupElement createLookupElement(@NotNull ResolveSession resolveSession,
@NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) { @NotNull DeclarationDescriptor descriptor, @Nullable PsiElement declaration) {
LookupElementBuilder element = LookupElementBuilder.create( LookupElementBuilder element = LookupElementBuilder.create(
new JetLookupObject(descriptor, bindingContext, declaration), descriptor.getName().getName()); new JetLookupObject(descriptor, resolveSession, declaration), descriptor.getName().getName());
String presentableText = descriptor.getName().getName(); String presentableText = descriptor.getName().getName();
String typeText = ""; String typeText = "";
@@ -80,14 +81,14 @@ public final class DescriptorLookupConverter {
// TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>' // TODO: A special case when it's impossible to resolve type parameters from arguments. Need '<' caret '>'
// TODO: Support omitting brackets for one argument functions // TODO: Support omitting brackets for one argument functions
if (functionDescriptor.getValueParameters().isEmpty()) { if (functionDescriptor.getValueParameters().isEmpty()) {
element = element.setInsertHandler(EMPTY_FUNCTION_HANDLER); element = element.withInsertHandler(EMPTY_FUNCTION_HANDLER);
} }
else { else {
if (functionDescriptor.getValueParameters().size() == 1 if (functionDescriptor.getValueParameters().size() == 1
&& JetStandardClasses.isFunctionType(functionDescriptor.getValueParameters().get(0).getType())) { && JetStandardClasses.isFunctionType(functionDescriptor.getValueParameters().get(0).getType())) {
element = element.setInsertHandler(PARAMS_BRACES_FUNCTION_HANDLER); element = element.withInsertHandler(PARAMS_BRACES_FUNCTION_HANDLER);
} else { } else {
element = element.setInsertHandler(PARAMS_PARENTHESIS_FUNCTION_HANDLER); element = element.withInsertHandler(PARAMS_PARENTHESIS_FUNCTION_HANDLER);
} }
} }
} }
@@ -100,20 +101,23 @@ public final class DescriptorLookupConverter {
assert declaredIn != null; assert declaredIn != null;
tailText = " (" + DescriptorUtils.getFQName(declaredIn) + ")"; tailText = " (" + DescriptorUtils.getFQName(declaredIn) + ")";
tailTextGrayed = true; tailTextGrayed = true;
element = element.setInsertHandler(JetClassInsertHandler.INSTANCE); element = element.withInsertHandler(JetClassInsertHandler.INSTANCE);
} }
else { else {
typeText = DescriptorRenderer.TEXT.render(descriptor); typeText = DescriptorRenderer.TEXT.render(descriptor);
} }
element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText).setPresentableText(presentableText); element = element.withTailText(tailText, tailTextGrayed).withTypeText(typeText).withPresentableText(presentableText);
element = element.setIcon(JetDescriptorIconProvider.getIcon(descriptor, Iconable.ICON_FLAG_VISIBILITY)); element = element.withIcon(JetDescriptorIconProvider.getIcon(descriptor, Iconable.ICON_FLAG_VISIBILITY));
return element; return element;
} }
@NotNull @NotNull
public static LookupElement createLookupElement(@NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) { public static LookupElement createLookupElement(
@NotNull ResolveSession resolveSession,
@NotNull BindingContext bindingContext,
@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof CallableMemberDescriptor) { if (descriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) descriptor; CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) descriptor;
while (callableMemberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { while (callableMemberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
@@ -122,14 +126,17 @@ public final class DescriptorLookupConverter {
} }
descriptor = callableMemberDescriptor; descriptor = callableMemberDescriptor;
} }
return createLookupElement(bindingContext, descriptor, BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)); return createLookupElement(resolveSession, descriptor, BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor));
} }
public static LookupElement[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) { public static LookupElement[] collectLookupElements(
@NotNull ResolveSession resolveSession,
@NotNull BindingContext bindingContext,
@NotNull Iterable<DeclarationDescriptor> descriptors) {
List<LookupElement> result = Lists.newArrayList(); List<LookupElement> result = Lists.newArrayList();
for (final DeclarationDescriptor descriptor : descriptors) { for (final DeclarationDescriptor descriptor : descriptors) {
result.add(createLookupElement(bindingContext, descriptor)); result.add(createLookupElement(resolveSession, bindingContext, descriptor));
} }
return result.toArray(new LookupElement[result.size()]); return result.toArray(new LookupElement[result.size()]);
@@ -60,7 +60,7 @@ public class JetClassCompletionContributor extends CompletionContributor {
final Collection<DeclarationDescriptor> jetOnlyClasses = JetShortNamesCache.getJetOnlyTypes(); final Collection<DeclarationDescriptor> jetOnlyClasses = JetShortNamesCache.getJetOnlyTypes();
for (DeclarationDescriptor jetOnlyClass : jetOnlyClasses) { for (DeclarationDescriptor jetOnlyClass : jetOnlyClasses) {
consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, jetOnlyClass)); consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, jetContext, jetOnlyClass));
} }
if (!JsModuleDetector.isJsModule((JetFile)parameters.getOriginalFile())) { if (!JsModuleDetector.isJsModule((JetFile)parameters.getOriginalFile())) {
@@ -98,7 +98,7 @@ public class JetClassCompletionContributor extends CompletionContributor {
}, resolveSession); }, resolveSession);
for (ClassDescriptor descriptor : descriptors) { for (ClassDescriptor descriptor : descriptors) {
consumer.consume(DescriptorLookupConverter.createLookupElement(jetContext, descriptor)); consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, jetContext, descriptor));
} }
} }
} }
@@ -121,7 +121,7 @@ public class JetClassCompletionContributor extends CompletionContributor {
Collection<ClassDescriptor> classDescriptors = ResolveSessionUtils.getClassDescriptorsByFqName( Collection<ClassDescriptor> classDescriptors = ResolveSessionUtils.getClassDescriptorsByFqName(
resolveSession,((JetLightClass) aClass).getFqName()); resolveSession,((JetLightClass) aClass).getFqName());
for (ClassDescriptor descriptor : classDescriptors) { for (ClassDescriptor descriptor : classDescriptors) {
consumer.consume(DescriptorLookupConverter.createLookupElement(context, descriptor)); consumer.consume(DescriptorLookupConverter.createLookupElement(resolveSession, context, descriptor));
} }
return true; return true;
@@ -184,7 +184,8 @@ public class JetCompletionContributor extends CompletionContributor {
matchPrefixCondition, expression, session.resolveSession, GlobalSearchScope.allScope(position.getProject())); matchPrefixCondition, expression, session.resolveSession, GlobalSearchScope.allScope(position.getProject()));
for (DeclarationDescriptor jetCallableExtension : jetCallableExtensions) { for (DeclarationDescriptor jetCallableExtension : jetCallableExtensions) {
result.addElement(DescriptorLookupConverter.createLookupElement(session.expressionBindingContext, jetCallableExtension)); result.addElement(DescriptorLookupConverter.createLookupElement(
session.resolveSession, session.expressionBindingContext, jetCallableExtension));
} }
} }
@@ -214,13 +215,11 @@ public class JetCompletionContributor extends CompletionContributor {
GlobalSearchScope scope = GlobalSearchScope.allScope(project); GlobalSearchScope scope = GlobalSearchScope.allScope(project);
Collection<String> functionNames = namesCache.getAllTopLevelFunctionNames(); Collection<String> functionNames = namesCache.getAllTopLevelFunctionNames();
ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile());
BindingContext resolutionContext = ResolveSessionUtils.getExpressionBindingContext(resolveSession, expression);
for (String name : functionNames) { for (String name : functionNames) {
if (name.contains(actualPrefix)) { if (name.contains(actualPrefix)) {
for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, expression, resolveSession, scope)) { for (FunctionDescriptor function : namesCache.getTopLevelFunctionDescriptorsByName(name, expression, session.resolveSession, scope)) {
addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(resolutionContext, function), session); addCompletionToResult(result, DescriptorLookupConverter.createLookupElement(
session.resolveSession, session.expressionBindingContext, function), session);
} }
} }
} }
@@ -342,6 +341,7 @@ public class JetCompletionContributor extends CompletionContributor {
if (descriptor instanceof DeclarationDescriptorWithVisibility) { if (descriptor instanceof DeclarationDescriptorWithVisibility) {
if (session.inDescriptor != null) { if (session.inDescriptor != null) {
//noinspection ConstantConditions
return Visibilities.isVisible((DeclarationDescriptorWithVisibility)descriptor, session.inDescriptor); return Visibilities.isVisible((DeclarationDescriptorWithVisibility)descriptor, session.inDescriptor);
} }
} }
@@ -368,6 +368,6 @@ public class JetCompletionContributor extends CompletionContributor {
} }
}); });
return DescriptorLookupConverter.collectLookupElements(session.expressionBindingContext, checkedDescriptors); return DescriptorLookupConverter.collectLookupElements(session.resolveSession, session.expressionBindingContext, checkedDescriptors);
} }
} }
@@ -16,11 +16,12 @@
package org.jetbrains.jet.plugin.completion; package org.jetbrains.jet.plugin.completion;
import com.intellij.openapi.diagnostic.Logger;
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;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.resolve.DescriptorRenderer; import org.jetbrains.jet.resolve.DescriptorRenderer;
/** /**
@@ -30,18 +31,20 @@ import org.jetbrains.jet.resolve.DescriptorRenderer;
* @author Nikolay Krasko * @author Nikolay Krasko
*/ */
public final class JetLookupObject { public final class JetLookupObject {
private static final Logger LOG = Logger.getInstance("#" + JetLookupObject.class.getName());
@Nullable @Nullable
private final DeclarationDescriptor descriptor; private final DeclarationDescriptor descriptor;
@Nullable @Nullable
private BindingContext context; private ResolveSession resolveSession;
@Nullable @Nullable
private final PsiElement psiElement; private final PsiElement psiElement;
public JetLookupObject(@Nullable DeclarationDescriptor descriptor, @NotNull BindingContext context, @Nullable PsiElement psiElement) { public JetLookupObject(@Nullable DeclarationDescriptor descriptor, @NotNull ResolveSession resolveSession, @Nullable PsiElement psiElement) {
this.descriptor = descriptor; this.descriptor = descriptor;
this.context = context; this.resolveSession = resolveSession;
this.psiElement = psiElement; this.psiElement = psiElement;
} }
@@ -78,12 +81,14 @@ public final class JetLookupObject {
// Same descriptor - same lookup element // Same descriptor - same lookup element
if (descriptor != null && other.descriptor != null) { if (descriptor != null && other.descriptor != null) {
if (context == other.context) { if (resolveSession == other.resolveSession) {
if (descriptor.equals(other.descriptor)) { if (descriptor.equals(other.descriptor)) {
return true; return true;
} }
} }
else { else {
LOG.warn("Descriptors from different resolve sessions");
String descriptorText = DescriptorRenderer.TEXT.render(descriptor); String descriptorText = DescriptorRenderer.TEXT.render(descriptor);
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
String otherDescriptorText = DescriptorRenderer.TEXT.render(other.descriptor); String otherDescriptorText = DescriptorRenderer.TEXT.render(other.descriptor);
@@ -28,6 +28,8 @@ import org.jetbrains.jet.cli.jvm.compiler.TipsManager;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetNamespaceHeader; import org.jetbrains.jet.lang.psi.JetNamespaceHeader;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.references.JetSimpleNameReference; import org.jetbrains.jet.plugin.references.JetSimpleNameReference;
@@ -71,11 +73,13 @@ public class JetPackagesContributor extends CompletionContributor {
int prefixLength = parameters.getOffset() - simpleNameReference.getExpression().getTextOffset(); int prefixLength = parameters.getOffset() - simpleNameReference.getExpression().getTextOffset();
result = result.withPrefixMatcher(new PlainPrefixMatcher(name.substring(0, prefixLength))); result = result.withPrefixMatcher(new PlainPrefixMatcher(name.substring(0, prefixLength)));
BindingContext bindingContext = WholeProjectAnalyzerFacade.getLazyResolveContext( ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile(
(JetFile) namespaceHeader.getContainingFile(), simpleNameReference.getExpression()); (JetFile) simpleNameReference.getExpression().getContainingFile());
BindingContext bindingContext = ResolveSessionUtils.getExpressionBindingContext(
resolveSession, simpleNameReference.getExpression());
for (LookupElement variant : DescriptorLookupConverter.collectLookupElements( for (LookupElement variant : DescriptorLookupConverter.collectLookupElements(
bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) { resolveSession, bindingContext, TipsManager.getPackageReferenceVariants(simpleNameReference.getExpression(), bindingContext))) {
if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) { if (!variant.getLookupString().contains(DUMMY_IDENTIFIER)) {
result.addElement(variant); result.addElement(variant);
} }
@@ -25,6 +25,8 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.psi.JetPsiFactory;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils;
import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter; import org.jetbrains.jet.plugin.completion.DescriptorLookupConverter;
import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade;
@@ -61,12 +63,11 @@ public class JetSimpleNameReference extends JetPsiReference {
@NotNull @NotNull
@Override @Override
public Object[] getVariants() { public Object[] getVariants() {
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) getExpression().getContainingFile());
(JetFile) myExpression.getContainingFile()) BindingContext bindingContext = ResolveSessionUtils.getExpressionBindingContext(resolveSession, getExpression());
.getBindingContext();
return DescriptorLookupConverter.collectLookupElements( return DescriptorLookupConverter.collectLookupElements(
bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); resolveSession, bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext));
} }
@Override @Override