Converted TipsManager to Kotlin
This commit is contained in:
committed by
valentin
parent
34aada75eb
commit
726f49b3f8
+2
@@ -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;
|
||||
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user