Callable reference completion for non-imported callables
This commit is contained in:
+12
-10
@@ -116,8 +116,8 @@ public class ReferenceVariantsHelper(
|
||||
else -> throw RuntimeException() //TODO: see KT-9394
|
||||
}
|
||||
|
||||
val resolutionScope = resolutionScope(expression) ?: return emptyList()
|
||||
val dataFlowInfo = dataFlowInfo(expression)
|
||||
val resolutionScope = resolutionScope(expression, context) ?: return emptyList()
|
||||
val dataFlowInfo = dataFlowInfo(expression, context)
|
||||
val containingDeclaration = resolutionScope.getContainingDeclaration()
|
||||
|
||||
val smartCastManager = resolutionFacade.frontendService<SmartCastManager>()
|
||||
@@ -334,14 +334,16 @@ public class ReferenceVariantsHelper(
|
||||
return resolutionScope.getDescriptorsFiltered(DescriptorKindFilter.PACKAGES, nameFilter).filter(visibilityFilter)
|
||||
}
|
||||
|
||||
//TODO: drop these methods
|
||||
public fun resolutionScope(expression: JetSimpleNameExpression): JetScope? {
|
||||
val parent = expression.parent
|
||||
return context[BindingContext.RESOLUTION_SCOPE, if (parent is JetCallableReferenceExpression) parent else expression]
|
||||
}
|
||||
companion object {
|
||||
//TODO: drop these methods
|
||||
public fun resolutionScope(expression: JetExpression, bindingContext: BindingContext): JetScope? {
|
||||
val parent = expression.parent
|
||||
return bindingContext[BindingContext.RESOLUTION_SCOPE, if (parent is JetCallableReferenceExpression) parent else expression]
|
||||
}
|
||||
|
||||
public fun dataFlowInfo(expression: JetSimpleNameExpression): DataFlowInfo {
|
||||
val parent = expression.parent
|
||||
return context.getDataFlowInfo(if (parent is JetCallableReferenceExpression) parent else expression)
|
||||
public fun dataFlowInfo(expression: JetExpression, bindingContext: BindingContext): DataFlowInfo {
|
||||
val parent = expression.parent
|
||||
return bindingContext.getDataFlowInfo(if (parent is JetCallableReferenceExpression) parent else expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,22 @@ package org.jetbrains.kotlin.idea.util
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.codeInsight.ReferenceVariantsHelper
|
||||
import org.jetbrains.kotlin.lexer.JetTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isImportDirectiveExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isPackageDirectiveExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastManager
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||
|
||||
public sealed class CallType<TReceiver : JetElement?>(val descriptorKindFilter: DescriptorKindFilter) {
|
||||
object UNKNOWN : CallType<Nothing?>(DescriptorKindFilter.ALL)
|
||||
@@ -140,3 +148,58 @@ public sealed class CallTypeAndReceiver<TReceiver : JetElement?, TCallType : Cal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun CallTypeAndReceiver<*, *>.receiverTypes(
|
||||
bindingContext: BindingContext,
|
||||
position: JetExpression,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
predictableSmartCastsOnly: Boolean
|
||||
): Collection<JetType>? {
|
||||
val receiverExpression: JetExpression?
|
||||
when (this) {
|
||||
is CallTypeAndReceiver.CALLABLE_REFERENCE -> {
|
||||
if (receiver != null) {
|
||||
val type = bindingContext[BindingContext.TYPE, receiver]
|
||||
return type.singletonOrEmptyList()
|
||||
}
|
||||
else {
|
||||
receiverExpression = null
|
||||
}
|
||||
}
|
||||
|
||||
is CallTypeAndReceiver.DEFAULT -> receiverExpression = null
|
||||
is CallTypeAndReceiver.DOT -> receiverExpression = receiver
|
||||
is CallTypeAndReceiver.SAFE -> receiverExpression = receiver
|
||||
is CallTypeAndReceiver.INFIX -> receiverExpression = receiver
|
||||
is CallTypeAndReceiver.UNARY -> receiverExpression = receiver
|
||||
|
||||
is CallTypeAndReceiver.IMPORT_DIRECTIVE,
|
||||
is CallTypeAndReceiver.PACKAGE_DIRECTIVE,
|
||||
is CallTypeAndReceiver.TYPE,
|
||||
is CallTypeAndReceiver.UNKNOWN ->
|
||||
return null
|
||||
|
||||
else -> throw RuntimeException() //TODO: see KT-9394
|
||||
}
|
||||
|
||||
val receiverValues = if (receiverExpression != null) {
|
||||
val expressionType = bindingContext.getType(receiverExpression)
|
||||
expressionType?.let { listOf(ExpressionReceiver(receiverExpression, expressionType)) } ?: return emptyList()
|
||||
}
|
||||
else {
|
||||
val resolutionScope = ReferenceVariantsHelper.resolutionScope(position, bindingContext) ?: return emptyList()
|
||||
resolutionScope.getImplicitReceiversWithInstance().map { it.value }
|
||||
}
|
||||
|
||||
val dataFlowInfo = ReferenceVariantsHelper.dataFlowInfo(position, bindingContext)
|
||||
|
||||
return receiverValues.flatMap { receiverValue ->
|
||||
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(receiverValue, bindingContext, moduleDescriptor)
|
||||
if (dataFlowValue.isPredictable || !predictableSmartCastsOnly) { // we don't include smart cast receiver types for "unpredictable" receiver value to mark members grayed
|
||||
SmartCastManager().getSmartCastVariantsWithLessSpecificExcluded(receiverValue, bindingContext, moduleDescriptor, dataFlowInfo)
|
||||
}
|
||||
else {
|
||||
listOf(receiverValue.type)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user