KT-12068 Special completion item for "[]" get-operator access
#KT-12068 Fixed
This commit is contained in:
@@ -67,6 +67,7 @@ tailrec fun <T : Any> LookupElement.getUserDataDeep(key: Key<T>): T? {
|
||||
enum class ItemPriority {
|
||||
SUPER_METHOD_WITH_ARGUMENTS,
|
||||
FROM_UNRESOLVED_NAME_SUGGESTION,
|
||||
GET_OPERATOR,
|
||||
DEFAULT,
|
||||
IMPLEMENT,
|
||||
OVERRIDE,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.codeInsight.AutoPopupController
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||
@@ -27,6 +28,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.GenerateLambdaInfo
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.lambdaPresentation
|
||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.util.CallType
|
||||
import org.jetbrains.kotlin.idea.util.toFuzzyType
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
@@ -42,6 +44,7 @@ import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
interface AbstractLookupElementFactory {
|
||||
@@ -100,6 +103,31 @@ class LookupElementFactory(
|
||||
}
|
||||
}
|
||||
|
||||
// special "[]" item for get-operator
|
||||
if (callType == CallType.DOT && descriptor is FunctionDescriptor && descriptor.isOperator() && descriptor.name == OperatorNameConventions.GET) {
|
||||
val baseLookupElement = createLookupElement(descriptor, useReceiverTypes)
|
||||
val lookupElement = object : LookupElementDecorator<LookupElement>(baseLookupElement) {
|
||||
override fun getLookupString() = "[]"
|
||||
override fun getAllLookupStrings() = setOf(lookupString)
|
||||
|
||||
override fun renderElement(presentation: LookupElementPresentation) {
|
||||
super.renderElement(presentation)
|
||||
presentation.itemText = lookupString
|
||||
}
|
||||
|
||||
override fun handleInsert(context: InsertionContext) {
|
||||
val startOffset = context.startOffset
|
||||
assert(context.document.charsSequence[startOffset - 1] == '.')
|
||||
context.document.deleteString(startOffset - 1, startOffset)
|
||||
context.editor.moveCaret(startOffset)
|
||||
|
||||
AutoPopupController.getInstance(context.project)?.autoPopupParameterInfo(context.editor, null)
|
||||
}
|
||||
}
|
||||
lookupElement.assignPriority(ItemPriority.GET_OPERATOR)
|
||||
result.add(lookupElement)
|
||||
}
|
||||
|
||||
return result.map(standardLookupElementsPostProcessor)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package p
|
||||
|
||||
class C
|
||||
|
||||
operator fun C.get(p: Int): Int = 0
|
||||
|
||||
fun foo(c: C) {
|
||||
c.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "[]", itemText: "[]", tailText: "(p: Int) for C in p", typeText: "Int", attributes: "bold" }
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some(list: List<String>?) {
|
||||
list?.<caret>
|
||||
}
|
||||
|
||||
// ABSENT: "[]"
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some(list: List<String>) {
|
||||
list.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "[]", itemText: "[]", tailText: "(index: Int)", typeText: "String", attributes: "bold" }
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some(list: List<String>) {
|
||||
list.<caret>
|
||||
}
|
||||
|
||||
// ELEMENT: "[]"
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some(list: List<String>) {
|
||||
list[<caret>]
|
||||
}
|
||||
|
||||
// ELEMENT: "[]"
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some(list: List<String>): String {
|
||||
return list.<caret>
|
||||
}
|
||||
|
||||
// EXIST: { lookupString: "[]", itemText: "[]", tailText: "(index: Int)", typeText: "String", attributes: "bold" }
|
||||
+27
@@ -1519,6 +1519,33 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/getOperator")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class GetOperator extends AbstractJSBasicCompletionTest {
|
||||
public void testAllFilesPresentInGetOperator() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/getOperator"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("Extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/getOperator/Extension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NotForSafeCall.kt")
|
||||
public void testNotForSafeCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/getOperator/NotForSafeCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/getOperator/Simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+27
@@ -1519,6 +1519,33 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/getOperator")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class GetOperator extends AbstractJvmBasicCompletionTest {
|
||||
public void testAllFilesPresentInGetOperator() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/getOperator"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("Extension.kt")
|
||||
public void testExtension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/getOperator/Extension.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("NotForSafeCall.kt")
|
||||
public void testNotForSafeCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/getOperator/NotForSafeCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/getOperator/Simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/idea-completion/testData/basic/common/highOrderFunctions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+6
@@ -149,6 +149,12 @@ public class JvmSmartCompletionTestGenerated extends AbstractJvmSmartCompletionT
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GetOperator.kt")
|
||||
public void testGetOperator() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/GetOperator.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GroupBySubstitutor.kt")
|
||||
public void testGroupBySubstitutor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/smart/GroupBySubstitutor.kt");
|
||||
|
||||
+6
@@ -119,6 +119,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("GetOperator.kt")
|
||||
public void testGetOperator() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/GetOperator.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("InterfaceNameBeforeRunBug.kt")
|
||||
public void testInterfaceNameBeforeRunBug() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/InterfaceNameBeforeRunBug.kt");
|
||||
|
||||
Reference in New Issue
Block a user