Fixed KT-10602 Incorrect completion for class name

#KT-10602 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-01-11 21:39:02 +03:00
parent 12b9002c0e
commit 0a3631db6a
15 changed files with 65 additions and 15 deletions
@@ -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>(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>(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)
@@ -0,0 +1,7 @@
fun<T> f(klass: Class<Array<T>>) {
}
fun g() {
f<String>(<caret>)
}
// ELEMENT: Array
@@ -0,0 +1,7 @@
fun<T> f(klass: Class<Array<T>>) {
}
fun g() {
f<String>(Array<String>::class.java)<caret>
}
// ELEMENT: Array
@@ -2,4 +2,4 @@ open class A<T : Any>(val javaClass: Class<T>?)
class B : A<java.io.File>(<caret>)
// ELEMENT: "File::class.java"
// ELEMENT: File
@@ -4,4 +4,4 @@ open class A<T : Any>(val javaClass: Class<T>?)
class B : A<java.io.File>(File::class.java)<caret>
// ELEMENT: "File::class.java"
// ELEMENT: File
@@ -4,5 +4,5 @@ fun bar() {
foo<String>(<caret>)
}
// ELEMENT: "String::class.java"
// ELEMENT: String
@@ -4,5 +4,5 @@ fun bar() {
foo<String>(String::class.java)<caret>
}
// ELEMENT: "String::class.java"
// ELEMENT: String
@@ -4,4 +4,4 @@ open class A<T : Any>(val kClass: KClass<T>?)
class B : A<java.io.File>(<caret>)
// ELEMENT: "File::class"
// ELEMENT: File
@@ -5,4 +5,4 @@ open class A<T : Any>(val kClass: KClass<T>?)
class B : A<java.io.File>(File::class)<caret>
// ELEMENT: "File::class"
// ELEMENT: File
@@ -0,0 +1,7 @@
import java.util.concurrent.atomic.*
fun f() {
AtomicReferenceFieldUpdater.newUpdater<String, Int>(<caret>)
}
// ELEMENT: String
@@ -0,0 +1,7 @@
import java.util.concurrent.atomic.*
fun f() {
AtomicReferenceFieldUpdater.newUpdater<String, Int>(String::class.java, <caret>)
}
// ELEMENT: String
@@ -2,4 +2,4 @@ open class A<T : Any>(val javaClass: Class<T>)
class B : A<String>(<caret>)
// EXIST_JAVA_ONLY: { lookupString: "String::class.java", itemText: "String::class.java", attributes: "" }
// EXIST_JAVA_ONLY: { lookupString: "String", itemText: "String::class.java", attributes: "" }
@@ -4,4 +4,4 @@ open class A<T : Any>(val kClass: KClass<T>)
class B : A<String>(<caret>)
// EXIST: { lookupString: "String::class", itemText: "String::class", attributes: "" }
// EXIST: { lookupString: "String", itemText: "String::class", attributes: "" }
@@ -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
@@ -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");