From 02fec6e4a56fa9b96f0729862117ed5705147f53 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 18 Apr 2017 20:38:25 +0300 Subject: [PATCH] Add fine check of type inference when adding <> in completion Add check if type inferred via type parameter of upper bound of extension receiver or value argument #KT-16161 fixed --- .../kotlin/idea/completion/InsertHandlerProvider.kt | 7 +++++-- .../handlers/basic/TypeInferedFromWrapperType.kt | 12 ++++++++++++ .../basic/TypeInferedFromWrapperType.kt.after | 12 ++++++++++++ .../BasicCompletionHandlerTestGenerated.java | 6 ++++++ 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt create mode 100644 idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after 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 b08911a174e..c9a3d98a5b8 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,8 +26,8 @@ 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.calls.util.getValueParametersCountFromFunctionType +import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue import org.jetbrains.kotlin.types.KotlinType import java.util.* @@ -94,8 +94,11 @@ class InsertHandlerProvider( fun addPotentiallyInferred(type: KotlinType) { val descriptor = type.constructor.declarationDescriptor as? TypeParameterDescriptor - if (descriptor != null && descriptor in typeParameters) { + if (descriptor != null && descriptor in typeParameters && descriptor !in potentiallyInferred) { potentiallyInferred.add(descriptor) + // Add possible inferred by type-arguments of upper-bound of parameter + // e.g. >, so T inferred from C + descriptor.upperBounds.filter { it.arguments.isNotEmpty() }.forEach(::addPotentiallyInferred) } if (type.isFunctionType && getValueParametersCountFromFunctionType(type) <= 1) { diff --git a/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt new file mode 100644 index 00000000000..be1703aeee5 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt @@ -0,0 +1,12 @@ +class Cn + +fun > C.some(arg: (T) -> Unit): C { + return this +} + +fun main(args: Array) { + val x = Cn() + x. +} + +//ELEMENT: some diff --git a/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after new file mode 100644 index 00000000000..7a28ebbad82 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt.after @@ -0,0 +1,12 @@ +class Cn + +fun > C.some(arg: (T) -> Unit): C { + return this +} + +fun main(args: Array) { + val x = Cn() + x.some { } +} + +//ELEMENT: some 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 77500a77006..18d7e51acdc 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 @@ -216,6 +216,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion doTest(fileName); } + @TestMetadata("TypeInferedFromWrapperType.kt") + public void testTypeInferedFromWrapperType() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/TypeInferedFromWrapperType.kt"); + doTest(fileName); + } + @TestMetadata("TypeParameter.kt") public void testTypeParameter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/TypeParameter.kt");