diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt index 29399b16aac..8c3803ce748 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/InsertHandlerProvider.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.core.ExpectedInfo import org.jetbrains.kotlin.idea.core.fuzzyType import org.jetbrains.kotlin.idea.util.CallType import org.jetbrains.kotlin.idea.util.fuzzyReturnType +import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.resolve.getValueParametersCountFromFunctionType import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -48,9 +49,10 @@ class InsertHandlerProvider( 1 -> { if (callType != CallType.SUPER_MEMBERS) { // for super call we don't suggest to generate "super.foo { ... }" (seems to be non-typical use) - val parameterType = parameters.single().type + val parameter = parameters.single() + val parameterType = parameter.type if (parameterType.isFunctionType) { - if (getValueParametersCountFromFunctionType(parameterType) <= 1) { + if (getValueParametersCountFromFunctionType(parameterType) <= 1 && !parameter.hasDefaultValue()) { // otherwise additional item with lambda template is to be added return KotlinFunctionInsertHandler.Normal( callType, needTypeArguments, inputValueArguments = false, diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt index 7ae604f71e0..6d1fede31ed 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/LookupElementFactory.kt @@ -140,9 +140,9 @@ class LookupElementFactory( val isSingleParameter = descriptor.valueParameters.size == 1 val parameterType = lastParameter.type - val functionParameterCount = getValueParametersCountFromFunctionType(parameterType) - // we don't need special item inserting lambda for single functional parameter that does not need multiple arguments because the default item will be special in this case - if (!isSingleParameter || functionParameterCount > 1) { + val insertHandler = insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler.Normal + if (insertHandler.lambdaInfo == null) { + val functionParameterCount = getValueParametersCountFromFunctionType(parameterType) add(createFunctionCallElementWithLambda(descriptor, parameterType, functionParameterCount > 1, useReceiverTypes)) } @@ -210,7 +210,7 @@ class LookupElementFactory( } private fun createFunctionCallElementWithArguments(descriptor: FunctionDescriptor, argumentText: String, useReceiverTypes: Boolean): LookupElement { - var lookupElement = createLookupElement(descriptor, useReceiverTypes) + val lookupElement = createLookupElement(descriptor, useReceiverTypes) val needTypeArguments = (insertHandlerProvider.insertHandler(descriptor) as KotlinFunctionInsertHandler.Normal).inputTypeArguments return FunctionCallWithArgumentsLookupElement(lookupElement, descriptor, argumentText, needTypeArguments) diff --git a/idea/idea-completion/testData/basic/common/highOrderFunctions/OptionalParameters.kt b/idea/idea-completion/testData/basic/common/highOrderFunctions/OptionalParameters.kt index cf273bf2d73..6ff9a96ccb6 100644 --- a/idea/idea-completion/testData/basic/common/highOrderFunctions/OptionalParameters.kt +++ b/idea/idea-completion/testData/basic/common/highOrderFunctions/OptionalParameters.kt @@ -1,6 +1,7 @@ fun xfoo1(option1: String = "", option2: Int = 1, p: () -> Unit){} fun xfoo2(option1: String = "", option2: Int = 1, p: (Int) -> Boolean){} fun xfoo3(option1: String = "", option2: Int = 1, p: (String, Char) -> Unit){} +fun xfoo4(p: () -> Unit = {}){} fun xfooBad1(option: String = "", notOption: Int, p: (String, Char) -> Unit){} fun xfooBad2(option1: String = "", option2: Int = 1, p: (String, Char) -> Unit, option3: Int = 0){} @@ -18,6 +19,10 @@ fun test(param: () -> Unit) { // EXIST: { itemText: "xfoo3", tailText: "(option1: String = ..., option2: Int = ..., p: (String, Char) -> Unit) ()", typeText:"Unit" } // EXIST: { itemText: "xfoo3", tailText: " { String, Char -> ... } (..., p: (String, Char) -> Unit) ()", typeText:"Unit" } +// EXIST: { itemText: "xfoo4", tailText: "(p: () -> Unit = ...) ()", typeText:"Unit" } +// EXIST: { itemText: "xfoo4", tailText: " {...} (p: () -> Unit = ...) ()", typeText:"Unit" } +// EXIST: { itemText: "xfoo4", tailText: "(param) ()", typeText:"Unit" } + // EXIST: { itemText: "xfooBad1", tailText: "(option: String = ..., notOption: Int, p: (String, Char) -> Unit) ()", typeText:"Unit" } // EXIST: { itemText: "xfooBad2", tailText: "(option1: String = ..., option2: Int = ..., p: (String, Char) -> Unit, option3: Int = ...) ()", typeText:"Unit" } diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt new file mode 100644 index 00000000000..e09ccd41af2 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt @@ -0,0 +1,9 @@ +fun xfoo(p: () -> Unit = {}){} + +fun test() { + xfo +} + +// ELEMENT: xfoo +// TAIL_TEXT: " {...} (p: () -> Unit = ...) ()" + diff --git a/idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt.after b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt.after new file mode 100644 index 00000000000..ed7ec38f104 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt.after @@ -0,0 +1,9 @@ +fun xfoo(p: () -> Unit = {}){} + +fun test() { + xfoo { } +} + +// ELEMENT: xfoo +// TAIL_TEXT: " {...} (p: () -> Unit = ...) ()" + diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index f72a13c896d..c53d27bb6a0 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -385,6 +385,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion doTest(fileName); } + @TestMetadata("OptionalParameters3.kt") + public void testOptionalParameters3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/OptionalParameters3.kt"); + doTest(fileName); + } + @TestMetadata("ParameterTypeIsDerivedFromFunction.kt") public void testParameterTypeIsDerivedFromFunction() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/ParameterTypeIsDerivedFromFunction.kt");