From 0a3631db6a2ee8d5d1240c03718df766da63bef2 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 11 Jan 2016 21:39:02 +0300 Subject: [PATCH] Fixed KT-10602 Incorrect completion for class name #KT-10602 Fixed --- .../completion/smart/ClassLiteralItems.kt | 22 ++++++++++++++----- .../handlers/smart/ArrayClassLiteral.kt | 7 ++++++ .../handlers/smart/ArrayClassLiteral.kt.after | 7 ++++++ .../handlers/smart/ConcreteJavaClass.kt | 2 +- .../handlers/smart/ConcreteJavaClass.kt.after | 2 +- .../handlers/smart/ConcreteJavaClass2.kt | 2 +- .../smart/ConcreteJavaClass2.kt.after | 2 +- .../testData/handlers/smart/ConcreteKClass.kt | 2 +- .../handlers/smart/ConcreteKClass.kt.after | 2 +- .../testData/handlers/smart/kt10602.kt | 7 ++++++ .../testData/handlers/smart/kt10602.kt.after | 7 ++++++ .../ConcreteJavaClassExpected.kt | 2 +- .../ConcreteKClassExpected.kt | 2 +- .../ConcreteKClassExpectedNoDuplicates.kt | 2 +- .../SmartCompletionHandlerTestGenerated.java | 12 ++++++++++ 15 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt create mode 100644 idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt.after create mode 100644 idea/idea-completion/testData/handlers/smart/kt10602.kt create mode 100644 idea/idea-completion/testData/handlers/smart/kt10602.kt.after diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/ClassLiteralItems.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/ClassLiteralItems.kt index 8da84b6e9d6..2cb4648ee4f 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/ClassLiteralItems.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/smart/ClassLiteralItems.kt @@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.InsertionContext import com.intellij.codeInsight.lookup.LookupElement import com.intellij.codeInsight.lookup.LookupElementDecorator import com.intellij.codeInsight.lookup.LookupElementPresentation +import com.intellij.psi.PsiDocumentManager import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.completion.BasicLookupElementFactory @@ -30,6 +31,7 @@ import org.jetbrains.kotlin.idea.imports.importableFqName import org.jetbrains.kotlin.idea.quickfix.moveCaret import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import java.util.* object ClassLiteralItems { @@ -60,19 +62,27 @@ object ClassLiteralItems { for ((pair, matchedExpectedInfos) in typeAndSuffixToExpectedInfos) { val (type, suffix) = pair - var lookupElement = lookupElementFactory.createLookupElementForType(type) ?: continue - val text = lookupElement.lookupString + suffix - lookupElement = object : LookupElementDecorator(lookupElement) { - override fun getLookupString() = text - override fun getAllLookupStrings() = setOf(lookupString) + val typeToUse = if (KotlinBuiltIns.isArray(type)) { + type.makeNotNullable() + } + else { + val classifier = (type.constructor.declarationDescriptor as? ClassDescriptor) ?: continue + classifier.defaultType + } + var lookupElement = lookupElementFactory.createLookupElementForType(typeToUse) ?: continue + + lookupElement = object : LookupElementDecorator(lookupElement) { override fun renderElement(presentation: LookupElementPresentation) { super.renderElement(presentation) - presentation.itemText = text + presentation.itemText += suffix } override fun handleInsert(context: InsertionContext) { super.handleInsert(context) + + PsiDocumentManager.getInstance(context.project).doPostponedOperationsAndUnblockDocument(context.document) + val offset = context.tailOffset context.document.insertString(offset, suffix) context.editor.moveCaret(offset + suffix.length) diff --git a/idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt b/idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt new file mode 100644 index 00000000000..57f2cb5c839 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt @@ -0,0 +1,7 @@ +fun f(klass: Class>) { +} + +fun g() { + f() +} +// ELEMENT: Array \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt.after b/idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt.after new file mode 100644 index 00000000000..591ebd70312 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt.after @@ -0,0 +1,7 @@ +fun f(klass: Class>) { +} + +fun g() { + f(Array::class.java) +} +// ELEMENT: Array \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt index b967ac87719..8eb88d09cd5 100644 --- a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt +++ b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt @@ -2,4 +2,4 @@ open class A(val javaClass: Class?) class B : A() -// ELEMENT: "File::class.java" +// ELEMENT: File diff --git a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt.after b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt.after index 354c4f50f9c..bdb7dbe72e6 100644 --- a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt.after +++ b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass.kt.after @@ -4,4 +4,4 @@ open class A(val javaClass: Class?) class B : A(File::class.java) -// ELEMENT: "File::class.java" +// ELEMENT: File diff --git a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt index c6d79e4466c..dda5400f7b4 100644 --- a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt +++ b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt @@ -4,5 +4,5 @@ fun bar() { foo() } -// ELEMENT: "String::class.java" +// ELEMENT: String diff --git a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt.after b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt.after index d7c838a578a..c0054e3c01e 100644 --- a/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt.after +++ b/idea/idea-completion/testData/handlers/smart/ConcreteJavaClass2.kt.after @@ -4,5 +4,5 @@ fun bar() { foo(String::class.java) } -// ELEMENT: "String::class.java" +// ELEMENT: String diff --git a/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt b/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt index 4f19f582cf3..8c3642e50ee 100644 --- a/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt +++ b/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt @@ -4,4 +4,4 @@ open class A(val kClass: KClass?) class B : A() -// ELEMENT: "File::class" +// ELEMENT: File diff --git a/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt.after b/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt.after index e2f4c5d7f39..5c39b041d44 100644 --- a/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt.after +++ b/idea/idea-completion/testData/handlers/smart/ConcreteKClass.kt.after @@ -5,4 +5,4 @@ open class A(val kClass: KClass?) class B : A(File::class) -// ELEMENT: "File::class" +// ELEMENT: File diff --git a/idea/idea-completion/testData/handlers/smart/kt10602.kt b/idea/idea-completion/testData/handlers/smart/kt10602.kt new file mode 100644 index 00000000000..1980b9d2878 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/kt10602.kt @@ -0,0 +1,7 @@ +import java.util.concurrent.atomic.* + +fun f() { + AtomicReferenceFieldUpdater.newUpdater() +} + +// ELEMENT: String \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/smart/kt10602.kt.after b/idea/idea-completion/testData/handlers/smart/kt10602.kt.after new file mode 100644 index 00000000000..bc14066b664 --- /dev/null +++ b/idea/idea-completion/testData/handlers/smart/kt10602.kt.after @@ -0,0 +1,7 @@ +import java.util.concurrent.atomic.* + +fun f() { + AtomicReferenceFieldUpdater.newUpdater(String::class.java, ) +} + +// ELEMENT: String \ No newline at end of file diff --git a/idea/idea-completion/testData/smart/callableReference/ConcreteJavaClassExpected.kt b/idea/idea-completion/testData/smart/callableReference/ConcreteJavaClassExpected.kt index 1a05d771015..db3ec15553e 100644 --- a/idea/idea-completion/testData/smart/callableReference/ConcreteJavaClassExpected.kt +++ b/idea/idea-completion/testData/smart/callableReference/ConcreteJavaClassExpected.kt @@ -2,4 +2,4 @@ open class A(val javaClass: Class) class B : A() -// EXIST_JAVA_ONLY: { lookupString: "String::class.java", itemText: "String::class.java", attributes: "" } +// EXIST_JAVA_ONLY: { lookupString: "String", itemText: "String::class.java", attributes: "" } diff --git a/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpected.kt b/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpected.kt index 497e763ac3b..c3d9c709f18 100644 --- a/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpected.kt +++ b/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpected.kt @@ -4,4 +4,4 @@ open class A(val kClass: KClass) class B : A() -// EXIST: { lookupString: "String::class", itemText: "String::class", attributes: "" } +// EXIST: { lookupString: "String", itemText: "String::class", attributes: "" } diff --git a/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpectedNoDuplicates.kt b/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpectedNoDuplicates.kt index 312571ba0f3..05710c346a9 100644 --- a/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpectedNoDuplicates.kt +++ b/idea/idea-completion/testData/smart/callableReference/ConcreteKClassExpectedNoDuplicates.kt @@ -8,7 +8,7 @@ fun f() { } // WITH_ORDER -// EXIST: { lookupString: "Int::class", itemText: "Int::class", attributes: "" } +// EXIST: { lookupString: "Int", itemText: "Int::class", attributes: "" } // EXIST: { lookupString: "object" } // EXIST: null // NOTHING_ELSE diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java index 3c93cbf4c0d..5b7a9465eed 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/SmartCompletionHandlerTestGenerated.java @@ -95,6 +95,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest(fileName); } + @TestMetadata("ArrayClassLiteral.kt") + public void testArrayClassLiteral() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/ArrayClassLiteral.kt"); + doTest(fileName); + } + @TestMetadata("AutoCompleteAfterAs1.kt") public void testAutoCompleteAfterAs1() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/AutoCompleteAfterAs1.kt"); @@ -515,6 +521,12 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion doTest(fileName); } + @TestMetadata("kt10602.kt") + public void testKt10602() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/kt10602.kt"); + doTest(fileName); + } + @TestMetadata("kt6179filterTo.kt") public void testKt6179filterTo() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/smart/kt6179filterTo.kt");