Fixed not working item in completion list for infix call

This commit is contained in:
Valentin Kipyatkov
2015-05-06 19:48:56 +03:00
parent 2adf0a3e9a
commit a036a6435b
6 changed files with 56 additions and 18 deletions
@@ -127,27 +127,35 @@ abstract class CompletionSessionBase(protected val configuration: CompletionSess
protected val referenceVariantsHelper: ReferenceVariantsHelper = ReferenceVariantsHelper(bindingContext) { isVisibleDescriptor(it) }
protected val receiversData: ReferenceVariantsHelper.ReceiversData? = reference?.let { referenceVariantsHelper.getReferenceVariantsReceivers(it.expression) }
protected val lookupElementFactory: LookupElementFactory = run {
val receiverTypes = if (reference != null) {
val expression = reference.expression
val (receivers, callType) = referenceVariantsHelper.getReferenceVariantsReceivers(expression)
if (receiversData != null) {
val dataFlowInfo = bindingContext.getDataFlowInfo(expression)
var receiverTypes = receivers.flatMap {
var receiverTypes = receiversData.receivers.flatMap {
SmartCastUtils.getSmartCastVariantsWithLessSpecificExcluded(it, bindingContext, moduleDescriptor, dataFlowInfo)
}
if (callType == CallType.SAFE) {
if (receiversData.callType == CallType.SAFE) {
receiverTypes = receiverTypes.map { it.makeNotNullable() }
}
receiverTypes
LookupElementFactory(receiverTypes)
}
else {
listOf()
LookupElementFactory(emptyList())
}
LookupElementFactory(receiverTypes)
}
protected val collector: LookupElementsCollector = LookupElementsCollector(
prefixMatcher, parameters, resolutionFacade, lookupElementFactory, inDescriptor, expression?.getParent() is JetSimpleNameStringTemplateEntry)
private val collectorContext = if (expression?.getParent() is JetSimpleNameStringTemplateEntry)
LookupElementsCollector.Context.STRING_TEMPLATE_AFTER_DOLLAR
else if (receiversData?.callType == CallType.INFIX)
LookupElementsCollector.Context.INFIX_CALL
else
LookupElementsCollector.Context.NORMAL
protected val collector: LookupElementsCollector = LookupElementsCollector(prefixMatcher, parameters, resolutionFacade, lookupElementFactory, inDescriptor, collectorContext)
protected val project: Project = position.getProject()
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.completion.handlers.CastReceiverInsertHandler
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -39,8 +39,14 @@ class LookupElementsCollector(
private val resolutionFacade: ResolutionFacade,
private val lookupElementFactory: LookupElementFactory,
private val inDescriptor: DeclarationDescriptor?,
private val surroundCallsWithBraces: Boolean
private val context: LookupElementsCollector.Context
) {
public enum class Context {
NORMAL
STRING_TEMPLATE_AFTER_DOLLAR
INFIX_CALL
}
private val elements = ArrayList<LookupElement>()
public fun flushToResultSet(resultSet: CompletionResultSet) {
@@ -63,7 +69,7 @@ class LookupElementsCollector(
}
}
public fun addDescriptorElements(descriptor: DeclarationDescriptor, suppressAutoInsertion: Boolean, withReceiverCast: Boolean) {
private fun addDescriptorElements(descriptor: DeclarationDescriptor, suppressAutoInsertion: Boolean, withReceiverCast: Boolean) {
run {
var lookupElement = lookupElementFactory.createLookupElement(resolutionFacade, descriptor, true)
@@ -71,7 +77,7 @@ class LookupElementsCollector(
lookupElement = lookupElement.withReceiverCast()
}
if (surroundCallsWithBraces && (descriptor is FunctionDescriptor || descriptor is ClassifierDescriptor)) {
if (context == Context.STRING_TEMPLATE_AFTER_DOLLAR && (descriptor is FunctionDescriptor || descriptor is ClassifierDescriptor)) {
lookupElement = lookupElement.withBracesSurrounding()
}
@@ -84,7 +90,7 @@ class LookupElementsCollector(
}
// add special item for function with one argument of function type with more than one parameter
if (descriptor is FunctionDescriptor) {
if (context != Context.INFIX_CALL && descriptor is FunctionDescriptor) {
val parameters = descriptor.getValueParameters()
if (parameters.size() == 1) {
val parameterType = parameters.get(0).getType()
@@ -108,7 +114,7 @@ class LookupElementsCollector(
}
}
if (surroundCallsWithBraces) {
if (context == Context.STRING_TEMPLATE_AFTER_DOLLAR) {
lookupElement = lookupElement.withBracesSurrounding()
}
@@ -121,10 +127,10 @@ class LookupElementsCollector(
if (descriptor is PropertyDescriptor) {
var lookupElement = lookupElementFactory.createBackingFieldLookupElement(descriptor, inDescriptor, resolutionFacade)
if (lookupElement != null) {
if (surroundCallsWithBraces) {
lookupElement = lookupElement!!.withBracesSurrounding()
if (context == Context.STRING_TEMPLATE_AFTER_DOLLAR) {
lookupElement = lookupElement.withBracesSurrounding()
}
addElement(lookupElement!!)
addElement(lookupElement)
}
}
}
@@ -0,0 +1,11 @@
// checks that no special item "ext1 { String, Int -> ... }" created for infix call
fun Int.ext1(handler: (String, Int) -> Unit){}
fun Int.ext2(c: Char){}
fun foo() {
val pair = 1 ext<caret>
}
// EXIST: ext1
// EXIST: ext2
// NUMBER: 2
@@ -631,6 +631,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName);
}
@TestMetadata("InfixCallNoSpecialLambdaArgumentItem.kt")
public void testInfixCallNoSpecialLambdaArgumentItem() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InfixCallNoSpecialLambdaArgumentItem.kt");
doTest(fileName);
}
@TestMetadata("InsideAnonymousClass.kt")
public void testInsideAnonymousClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InsideAnonymousClass.kt");
@@ -631,6 +631,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName);
}
@TestMetadata("InfixCallNoSpecialLambdaArgumentItem.kt")
public void testInfixCallNoSpecialLambdaArgumentItem() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InfixCallNoSpecialLambdaArgumentItem.kt");
doTest(fileName);
}
@TestMetadata("InsideAnonymousClass.kt")
public void testInsideAnonymousClass() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InsideAnonymousClass.kt");