Completion: escaping of named arguments

This commit is contained in:
Valentin Kipyatkov
2014-08-27 21:45:46 +04:00
parent d64f930ff1
commit 89aaa018fe
18 changed files with 63 additions and 50 deletions
@@ -36,7 +36,8 @@ import com.intellij.psi.filters.ClassFilter
import org.jetbrains.jet.plugin.util.FirstChildInParentFilter import org.jetbrains.jet.plugin.util.FirstChildInParentFilter
import org.jetbrains.jet.lang.psi.psiUtil.getCallNameExpression import org.jetbrains.jet.lang.psi.psiUtil.getCallNameExpression
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.jet.plugin.completion.handlers.BaseDeclarationInsertHandler import com.intellij.codeInsight.completion.InsertHandler
import org.jetbrains.jet.lang.resolve.name.Name
object NamedParametersCompletion { object NamedParametersCompletion {
private val positionFilter = AndFilter( private val positionFilter = AndFilter(
@@ -83,13 +84,14 @@ object NamedParametersCompletion {
val usedArguments = QuickFixUtil.getUsedParameters(callElement, valueArgument, funDescriptor) val usedArguments = QuickFixUtil.getUsedParameters(callElement, valueArgument, funDescriptor)
for (parameter in funDescriptor.getValueParameters()) { for (parameter in funDescriptor.getValueParameters()) {
val name = parameter.getName().asString() val name = parameter.getName()
if (name !in usedArguments) { val nameString = name.asString()
val lookupElement = LookupElementBuilder.create(parameter, name) if (nameString !in usedArguments) {
.withPresentableText("$name = ") val text = "$nameString ="
.withTailText("${DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(parameter.getType())}") val lookupElement = LookupElementBuilder.create(text)
.withTailText(" ${DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(parameter.getType())}")
.withIcon(JetIcons.PARAMETER) .withIcon(JetIcons.PARAMETER)
.withInsertHandler(NamedParameterInsertHandler) .withInsertHandler(NamedParameterInsertHandler(name))
.assignPriority(ItemPriority.NAMED_PARAMETER) .assignPriority(ItemPriority.NAMED_PARAMETER)
lookupElement.putUserData(JetCompletionCharFilter.ACCEPT_EQ, true); lookupElement.putUserData(JetCompletionCharFilter.ACCEPT_EQ, true);
@@ -99,7 +101,7 @@ object NamedParametersCompletion {
} }
} }
private object NamedParameterInsertHandler : BaseDeclarationInsertHandler() { private class NamedParameterInsertHandler(val parameterName: Name) : InsertHandler<LookupElement> {
override fun handleInsert(context: InsertionContext, item: LookupElement) { override fun handleInsert(context: InsertionContext, item: LookupElement) {
val ch = context.getCompletionChar() val ch = context.getCompletionChar()
if (ch == '=' || ch == ' ') { if (ch == '=' || ch == ' ') {
@@ -107,10 +109,9 @@ object NamedParametersCompletion {
} }
val editor = context.getEditor() val editor = context.getEditor()
val tailOffset = context.getTailOffset() val text = DescriptorRenderer.SOURCE_CODE.renderName(parameterName) + " = "
editor.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), text)
editor.getDocument().insertString(tailOffset, " = ") editor.getCaretModel().moveToOffset(context.getStartOffset() + text.length)
editor.getCaretModel().moveToOffset(tailOffset + 3)
} }
} }
} }
@@ -3,4 +3,4 @@ fun small(param: Int) {
fun test() = small(<caret>) fun test() = small(<caret>)
// EXIST: {"lookupString":"param","tailText":"Int","itemText":"param = "} // EXIST: {"lookupString":"param =","tailText":" Int","itemText":"param ="}
@@ -3,5 +3,5 @@ fun small(first: Int, second: Int) {
fun test() = small(12, <caret>) fun test() = small(12, <caret>)
// ABSENT: first // ABSENT: "first ="
// EXIST: second // EXIST: "second ="
@@ -7,5 +7,5 @@ fun small(paramFirst: ArrayList<String>, paramSecond: Comparable<java.lang.Runti
fun test() = small(<caret>) fun test() = small(<caret>)
// EXIST: {"lookupString":"paramSecond","tailText":"Comparable<RuntimeException>","itemText":"paramSecond = "} // EXIST: {"lookupString":"paramSecond =","tailText":" Comparable<RuntimeException>","itemText":"paramSecond ="}
// EXIST: {"lookupString":"paramFirst","tailText":"ArrayList<String>","itemText":"paramFirst = "} // EXIST: {"lookupString":"paramFirst =","tailText":" ArrayList<String>","itemText":"paramFirst ="}
@@ -6,6 +6,6 @@ fun small(paramFirst: Int, paramSecond: Int) {
fun test() = small(paramFirst = param<caret>) fun test() = small(paramFirst = param<caret>)
// EXIST: paramTest // EXIST: paramTest
// ABSENT: {"lookupString":"paramFirst","tailText":"Int","itemText":"paramFirst = "} // ABSENT: {"lookupString":"paramFirst =","tailText":" Int","itemText":"paramFirst ="}
// ABSENT: paramSecond // ABSENT: "paramSecond ="
// NUMBER: 1 // NUMBER: 1
@@ -10,11 +10,11 @@ fun other() {
foo(n<caret>) foo(n<caret>)
} }
// EXIST: nFirst // EXIST: "nFirst ="
// EXIST: nSecond // EXIST: "nSecond ="
// EXIST: nThird // EXIST: "nThird ="
// EXIST: nLocal // EXIST: nLocal
// todo - should exist // todo - should exist
// ABSENT: nClassParam // ABSENT: "nClassParam ="
// ABSENT: nClassField // ABSENT: "nClassField ="
@@ -6,5 +6,5 @@ fun other() {
Foo(p<caret>) Foo(p<caret>)
} }
// EXIST: {"lookupString":"pFirst","tailText":"String?","itemText":"pFirst = "} // EXIST: {"lookupString":"pFirst =","tailText":" String?","itemText":"pFirst ="}
// EXIST: {"lookupString":"pSecond","tailText":"Int","itemText":"pSecond = "} // EXIST: {"lookupString":"pSecond =","tailText":" Int","itemText":"pSecond ="}
@@ -4,8 +4,8 @@ fun test() {
foo("str", paramThird = "test", param<caret>) foo("str", paramThird = "test", param<caret>)
} }
// ABSENT: paramFirst // ABSENT: "paramFirst ="
// EXIST: paramSecond // EXIST: "paramSecond ="
// ABSENT: paramThird // ABSENT: "paramThird ="
// EXIST: paramFourth // EXIST: "paramFourth ="
@@ -5,7 +5,7 @@ fun test() {
foo(12, param<caret>) foo(12, param<caret>)
} }
// ABSENT: paramFirst // ABSENT: "paramFirst ="
// EXIST: {"lookupString":"paramSecond","tailText":"Int","itemText":"paramSecond = "} // EXIST: {"lookupString":"paramSecond =","tailText":" Int","itemText":"paramSecond ="}
// ABSENT: paramThird // ABSENT: "paramThird ="
// ABSENT: paramFourth // ABSENT: "paramFourth ="
@@ -4,6 +4,6 @@ fun foo(first: Int, second: Int, third: String) {
fun test(p: Int) = foo(12, <caret>, third = "") fun test(p: Int) = foo(12, <caret>, third = "")
// EXIST: p // EXIST: p
// ABSENT: first // ABSENT: "first ="
// EXIST: third // EXIST: "third ="
// EXIST: second // EXIST: "second ="
@@ -4,6 +4,6 @@ fun foo(first: Int, second: Int, third: String) {
fun test(p: Int) = foo(<caret>second = 3) fun test(p: Int) = foo(<caret>second = 3)
// EXIST: p // EXIST: p
// EXIST: first // EXIST: "first ="
// EXIST: second // EXIST: "second ="
// EXIST: third // EXIST: "third ="
@@ -4,7 +4,7 @@ fun foo(first: Int, second: Int, third: String) {
fun test(p: Int) = foo(12, third = "", <caret>) fun test(p: Int) = foo(12, third = "", <caret>)
// ABSENT: p // ABSENT: p
// ABSENT: first // ABSENT: "first ="
// ABSENT: third // ABSENT: "third ="
// EXIST: second // EXIST: "second ="
// NUMBER: 1 // NUMBER: 1
@@ -5,8 +5,8 @@ fun small(paramFirst: Int, paramSecond: Int) {
fun test() = small(param<caret>First = 12) fun test() = small(param<caret>First = 12)
// EXIST: paramFirst // EXIST: "paramFirst ="
// EXIST: paramSecond // EXIST: "paramSecond ="
// EXIST: paramTest // EXIST: paramTest
// NUMBER: 3 // NUMBER: 3
@@ -2,5 +2,5 @@ import lib.KotlinClass
fun test() = KotlinClass().foo(<caret>) fun test() = KotlinClass().foo(<caret>)
// ABSENT: p0 // ABSENT: "p0 ="
// EXIST: paramName // EXIST: "paramName ="
@@ -0,0 +1,5 @@
fun foo(`class`: Int) {}
fun test() {
foo(<caret>)
}
@@ -0,0 +1,5 @@
fun foo(`class`: Int) {}
fun test() {
foo(`class` = <caret>)
}
@@ -18,5 +18,5 @@ fun test(listParam: Int) {
// ORDER: listImportedVal // ORDER: listImportedVal
// ORDER: listThisFileFun // ORDER: listThisFileFun
// ORDER: listImportedFun // ORDER: listImportedFun
// ORDER: listMatch // ORDER: "listMatch ="
// ORDER: listNew // ORDER: "listNew ="
@@ -48,7 +48,9 @@ public class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
fun testNamedParametersCompletion() = doTest() fun testNamedParametersCompletion() = doTest()
fun testNamedParametersCompletionOnEqual() = doTest(0, "paramTest", null, '=') fun testNamedParametersCompletionOnEqual() = doTest(0, "paramTest =", null, '=')
fun testNamedParameterKeywordName() = doTest(1, "class =", null, '\n')
fun testInsertJavaClassImport() = doTest() fun testInsertJavaClassImport() = doTest()