Fixed KT-5231 Smart completion does not insert comma in super constructor argument list

KT-5231 Fixed
This commit is contained in:
Valentin Kipyatkov
2014-07-22 17:46:08 +04:00
parent c8c8b477ef
commit 81393c999b
4 changed files with 31 additions and 13 deletions
@@ -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<ExpectedInfo>? {
@@ -97,13 +98,13 @@ class ExpectedInfos(val bindingContext: BindingContext, val moduleDescriptor: Mo
return null
}
private fun calculateForArgument(callExpression: JetCallExpression, argumentIndex: Int, isFunctionLiteralArgument: Boolean): Collection<ExpectedInfo>? {
val calleeExpression = callExpression.getCalleeExpression()
private fun calculateForArgument(callElement: JetCallElement, argumentIndex: Int, isFunctionLiteralArgument: Boolean): Collection<ExpectedInfo>? {
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<FunctionDescriptor> = callResolver.resolveFunctionCall(callResolutionContext)
val expectedInfos = HashSet<ExpectedInfo>()
@@ -0,0 +1,5 @@
open class Base(p1: String, p2: String)
class Derived(s: String) : Base(<caret>)
// ELEMENT: s
@@ -0,0 +1,5 @@
open class Base(p1: String, p2: String)
class Derived(s: String) : Base(s, <caret>)
// ELEMENT: s
@@ -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");