Converted TipsManager to Kotlin

This commit is contained in:
Valentin Kipyatkov
2014-09-17 14:11:33 +04:00
committed by valentin
parent 34aada75eb
commit 726f49b3f8
7 changed files with 145 additions and 223 deletions
@@ -44,6 +44,7 @@ public class AutoCastUtils {
private AutoCastUtils() {}
@NotNull
public static List<JetType> getAutoCastVariants(
@NotNull ReceiverValue receiverToCast,
@NotNull ResolutionContext context
@@ -51,6 +52,7 @@ public class AutoCastUtils {
return getAutoCastVariants(receiverToCast, context.trace.getBindingContext(), context.dataFlowInfo);
}
@NotNull
public static List<JetType> getAutoCastVariants(
@NotNull ReceiverValue receiverToCast,
@NotNull BindingContext bindingContext,
@@ -36,6 +36,7 @@ import java.util.Set;
public final class JetScopeUtils {
private JetScopeUtils() {}
@NotNull
public static List<ReceiverValue> getImplicitReceiversHierarchyValues(@NotNull JetScope scope) {
Collection<ReceiverParameterDescriptor> hierarchy = scope.getImplicitReceiversHierarchy();
@@ -56,6 +57,7 @@ public final class JetScopeUtils {
* @param scope Scope for query extensions.
* @return extension descriptors.
*/
@NotNull
public static Collection<CallableDescriptor> getAllExtensions(@NotNull JetScope scope) {
Set<CallableDescriptor> result = Sets.newHashSet();
@@ -37,19 +37,19 @@ import kotlin.properties.Delegates
public trait Qualifier {
val expression: JetExpression
public val expression: JetExpression
val packageView: PackageViewDescriptor?
public val packageView: PackageViewDescriptor?
val classifier: ClassifierDescriptor?
public val classifier: ClassifierDescriptor?
val name: Name
public val name: Name
get() = classifier?.getName() ?: packageView!!.getName()
// package, classifier or class object descriptor
val resultingDescriptor: DeclarationDescriptor
public val resultingDescriptor: DeclarationDescriptor
val scope: JetScope
public val scope: JetScope
}
class QualifierReceiver (
@@ -1,215 +0,0 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.codeInsight;
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.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
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.Qualifier;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getDataFlowInfo;
public final class TipsManager {
private TipsManager() {
}
@NotNull
public static Collection<DeclarationDescriptor> getReferenceVariants(
@NotNull JetSimpleNameExpression expression,
@NotNull BindingContext context
) {
JetExpression receiverExpression = PsiUtilPackage.getReceiverExpression(expression);
PsiElement parent = expression.getParent();
boolean inPositionForCompletionWithReceiver = parent instanceof JetCallExpression || parent instanceof JetQualifiedExpression;
if (receiverExpression != null && inPositionForCompletionWithReceiver) {
Set<DeclarationDescriptor> descriptors = new HashSet<DeclarationDescriptor>();
// Process as call expression
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
if (resolutionScope == null) return descriptors;
Qualifier qualifier = context.get(BindingContext.QUALIFIER, receiverExpression);
if (qualifier != null) {
// It's impossible to add extension function for package or class (if it's class object, expression type is not null)
descriptors.addAll(excludePrivateDescriptors(qualifier.getScope().getAllDescriptors()));
}
JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
if (expressionType != null && !expressionType.isError()) {
ExpressionReceiver receiverValue = new ExpressionReceiver(receiverExpression, expressionType);
DataFlowInfo info = getDataFlowInfo(context, expression);
List<JetType> variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info);
for (JetType variant : variantsForExplicitReceiver) {
descriptors.addAll(excludePrivateDescriptors(variant.getMemberScope().getAllDescriptors()));
}
descriptors.addAll(externalCallableExtensions(resolutionScope, receiverValue, context, info));
}
return descriptors;
}
else {
return getVariantsNoReceiver(expression, context);
}
}
public static Collection<DeclarationDescriptor> getVariantsNoReceiver(JetExpression expression, BindingContext context) {
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
if (resolutionScope != null) {
if (expression.getParent() instanceof JetImportDirective || expression.getParent() instanceof JetPackageDirective) {
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors());
}
else {
Collection<DeclarationDescriptor> descriptorsSet = Sets.newHashSet();
List<ReceiverParameterDescriptor> result = resolutionScope.getImplicitReceiversHierarchy();
for (ReceiverParameterDescriptor receiverDescriptor : result) {
JetType receiverType = receiverDescriptor.getType();
for (DeclarationDescriptor member : receiverType.getMemberScope().getAllDescriptors()) {
// skip member extension functions&properties
if (member instanceof CallableDescriptor && ((CallableDescriptor) member).getReceiverParameter() != null) continue;
descriptorsSet.add(member);
}
}
descriptorsSet.addAll(resolutionScope.getAllDescriptors());
DataFlowInfo info = getDataFlowInfo(context, expression);
return excludeNotCallableExtensions(excludePrivateDescriptors(descriptorsSet), resolutionScope, context, info);
}
}
return Collections.emptyList();
}
@NotNull
public static Collection<DeclarationDescriptor> getPackageReferenceVariants(
JetSimpleNameExpression expression,
BindingContext context
) {
JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);
if (resolutionScope != null) {
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors());
}
return Collections.emptyList();
}
private static Collection<DeclarationDescriptor> excludePrivateDescriptors(
@NotNull Collection<DeclarationDescriptor> descriptors
) {
return Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
if (descriptor == null) {
return false;
}
return true;
}
});
}
public static Collection<DeclarationDescriptor> excludeNotCallableExtensions(
@NotNull Collection<? extends DeclarationDescriptor> descriptors,
@NotNull JetScope scope,
@NotNull final BindingContext context,
@NotNull final DataFlowInfo dataFlowInfo
) {
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
final List<ReceiverParameterDescriptor> result = scope.getImplicitReceiversHierarchy();
descriptorsSet.removeAll(
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
@Override
public boolean apply(CallableDescriptor callableDescriptor) {
if (callableDescriptor.getReceiverParameter() == null) {
return false;
}
for (ReceiverParameterDescriptor receiverDescriptor : result) {
if (ExpressionTypingUtils.checkIsExtensionCallable(receiverDescriptor.getValue(), callableDescriptor, context, dataFlowInfo)) {
return false;
}
}
return true;
}
}));
return Lists.newArrayList(descriptorsSet);
}
private static Collection<DeclarationDescriptor> excludeNonPackageDescriptors(
@NotNull Collection<DeclarationDescriptor> descriptors
) {
return Collections2.filter(descriptors, new Predicate<DeclarationDescriptor>() {
@Override
public boolean apply(DeclarationDescriptor declarationDescriptor) {
if (declarationDescriptor instanceof PackageViewDescriptor) {
// Heuristic: we don't want to complete "System" in "package java.lang.Sys",
// so we find class of the same name as package, we exclude this package
PackageViewDescriptor parent = ((PackageViewDescriptor) declarationDescriptor).getContainingDeclaration();
if (parent != null) {
JetScope parentScope = parent.getMemberScope();
return parentScope.getClassifier(declarationDescriptor.getName()) == null;
}
return true;
}
return false;
}
});
}
private static Collection<CallableDescriptor> externalCallableExtensions(
@NotNull JetScope externalScope,
@NotNull final ReceiverValue receiverValue,
@NotNull final BindingContext context,
@NotNull final DataFlowInfo dataFlowInfo
) {
return Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
new Predicate<CallableDescriptor>() {
@Override
public boolean apply(CallableDescriptor callableDescriptor) {
return ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, callableDescriptor, context, dataFlowInfo);
}
});
}
}
@@ -0,0 +1,133 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.plugin.codeInsight
import com.google.common.base.Predicate
import org.jetbrains.jet.lang.descriptors.*
import org.jetbrains.jet.lang.psi.*
import org.jetbrains.jet.lang.psi.psiUtil.*
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo
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.ReceiverValue
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils
import java.util.*
import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo
public object TipsManager{
public fun getReferenceVariants(expression: JetSimpleNameExpression, context: BindingContext): Collection<DeclarationDescriptor> {
val receiverExpression = expression.getReceiverExpression()
val parent = expression.getParent()
val inPositionForCompletionWithReceiver = parent is JetCallExpression || parent is JetQualifiedExpression
if (receiverExpression != null && inPositionForCompletionWithReceiver) {
// Process as call expression
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf()
val descriptors = HashSet<DeclarationDescriptor>()
val qualifier = context[BindingContext.QUALIFIER, receiverExpression]
if (qualifier != null) {
// It's impossible to add extension function for package or class (if it's class object, expression type is not null)
descriptors.addAll(qualifier.scope.getAllDescriptors())
}
val expressionType = context[BindingContext.EXPRESSION_TYPE, receiverExpression]
if (expressionType != null && !expressionType.isError()) {
val receiverValue = ExpressionReceiver(receiverExpression, expressionType)
val info = context.getDataFlowInfo(expression)
val variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info)
for (variant in variantsForExplicitReceiver) {
descriptors.addAll(variant.getMemberScope().getAllDescriptors())
}
descriptors.addAll(externalCallableExtensions(resolutionScope, receiverValue, context, info))
}
return descriptors
}
else {
return getVariantsNoReceiver(expression, context)
}
}
public fun getVariantsNoReceiver(expression: JetExpression, context: BindingContext): Collection<DeclarationDescriptor> {
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf()
val parent = expression.getParent()
if (parent is JetImportDirective || parent is JetPackageDirective) {
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors())
}
else {
val descriptorsSet = HashSet<DeclarationDescriptor>()
for (receiverDescriptor in resolutionScope.getImplicitReceiversHierarchy()) {
receiverDescriptor.getType().getMemberScope().getAllDescriptors().filterTo(descriptorsSet) {
it !is CallableDescriptor || it.getReceiverParameter() == null/*skip member extension functions and properties*/
}
}
descriptorsSet.addAll(resolutionScope.getAllDescriptors())
return excludeNotCallableExtensions(descriptorsSet, resolutionScope, context, context.getDataFlowInfo(expression))
}
}
public fun getPackageReferenceVariants(expression: JetSimpleNameExpression, context: BindingContext): Collection<DeclarationDescriptor> {
val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf()
return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors())
}
public fun excludeNotCallableExtensions(descriptors: Collection<DeclarationDescriptor>, scope: JetScope, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection<DeclarationDescriptor> {
val implicitReceivers = scope.getImplicitReceiversHierarchy()
val descriptorsSet = HashSet(descriptors)
descriptorsSet.removeAll(JetScopeUtils.getAllExtensions(scope).filter { callable ->
if (callable.getReceiverParameter() == null)
false
else
implicitReceivers.none { ExpressionTypingUtils.checkIsExtensionCallable(it.getValue(), callable, context, dataFlowInfo) }
})
return descriptorsSet
}
private fun excludeNonPackageDescriptors(descriptors: Collection<DeclarationDescriptor>): Collection<DeclarationDescriptor> {
return descriptors.filter{
if (it is PackageViewDescriptor) {
// Heuristic: we don't want to complete "System" in "package java.lang.Sys",
// so we find class of the same name as package, we exclude this package
val parent = it.getContainingDeclaration()
parent == null || parent.getMemberScope().getClassifier(it.getName()) == null
}
else {
false
}
}
}
private fun externalCallableExtensions(externalScope: JetScope, receiverValue: ReceiverValue, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection<CallableDescriptor> {
return JetScopeUtils.getAllExtensions(externalScope).filter {
ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, context, dataFlowInfo)
}
}
}
@@ -87,7 +87,7 @@ public abstract class BaseJetVariableMacro extends Macro {
DataFlowInfo dataFlowInfo = getDataFlowInfo(bindingContext, contextExpression);
List<JetNamedDeclaration> declarations = new ArrayList<JetNamedDeclaration>();
for (DeclarationDescriptor declarationDescriptor : TipsManager.excludeNotCallableExtensions(filteredDescriptors, scope, bindingContext, dataFlowInfo)) {
for (DeclarationDescriptor declarationDescriptor : TipsManager.INSTANCE$.excludeNotCallableExtensions(filteredDescriptors, scope, bindingContext, dataFlowInfo)) {
PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor);
assert declaration == null || declaration instanceof PsiNamedElement;
@@ -389,7 +389,7 @@ public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWith
placeDescriptor = scope.getContainingDeclaration();
}
Collection<DeclarationDescriptor> variants = TipsManager.getReferenceVariants(callNameExpression, bindingContext);
Collection<DeclarationDescriptor> variants = TipsManager.INSTANCE$.getReferenceVariants(callNameExpression, bindingContext);
Name refName = callNameExpression.getReferencedNameAsName();