From 9c5ff3fa7f36cef71cae7fe1e680467fee27564d Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 21 Dec 2011 16:20:51 +0400 Subject: [PATCH 1/2] Refactoring: move main completion resolver out of Idea plugin. --- .../jetbrains/jet/compiler/TipsManager.java | 134 ++++++++++++++++++ .../references/JetSimpleNameReference.java | 112 +-------------- 2 files changed, 139 insertions(+), 107 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java diff --git a/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java new file mode 100644 index 00000000000..b105ef2a633 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/compiler/TipsManager.java @@ -0,0 +1,134 @@ +package org.jetbrains.jet.compiler; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetQualifiedExpression; +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.NamespaceType; +import org.jetbrains.jet.lang.types.Variance; + +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + +import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER; + +/** + * @author Nikolay Krasko + */ +public final class TipsManager { + + private TipsManager() { + } + + @NotNull + public static Collection getReferenceVariants(JetSimpleNameExpression expression, BindingContext context) { + PsiElement parent = expression.getParent(); + if (parent instanceof JetQualifiedExpression) { + JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent; + JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); + + final JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); + final JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); + + if (expressionType != null && resolutionScope != null) { + return includeExternalCallableExtensions( + expressionType.getMemberScope().getAllDescriptors(), + resolutionScope, new ExpressionReceiver(receiverExpression, expressionType)); + } + } + else { + JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); + if (resolutionScope != null) { + return excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope); + } + } + + return Collections.emptyList(); + } + + private static Collection excludeNotCallableExtensions( + @NotNull Collection descriptors, @NotNull final JetScope scope + ) { + final Set descriptorsSet = Sets.newHashSet(descriptors); + + descriptorsSet.removeAll( + Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate() { + @Override + public boolean apply(CallableDescriptor callableDescriptor) { + return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor); + } + })); + + return Lists.newArrayList(descriptorsSet); + } + + private static Collection includeExternalCallableExtensions( + @NotNull Collection descriptors, + @NotNull final JetScope externalScope, + @NotNull final ReceiverDescriptor receiverDescriptor + ) { + // It's impossible to add extension function for namespace + if (receiverDescriptor.getType() instanceof NamespaceType) { + return descriptors; + } + + Set descriptorsSet = Sets.newHashSet(descriptors); + + descriptorsSet.addAll( + Collections2.filter(JetScopeUtils.getAllExtensions(externalScope), + new Predicate() { + @Override + public boolean apply(CallableDescriptor callableDescriptor) { + return checkReceiverResolution(receiverDescriptor, callableDescriptor); + } + })); + + return descriptorsSet; + } + + /* + * Checks if receiver declaration could be resolved to call expected receiver. + */ + private static boolean checkReceiverResolution ( + @NotNull ReceiverDescriptor expectedReceiver, + @NotNull CallableDescriptor receiverArgument + ) { + ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING); + for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) { + constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); + } + + ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter(); + if (expectedReceiver.exists() && receiverParameter.exists()) { + constraintSystem.addSubtypingConstraint( + RECEIVER.assertSubtyping(expectedReceiver.getType(), receiverParameter.getType())); + } + else if (expectedReceiver.exists() || receiverParameter.exists()) { + // Only one of receivers exist + return false; + } + + ConstraintSystemSolution solution = constraintSystem.solve(); + return solution.getStatus().isSuccessful(); + } + +} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java index bb955817b2c..a0a42cfeee2 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -1,9 +1,6 @@ package org.jetbrains.jet.plugin.references; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.openapi.util.Iconable; @@ -13,29 +10,17 @@ import com.intellij.psi.PsiElement; import com.intellij.util.Function; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.compiler.TipsManager; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener; -import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; -import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl; -import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.NamespaceType; -import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler; import org.jetbrains.jet.resolve.DescriptorRenderer; import java.util.List; -import java.util.Set; - -import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER; /** * @author yole @@ -70,33 +55,10 @@ class JetSimpleNameReference extends JetPsiReference { @NotNull @Override public Object[] getVariants() { - PsiElement parent = myExpression.getParent(); - if (parent instanceof JetQualifiedExpression) { - JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent; - JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); - JetFile file = (JetFile) myExpression.getContainingFile(); - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); + BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile( + (JetFile) myExpression.getContainingFile()); - final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression); - final JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); - - if (expressionType != null && resolutionScope != null) { - return collectLookupElements(bindingContext, - includeExternalCallableExtensions(expressionType.getMemberScope().getAllDescriptors(), - resolutionScope, new ExpressionReceiver(receiverExpression, expressionType))); - } - } - else { - JetFile file = (JetFile) myExpression.getContainingFile(); - BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file); - JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression); - if (resolutionScope != null) { - return collectLookupElements(bindingContext, - excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope)); - } - } - - return EMPTY_ARRAY; + return collectLookupElements(bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext)); } @Override @@ -105,46 +67,7 @@ class JetSimpleNameReference extends JetPsiReference { return myExpression.getReferencedNameElement().replace(element); } - private Iterable excludeNotCallableExtensions( - @NotNull Iterable descriptors, @NotNull final JetScope scope - ) { - final Set descriptorsSet = Sets.newHashSet(descriptors); - - descriptorsSet.removeAll( - Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate() { - @Override - public boolean apply(CallableDescriptor callableDescriptor) { - return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor); - } - })); - - return descriptorsSet; - } - - private Iterable includeExternalCallableExtensions( - @NotNull Iterable descriptors, - @NotNull final JetScope externalScope, - @NotNull final ReceiverDescriptor receiverDescriptor - ) { - // It's impossible to add extension function for namespace - if (receiverDescriptor.getType() instanceof NamespaceType) { - return descriptors; - } - - Set descriptorsSet = Sets.newHashSet(descriptors); - - descriptorsSet.addAll(Collections2.filter(JetScopeUtils.getAllExtensions(externalScope), - new Predicate() { - @Override - public boolean apply(CallableDescriptor callableDescriptor) { - return checkReceiverResolution(receiverDescriptor, callableDescriptor); - } - })); - - return descriptorsSet; - } - - private Object[] collectLookupElements(BindingContext bindingContext, Iterable descriptors) { + private static Object[] collectLookupElements(BindingContext bindingContext, Iterable descriptors) { List result = Lists.newArrayList(); for (final DeclarationDescriptor descriptor : descriptors) { @@ -198,29 +121,4 @@ class JetSimpleNameReference extends JetPsiReference { } return result.toArray(); } - - /* - * Checks if receiver declaration could be resolved to call expected receiver. - */ - private static boolean checkReceiverResolution ( - @NotNull ReceiverDescriptor expectedReceiver, - @NotNull CallableDescriptor receiverArgument - ) { - ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING); - for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) { - constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); - } - - ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter(); - if (expectedReceiver.exists() && receiverParameter.exists()) { - constraintSystem.addSubtypingConstraint(RECEIVER.assertSubtyping(expectedReceiver.getType(), receiverParameter.getType())); - } - else if (expectedReceiver.exists() || receiverParameter.exists()) { - // Only one of receivers exist - return false; - } - - ConstraintSystemSolution solution = constraintSystem.solve(); - return solution.getStatus().isSuccessful(); - } } From ec239e89ae19f66dd613a0a1189f2b3d0f663ae5 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Wed, 21 Dec 2011 17:03:24 +0400 Subject: [PATCH 2/2] fix tests broken yesterday sorry, everyone --- .../org/jetbrains/jet/codegen/ImplementationBodyCodegen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 494742a8192..4121669fc55 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -56,7 +56,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { isAbstract = true; isInterface = true; } - if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD)) { + if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD) && !isAbstract) { isFinal = true; } }