From 81393c999b6a092c34c44a0b9df093ea670fcb3a Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 22 Jul 2014 17:46:08 +0400 Subject: [PATCH] Fixed KT-5231 Smart completion does not insert comma in super constructor argument list KT-5231 Fixed --- .../jet/plugin/completion/ExpectedInfos.kt | 29 ++++++++++--------- .../smart/CommaInSuperConstructorCall.kt | 5 ++++ .../CommaInSuperConstructorCall.kt.after | 5 ++++ .../SmartCompletionHandlerTestGenerated.java | 5 ++++ 4 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt create mode 100644 idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt b/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt index ef97d8a1f3f..f3662fb4ad1 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt +++ b/idea/src/org/jetbrains/jet/plugin/completion/ExpectedInfos.kt @@ -26,9 +26,6 @@ import com.intellij.lang.ASTNode import org.jetbrains.jet.lang.psi.JetQualifiedExpression import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.jet.lang.resolve.calls.util.CallMaker -import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext -import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace -import org.jetbrains.jet.lang.types.TypeUtils import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency import org.jetbrains.jet.lang.resolve.calls.context.CheckValueArgumentsMode @@ -56,6 +53,10 @@ import org.jetbrains.jet.plugin.util.makeNotNullable import org.jetbrains.jet.lang.psi.JetWhenConditionWithExpression import org.jetbrains.jet.lang.psi.JetWhenEntry import org.jetbrains.jet.lang.psi.JetWhenExpression +import org.jetbrains.jet.lang.psi.JetCallElement +import org.jetbrains.jet.lang.types.TypeUtils +import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext +import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace enum class Tail { COMMA @@ -82,8 +83,8 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo if (argument.isNamed()) return null //TODO - support named arguments (also do not forget to check for presence of named arguments before) val argumentList = argument.getParent() as JetValueArgumentList val argumentIndex = argumentList.getArguments().indexOf(argument) - val callExpression = argumentList.getParent() as? JetCallExpression ?: return null - return calculateForArgument(callExpression, argumentIndex, false) + val callElement = argumentList.getParent() as? JetCallElement ?: return null + return calculateForArgument(callElement, argumentIndex, false) } private fun calculateForFunctionLiteralArgument(expressionWithType: JetExpression): Collection? { @@ -97,13 +98,13 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo return null } - private fun calculateForArgument(callExpression: JetCallExpression, argumentIndex: Int, isFunctionLiteralArgument: Boolean): Collection? { - val calleeExpression = callExpression.getCalleeExpression() + private fun calculateForArgument(callElement: JetCallElement, argumentIndex: Int, isFunctionLiteralArgument: Boolean): Collection? { + val calleeExpression = callElement.getCalleeExpression() - val parent = callExpression.getParent() + val parent = callElement.getParent() val receiver: ReceiverValue val callOperationNode: ASTNode? - if (parent is JetQualifiedExpression && callExpression == parent.getSelectorExpression()) { + if (parent is JetQualifiedExpression && callElement == parent.getSelectorExpression()) { val receiverExpression = parent.getReceiverExpression() val expressionType = bindingContext[BindingContext.EXPRESSION_TYPE, receiverExpression] ?: return null receiver = ExpressionReceiver(receiverExpression, expressionType) @@ -113,7 +114,7 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo receiver = ReceiverValue.NO_RECEIVER callOperationNode = null } - var call = CallMaker.makeCall(receiver, callOperationNode, callExpression) + var call = CallMaker.makeCall(receiver, callOperationNode, callElement) if (!isFunctionLiteralArgument) { // leave only arguments before the current one call = object : DelegatingCall(call) { @@ -124,17 +125,19 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo val resolutionScope = bindingContext[BindingContext.RESOLUTION_SCOPE, calleeExpression] ?: return null //TODO: discuss it + val expectedType = (callElement as? JetExpression)?.let { bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, it] } ?: TypeUtils.NO_EXPECTED_TYPE + val dataFlowInfo = (callElement as? JetExpression)?.let { bindingContext[BindingContext.EXPRESSION_DATA_FLOW_INFO, it] } ?: DataFlowInfo.EMPTY val callResolutionContext = BasicCallResolutionContext.create( DelegatingBindingTrace(bindingContext, "Temporary trace for completion"), resolutionScope, call, - bindingContext[BindingContext.EXPECTED_EXPRESSION_TYPE, callExpression] ?: TypeUtils.NO_EXPECTED_TYPE, - bindingContext[BindingContext.EXPRESSION_DATA_FLOW_INFO, callExpression] ?: DataFlowInfo.EMPTY, + expectedType, + dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, CompositeExtension(listOf()), false).replaceCollectAllCandidates(true) - val callResolver = InjectorForMacros(callExpression.getProject(), moduleDescriptor).getCallResolver()!! + val callResolver = InjectorForMacros(callElement.getProject(), moduleDescriptor).getCallResolver()!! val results: OverloadResolutionResults = callResolver.resolveFunctionCall(callResolutionContext) val expectedInfos = HashSet() diff --git a/idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt b/idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt new file mode 100644 index 00000000000..010d20b6d52 --- /dev/null +++ b/idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt @@ -0,0 +1,5 @@ +open class Base(p1: String, p2: String) + +class Derived(s: String) : Base() + +// ELEMENT: s diff --git a/idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt.after b/idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt.after new file mode 100644 index 00000000000..db7a024fb87 --- /dev/null +++ b/idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt.after @@ -0,0 +1,5 @@ +open class Base(p1: String, p2: String) + +class Derived(s: String) : Base(s, ) + +// ELEMENT: s diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java index ba61d899dbd..26ca5b602a5 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/SmartCompletionHandlerTestGenerated.java @@ -131,6 +131,11 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest("idea/testData/completion/handlers/smart/Comma9.kt"); } + @TestMetadata("CommaInSuperConstructorCall.kt") + public void testCommaInSuperConstructorCall() throws Exception { + doTest("idea/testData/completion/handlers/smart/CommaInSuperConstructorCall.kt"); + } + @TestMetadata("Constructor.kt") public void testConstructor() throws Exception { doTest("idea/testData/completion/handlers/smart/Constructor.kt");