From d674f519fd1a54184c23c727986de2488826ec8f Mon Sep 17 00:00:00 2001 From: Pavel Kirpichenkov Date: Fri, 4 Sep 2020 18:34:55 +0300 Subject: [PATCH] [FIR-IDE] Fix completion check for generic extensions Generic candidate extensions are completed in partial mode when there is not enough information for type parameter in return position. Partial completion mode in single candidate resolver leads to unconditionally failing candidate. Providing noExpectedType instead of null guarantees full completion. --- .../common/extensions/ParametrizedExpectedType.kt | 11 +++++++++++ .../test/JSBasicCompletionTestGenerated.java | 5 +++++ .../test/JvmBasicCompletionTestGenerated.java | 5 +++++ .../HighLevelJvmBasicCompletionTestGenerated.java | 5 +++++ .../low/level/api/resolver/SingleCandidateResolver.kt | 3 ++- 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt diff --git a/idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt b/idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt new file mode 100644 index 00000000000..161971cffd1 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt @@ -0,0 +1,11 @@ +// FIR_COMPARISON +class Generic + +fun Generic.extension(arg: (A) -> B): B = TODO() + +fun test() { + val v = Generic() + v.ext +} + +// EXIST: extension diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java index 22269f0a6b0..7489de821c2 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java @@ -1433,6 +1433,11 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes runTest("idea/idea-completion/testData/basic/common/extensions/NoMemberExtensionsFromCompanionObject.kt"); } + @TestMetadata("ParametrizedExpectedType.kt") + public void testParametrizedExpectedType() throws Exception { + runTest("idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt"); + } + @TestMetadata("StarTypeArg.kt") public void testStarTypeArg() throws Exception { runTest("idea/idea-completion/testData/basic/common/extensions/StarTypeArg.kt"); diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java index 9af0da044a0..0650bc59a81 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java @@ -1433,6 +1433,11 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT runTest("idea/idea-completion/testData/basic/common/extensions/NoMemberExtensionsFromCompanionObject.kt"); } + @TestMetadata("ParametrizedExpectedType.kt") + public void testParametrizedExpectedType() throws Exception { + runTest("idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt"); + } + @TestMetadata("StarTypeArg.kt") public void testStarTypeArg() throws Exception { runTest("idea/idea-completion/testData/basic/common/extensions/StarTypeArg.kt"); diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/completion/HighLevelJvmBasicCompletionTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/completion/HighLevelJvmBasicCompletionTestGenerated.java index 4f40129b48b..266a53a6f01 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/completion/HighLevelJvmBasicCompletionTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/completion/HighLevelJvmBasicCompletionTestGenerated.java @@ -1433,6 +1433,11 @@ public class HighLevelJvmBasicCompletionTestGenerated extends AbstractHighLevelJ runTest("idea/idea-completion/testData/basic/common/extensions/NoMemberExtensionsFromCompanionObject.kt"); } + @TestMetadata("ParametrizedExpectedType.kt") + public void testParametrizedExpectedType() throws Exception { + runTest("idea/idea-completion/testData/basic/common/extensions/ParametrizedExpectedType.kt"); + } + @TestMetadata("StarTypeArg.kt") public void testStarTypeArg() throws Exception { runTest("idea/idea-completion/testData/basic/common/extensions/StarTypeArg.kt"); diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt index 3da86b3e175..34ffd5dab69 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/resolver/SingleCandidateResolver.kt @@ -90,7 +90,8 @@ class SingleCandidateResolver( candidate = candidate ) } - val completionResult = firCallCompleter.completeCall(fakeCall, resolutionParameters.expectedType) + val expectedType = resolutionParameters.expectedType ?: bodyResolveComponents.noExpectedType + val completionResult = firCallCompleter.completeCall(fakeCall, expectedType) return if (completionResult.callCompleted) { completionResult.result } else null