Insert ']' instead of ')'

This commit is contained in:
Valentin Kipyatkov
2015-10-06 17:25:30 +03:00
parent fa51ca5716
commit c876759ee0
7 changed files with 52 additions and 11 deletions
@@ -133,15 +133,16 @@ class ExpectedInfo(
val ExpectedInfo.fuzzyType: FuzzyType? val ExpectedInfo.fuzzyType: FuzzyType?
get() = (this.filter as? ByExpectedTypeFilter)?.fuzzyType get() = (this.filter as? ByExpectedTypeFilter)?.fuzzyType
sealed class ArgumentPositionData(val function: FunctionDescriptor) : ExpectedInfo.AdditionalData { sealed class ArgumentPositionData(val function: FunctionDescriptor, val callType: Call.CallType) : ExpectedInfo.AdditionalData {
class Positional( class Positional(
function: FunctionDescriptor, function: FunctionDescriptor,
callType: Call.CallType,
val argumentIndex: Int, val argumentIndex: Int,
val isFunctionLiteralArgument: Boolean, val isFunctionLiteralArgument: Boolean,
val namedArgumentCandidates: Collection<ParameterDescriptor> val namedArgumentCandidates: Collection<ParameterDescriptor>
) : ArgumentPositionData(function) ) : ArgumentPositionData(function, callType)
class Named(function: FunctionDescriptor, val argumentName: Name) : ArgumentPositionData(function) class Named(function: FunctionDescriptor, callType: Call.CallType, val argumentName: Name) : ArgumentPositionData(function, callType)
} }
class ReturnValueAdditionalData(val callable: CallableDescriptor) : ExpectedInfo.AdditionalData class ReturnValueAdditionalData(val callable: CallableDescriptor) : ExpectedInfo.AdditionalData
@@ -309,8 +310,10 @@ class ExpectedInfos(
val argumentName = argument.getArgumentName()?.asName val argumentName = argument.getArgumentName()?.asName
val isFunctionLiteralArgument = argument is FunctionLiteralArgument val isFunctionLiteralArgument = argument is FunctionLiteralArgument
val callType = call.callType
val argumentPositionData = if (argumentName != null) { val argumentPositionData = if (argumentName != null) {
ArgumentPositionData.Named(descriptor, argumentName) ArgumentPositionData.Named(descriptor, callType, argumentName)
} }
else { else {
val namedArgumentCandidates = if (!isFunctionLiteralArgument && descriptor.hasStableParameterNames()) { val namedArgumentCandidates = if (!isFunctionLiteralArgument && descriptor.hasStableParameterNames()) {
@@ -320,10 +323,9 @@ class ExpectedInfos(
else { else {
emptyList() emptyList()
} }
ArgumentPositionData.Positional(descriptor, argumentIndex, isFunctionLiteralArgument, namedArgumentCandidates) ArgumentPositionData.Positional(descriptor, callType, argumentIndex, isFunctionLiteralArgument, namedArgumentCandidates)
} }
val callType = call.callType
val isArrayAccess = callType == Call.CallType.ARRAY_GET_METHOD || callType == Call.CallType.ARRAY_SET_METHOD val isArrayAccess = callType == Call.CallType.ARRAY_GET_METHOD || callType == Call.CallType.ARRAY_SET_METHOD
val rparenthTail = if (isArrayAccess) Tail.RBRACKET else Tail.RPARENTH val rparenthTail = if (isArrayAccess) Tail.RBRACKET else Tail.RPARENTH
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.completion.SmartCastCalculator
import org.jetbrains.kotlin.idea.completion.Tail import org.jetbrains.kotlin.idea.completion.Tail
import org.jetbrains.kotlin.idea.util.getVariableFromImplicitReceivers import org.jetbrains.kotlin.idea.util.getVariableFromImplicitReceivers
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.renderer.render import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -47,16 +48,21 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext,
val added = HashSet<String>() val added = HashSet<String>()
for (expectedInfo in expectedInfos) { for (expectedInfo in expectedInfos) {
if (expectedInfo.additionalData is ArgumentPositionData.Positional && expectedInfo.additionalData.argumentIndex == 0) { val additionalData = expectedInfo.additionalData
val parameters = expectedInfo.additionalData.function.valueParameters if (additionalData is ArgumentPositionData.Positional && additionalData.argumentIndex == 0) {
val parameters = additionalData.function.valueParameters
if (parameters.size() > 1) { if (parameters.size() > 1) {
val tail = when (additionalData.callType) {
Call.CallType.ARRAY_GET_METHOD, Call.CallType.ARRAY_SET_METHOD -> Tail.RBRACKET
else -> Tail.RPARENTH
}
val variables = ArrayList<VariableDescriptor>() val variables = ArrayList<VariableDescriptor>()
for ((i, parameter) in parameters.withIndex()) { for ((i, parameter) in parameters.withIndex()) {
val variable = variableInScope(parameter, resolutionScope) ?: break val variable = variableInScope(parameter, resolutionScope) ?: break
variables.add(variable) // TODO: cannot inline variable because of KT-5890 variables.add(variable) // TODO: cannot inline variable because of KT-5890
if (i > 0 && parameters.asSequence().drop(i + 1).all { it.hasDefaultValue() }) { // this is the last parameter or all others have default values if (i > 0 && parameters.asSequence().drop(i + 1).all { it.hasDefaultValue() }) { // this is the last parameter or all others have default values
val lookupElement = createParametersLookupElement(variables) val lookupElement = createParametersLookupElement(variables, tail)
if (added.add(lookupElement.getLookupString())) { // check that we don't already have item with the same text if (added.add(lookupElement.getLookupString())) { // check that we don't already have item with the same text
collection.add(lookupElement) collection.add(lookupElement)
} }
@@ -67,7 +73,7 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext,
} }
} }
private fun createParametersLookupElement(variables: List<VariableDescriptor>): LookupElement { private fun createParametersLookupElement(variables: List<VariableDescriptor>, tail: Tail): LookupElement {
val compoundIcon = LayeredIcon(2) val compoundIcon = LayeredIcon(2)
val firstIcon = JetDescriptorIconProvider.getIcon(variables.first(), null, 0) val firstIcon = JetDescriptorIconProvider.getIcon(variables.first(), null, 0)
val lastIcon = JetDescriptorIconProvider.getIcon(variables.last(), null, 0) val lastIcon = JetDescriptorIconProvider.getIcon(variables.last(), null, 0)
@@ -86,7 +92,7 @@ class MultipleArgumentsItemProvider(val bindingContext: BindingContext,
} }
.withIcon(compoundIcon) .withIcon(compoundIcon)
.addTail(Tail.RPARENTH) //TODO: support square brackets .addTail(tail)
.assignSmartCompletionPriority(SmartCompletionItemPriority.MULTIPLE_ARGUMENTS_ITEM) .assignSmartCompletionPriority(SmartCompletionItemPriority.MULTIPLE_ARGUMENTS_ITEM)
} }
@@ -0,0 +1,7 @@
operator fun String.get(a: Int, b: String, c: String): Int = 0
fun bar(b: String, a: Int, c: String) {
""[<caret>]
}
// ELEMENT: "a, b, c"
@@ -0,0 +1,7 @@
operator fun String.get(a: Int, b: String, c: String): Int = 0
fun bar(b: String, a: Int, c: String) {
""[a, b, c]<caret>
}
// ELEMENT: "a, b, c"
@@ -0,0 +1,7 @@
operator fun String.get(a: Int, b: String, c: String): Int = 0
fun bar(b: String, a: Int, c: String) {
""[<caret>]
}
// EXIST: "a, b, c"
@@ -1356,6 +1356,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
public void testAllFilesPresentInMultipleArgsItem() throws Exception { public void testAllFilesPresentInMultipleArgsItem() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/smart/multipleArgsItem"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/smart/multipleArgsItem"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@TestMetadata("CallWithBrackets.kt")
public void testCallWithBrackets() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/smart/multipleArgsItem/CallWithBrackets.kt");
doTest(fileName);
}
} }
@TestMetadata("idea/idea-completion/testData/smart/smartCasts") @TestMetadata("idea/idea-completion/testData/smart/smartCasts")
@@ -569,6 +569,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
doTest(fileName); doTest(fileName);
} }
@TestMetadata("MultipleArgsIntoBrackets.kt")
public void testMultipleArgsIntoBrackets() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/MultipleArgsIntoBrackets.kt");
doTest(fileName);
}
@TestMetadata("MultipleArgsItem.kt") @TestMetadata("MultipleArgsItem.kt")
public void testMultipleArgsItem() throws Exception { public void testMultipleArgsItem() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/MultipleArgsItem.kt"); String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/MultipleArgsItem.kt");