Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -56,7 +56,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
isAbstract = true;
|
isAbstract = true;
|
||||||
isInterface = true;
|
isInterface = true;
|
||||||
}
|
}
|
||||||
if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
if (!jetClass.hasModifier(JetTokens.OPEN_KEYWORD) && !isAbstract) {
|
||||||
isFinal = true;
|
isFinal = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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<DeclarationDescriptor> 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<DeclarationDescriptor> excludeNotCallableExtensions(
|
||||||
|
@NotNull Collection<DeclarationDescriptor> descriptors, @NotNull final JetScope scope
|
||||||
|
) {
|
||||||
|
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
|
||||||
|
descriptorsSet.removeAll(
|
||||||
|
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||||
|
return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Lists.newArrayList(descriptorsSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Collection<DeclarationDescriptor> includeExternalCallableExtensions(
|
||||||
|
@NotNull Collection<DeclarationDescriptor> 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<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
|
||||||
|
descriptorsSet.addAll(
|
||||||
|
Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
||||||
|
new Predicate<CallableDescriptor>() {
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
package org.jetbrains.jet.plugin.references;
|
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.Lists;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||||
import com.intellij.openapi.util.Iconable;
|
import com.intellij.openapi.util.Iconable;
|
||||||
@@ -13,29 +10,17 @@ import com.intellij.psi.PsiElement;
|
|||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
import com.intellij.util.IncorrectOperationException;
|
import com.intellij.util.IncorrectOperationException;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.compiler.TipsManager;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
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.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.compiler.WholeProjectAnalyzerFacade;
|
||||||
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
import org.jetbrains.jet.plugin.completion.handlers.JetFunctionInsertHandler;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintType.RECEIVER;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -70,33 +55,10 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Object[] getVariants() {
|
public Object[] getVariants() {
|
||||||
PsiElement parent = myExpression.getParent();
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(
|
||||||
if (parent instanceof JetQualifiedExpression) {
|
(JetFile) myExpression.getContainingFile());
|
||||||
JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent;
|
|
||||||
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
|
||||||
JetFile file = (JetFile) myExpression.getContainingFile();
|
|
||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
|
||||||
|
|
||||||
final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
return collectLookupElements(bindingContext, TipsManager.getReferenceVariants(myExpression, bindingContext));
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -105,46 +67,7 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
return myExpression.getReferencedNameElement().replace(element);
|
return myExpression.getReferencedNameElement().replace(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterable<DeclarationDescriptor> excludeNotCallableExtensions(
|
private static Object[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) {
|
||||||
@NotNull Iterable<DeclarationDescriptor> descriptors, @NotNull final JetScope scope
|
|
||||||
) {
|
|
||||||
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
|
||||||
|
|
||||||
descriptorsSet.removeAll(
|
|
||||||
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
|
||||||
return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return descriptorsSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Iterable<DeclarationDescriptor> includeExternalCallableExtensions(
|
|
||||||
@NotNull Iterable<DeclarationDescriptor> 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<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
|
||||||
|
|
||||||
descriptorsSet.addAll(Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
|
||||||
new Predicate<CallableDescriptor>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(CallableDescriptor callableDescriptor) {
|
|
||||||
return checkReceiverResolution(receiverDescriptor, callableDescriptor);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
return descriptorsSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Object[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) {
|
|
||||||
List<LookupElement> result = Lists.newArrayList();
|
List<LookupElement> result = Lists.newArrayList();
|
||||||
|
|
||||||
for (final DeclarationDescriptor descriptor : descriptors) {
|
for (final DeclarationDescriptor descriptor : descriptors) {
|
||||||
@@ -198,29 +121,4 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
}
|
}
|
||||||
return result.toArray();
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user