diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt index b1535681860..c50f15946bb 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt @@ -16,7 +16,6 @@ package org.jetbrains.kotlin.idea.util -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemImpl @@ -42,7 +41,7 @@ fun FuzzyType.makeNotNullable() = FuzzyType(type.makeNotNullable(), freeParamete fun FuzzyType.makeNullable() = FuzzyType(type.makeNullable(), freeParameters) fun FuzzyType.nullability() = type.nullability() -fun FuzzyType.isAlmostAnyType(): Boolean { +fun FuzzyType.isAlmostEverything(): Boolean { if (freeParameters.isEmpty()) return false val typeParameter = type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false if (typeParameter !in freeParameters) return false diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt index a3ade125b0a..40f8c0f223b 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.idea.completion.smart.toList import org.jetbrains.kotlin.idea.core.mapArgumentsToParameters import org.jetbrains.kotlin.idea.util.FuzzyType import org.jetbrains.kotlin.idea.util.fuzzyReturnType -import org.jetbrains.kotlin.idea.util.isAlmostAnyType import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* @@ -51,7 +50,7 @@ import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.typeUtil.containsError import org.jetbrains.kotlin.types.typeUtil.makeNotNullable -import java.util.* +import java.util.LinkedHashSet enum class Tail { COMMA, @@ -146,7 +145,11 @@ class ExpectedInfos( ?.map { it.fuzzyType } ?: return results if (expectedFuzzyTypes.isEmpty() || expectedFuzzyTypes.any { it.freeParameters.isNotEmpty() }) return results - return expectedFuzzyTypes.flatMap { calculateForArgument(call, it.type, argument) ?: emptyList() }.toSet() + return expectedFuzzyTypes + .map { it.type } + .toSet() + .flatMap { calculateForArgument(call, it, argument) ?: emptyList() } + .toSet() } return results @@ -200,6 +203,7 @@ class ExpectedInfos( var argumentToParameter = call.mapArgumentsToParameters(descriptor) var parameter = argumentToParameter[argument] ?: continue + //TODO: we can loose partially inferred substitution here but what to do? if (parameter.type.containsError()) { parameter = parameter.original descriptor = descriptor.original diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCompletionSession.kt index 3fa39e03845..5db1a35e1ed 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/SmartCompletionSession.kt @@ -107,7 +107,7 @@ class SmartCompletionSession(configuration: CompletionSessionConfiguration, para override fun getValueArgumentList() = throw UnsupportedOperationException() } - val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useHeuristicSignatures = false) + val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor) .calculateForArgument(dummyCall, dummyArgument) if (expectedInfos != null) { collector.addElements(LambdaItems.collect(expectedInfos)) diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt index 082876c6ed4..265ed4e21ad 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/SmartCompletion.kt @@ -39,7 +39,9 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.types.typeUtil.* +import org.jetbrains.kotlin.types.typeUtil.TypeNullability +import org.jetbrains.kotlin.types.typeUtil.isNothing +import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import java.util.ArrayList import java.util.HashSet @@ -210,7 +212,7 @@ class SmartCompletion( var returnType = fuzzyReturnType() ?: return listOf() // skip declarations of type Nothing or of generic parameter type which has no real bounds //TODO: maybe we should include them on the second press? - if (returnType.type.isNothing() || returnType.isAlmostAnyType()) return listOf() + if (returnType.type.isNothing() || returnType.isAlmostEverything()) return listOf() if (this is VariableDescriptor) { return smartCastTypes(this).map { FuzzyType(it, listOf()) } @@ -244,7 +246,7 @@ class SmartCompletion( while (true) { val infos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor, useOuterCallsExpectedTypeCount = count) .calculate(expression) ?: return null - if (count == 2 /* use two outer calls maximum */ || infos.none { it.fuzzyType.isAlmostAnyType() }) return infos + if (count == 2 /* use two outer calls maximum */ || infos.none { it.fuzzyType.isAlmostEverything() }) return infos count++ } //TODO: we could always give higher priority to results with outer call expected type used diff --git a/idea/idea-completion/testData/smart/FilterTo.kt b/idea/idea-completion/testData/smart/FilterTo.kt new file mode 100644 index 00000000000..033a4c0fab7 --- /dev/null +++ b/idea/idea-completion/testData/smart/FilterTo.kt @@ -0,0 +1,8 @@ +fun foo(list: List, intList: MutableList, stringList: MutableList, p: Any) { + list.filterTo() +} + +// EXIST: arrayListOf +// EXIST: stringList +// ABSENT: intList +// ABSENT: p diff --git a/idea/idea-completion/testData/smart/LambdaValue3.kt b/idea/idea-completion/testData/smart/LambdaValue3.kt index 29ff33895d6..a60f4368b6a 100644 --- a/idea/idea-completion/testData/smart/LambdaValue3.kt +++ b/idea/idea-completion/testData/smart/LambdaValue3.kt @@ -1,4 +1,4 @@ -fun foo(list: List): Collection { +fun foo(list: List) { bar(list.map { it. }) } diff --git a/idea/idea-completion/testData/smart/MapTo.kt b/idea/idea-completion/testData/smart/MapTo.kt index 59877a17126..5bc9c0aff96 100644 --- a/idea/idea-completion/testData/smart/MapTo.kt +++ b/idea/idea-completion/testData/smart/MapTo.kt @@ -1,7 +1,8 @@ -fun foo(list: List, intList: MutableList, stringList: MutableList): Collection { +fun foo(list: List, intList: MutableList, stringList: MutableList, p: Any): Collection { return list.mapTo() } // EXIST: intList // EXIST: arrayListOf // EXIST: stringList +// ABSENT: p diff --git a/idea/idea-completion/testData/smart/MapTo2.kt b/idea/idea-completion/testData/smart/MapTo2.kt index de9ce76e637..90e4cdb1de2 100644 --- a/idea/idea-completion/testData/smart/MapTo2.kt +++ b/idea/idea-completion/testData/smart/MapTo2.kt @@ -1,7 +1,8 @@ -fun foo(list: List, intList: MutableList, stringList: MutableList): Collection { +fun foo(list: List, intList: MutableList, stringList: MutableList, p: Any): Collection { list.mapTo() } // EXIST: intList // EXIST: stringList // EXIST: arrayListOf +// ABSENT: p diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java index 36495467d43..782868410a4 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmSmartCompletionTestGenerated.java @@ -131,6 +131,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest(fileName); } + @TestMetadata("FilterTo.kt") + public void testFilterTo() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/FilterTo.kt"); + doTest(fileName); + } + @TestMetadata("GroupBySubstitutor.kt") public void testGroupBySubstitutor() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/GroupBySubstitutor.kt");