From 7663793e3db2dcbcf53e74fd3f984add3279989c Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 3 Sep 2015 14:03:26 +0300 Subject: [PATCH] Smart completion to work when some of previous arguments have errors (+ fixed testAfterEmptyArgument broken by previous changes) --- .../kotlin/idea/completion/ExpectedInfos.kt | 9 +++++++-- .../testData/smart/PreviousArgError.kt | 16 ++++++++++++++++ .../smart/PreviousArgMismatchedType.kt.todo | 16 ++++++++++++++++ .../test/JvmSmartCompletionTestGenerated.java | 6 ++++++ 4 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 idea/idea-completion/testData/smart/PreviousArgError.kt create mode 100644 idea/idea-completion/testData/smart/PreviousArgMismatchedType.kt.todo 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 cbffdbc423c..add40185c77 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 @@ -37,7 +37,6 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo import org.jetbrains.kotlin.resolve.bindingContextUtil.getTargetFunctionDescriptor import org.jetbrains.kotlin.resolve.calls.CallResolver import org.jetbrains.kotlin.resolve.calls.callUtil.getCall -import org.jetbrains.kotlin.resolve.calls.callUtil.noErrorsInValueArguments import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode @@ -250,7 +249,7 @@ class ExpectedInfos( if (status == ResolutionStatus.RECEIVER_TYPE_ERROR || status == ResolutionStatus.RECEIVER_PRESENCE_ERROR) continue // check that all arguments before the current one matched - if (!candidate.noErrorsInValueArguments()) continue + if (!candidate.allArgumentsMatched()) continue var descriptor = candidate.getResultingDescriptor() if (descriptor.valueParameters.isEmpty()) continue @@ -352,6 +351,12 @@ class ExpectedInfos( return expectedInfos } + private fun ResolvedCall.allArgumentsMatched() + = call.valueArguments.none { argument -> getArgumentMapping(argument).isError() && !argument.hasError() /* ignore arguments that has error type */ } + + private fun ValueArgument.hasError() + = getArgumentExpression()?.let { bindingContext.getType(it) }?.isError ?: true + private fun namedArgumentTail(argumentToParameter: Map, argumentName: Name, descriptor: FunctionDescriptor): Tail? { val usedParameterNames = (argumentToParameter.values().map { it.getName() } + listOf(argumentName)).toSet() val notUsedParameters = descriptor.getValueParameters().filter { it.getName() !in usedParameterNames } diff --git a/idea/idea-completion/testData/smart/PreviousArgError.kt b/idea/idea-completion/testData/smart/PreviousArgError.kt new file mode 100644 index 00000000000..9288dd9d16a --- /dev/null +++ b/idea/idea-completion/testData/smart/PreviousArgError.kt @@ -0,0 +1,16 @@ +class A +class B +class C +class D +class E + +fun foo(s: String, a: A){} +fun foo(p: Int, b: B, c: C){} +fun foo(s: String, d: D, e: E, a: A){} + +fun f(pa: A, pb: B, pc: C, pd: D, pe: E) { + foo(xxx, pb, ) +} + +// EXIST: pc +// ABSENT: pa, pb, pd, pe diff --git a/idea/idea-completion/testData/smart/PreviousArgMismatchedType.kt.todo b/idea/idea-completion/testData/smart/PreviousArgMismatchedType.kt.todo new file mode 100644 index 00000000000..b7e2c703831 --- /dev/null +++ b/idea/idea-completion/testData/smart/PreviousArgMismatchedType.kt.todo @@ -0,0 +1,16 @@ +class A +class B +class C +class D +class E + +fun foo(a: A){} +fun foo(b: B, c: C){} +fun foo(d: D, e: E, a: A){} + +fun f(pa: A, pb: B, pc: C, pd: D, pe: E) { + foo(pa, ) +} + +// EXIST: pc, pe +// ABSENT: pa, pb, pd 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 bd3f1ee4961..c43e8b04388 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 @@ -413,6 +413,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT doTest(fileName); } + @TestMetadata("PreviousArgError.kt") + public void testPreviousArgError() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/PreviousArgError.kt"); + doTest(fileName); + } + @TestMetadata("QualifiedOverloadedMethodCallArgument1.kt") public void testQualifiedOverloadedMethodCallArgument1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/QualifiedOverloadedMethodCallArgument1.kt");