Smart completion: no more duplicates among type instantiation items
This commit is contained in:
@@ -70,13 +70,12 @@ fun buildSmartCompletionData(expression: JetSimpleNameExpression, resolveSession
|
||||
|
||||
if (receiver == null) {
|
||||
for (expectedType in expectedTypes) {
|
||||
//TODO: there can be duplicates here for multiple expected types
|
||||
typeInstantiationItems(expectedType, resolveSession, bindingContext).toCollection(additionalElements)
|
||||
|
||||
//TODO: there can be duplicates here for multiple expected types
|
||||
staticMembers(expressionWithType, expectedType, resolveSession, bindingContext).toCollection(additionalElements)
|
||||
}
|
||||
|
||||
additionalElements.addTypeInstantiationItems(expectedTypes, resolveSession, bindingContext)
|
||||
|
||||
thisItems(expressionWithType, expectedTypes, bindingContext).toCollection(additionalElements)
|
||||
}
|
||||
|
||||
@@ -204,18 +203,24 @@ private fun calcItemsToSkip(expression: JetExpression, resolveSession: ResolveSe
|
||||
return listOf()
|
||||
}
|
||||
|
||||
private fun typeInstantiationItems(expectedType: ExpectedTypeInfo, resolveSession: ResolveSessionForBodies, bindingContext: BindingContext): Iterable<LookupElement> {
|
||||
val typeConstructor: TypeConstructor = expectedType.`type`.getConstructor()
|
||||
val classifier: ClassifierDescriptor? = typeConstructor.getDeclarationDescriptor()
|
||||
if (!(classifier is ClassDescriptor)) return listOf()
|
||||
private fun MutableCollection<LookupElement>.addTypeInstantiationItems(expectedTypes: Collection<ExpectedTypeInfo>, resolveSession: ResolveSessionForBodies, bindingContext: BindingContext) {
|
||||
val expectedTypesGrouped: Map<JetType, List<ExpectedTypeInfo>> = expectedTypes.groupBy { TypeUtils.makeNotNullable(it.`type`) }
|
||||
for ((jetType, types) in expectedTypesGrouped) {
|
||||
val tail = mergeTails(types.map { it.tail })
|
||||
addTypeInstantiationItems(jetType, tail, resolveSession, bindingContext)
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableCollection<LookupElement>.addTypeInstantiationItems(jetType: JetType, tail: Tail?, resolveSession: ResolveSessionForBodies, bindingContext: BindingContext) {
|
||||
val classifier = jetType.getConstructor().getDeclarationDescriptor()
|
||||
if (!(classifier is ClassDescriptor)) return
|
||||
//TODO: check for constructor's visibility
|
||||
|
||||
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, classifier)
|
||||
|
||||
var lookupString = lookupElement.getLookupString()
|
||||
|
||||
val typeArgs = expectedType.`type`.getArguments()
|
||||
val typeArgs = jetType.getArguments()
|
||||
var itemText = lookupString + DescriptorRenderer.TEXT.renderTypeArguments(typeArgs)
|
||||
|
||||
val insertHandler: InsertHandler<LookupElement>
|
||||
@@ -286,13 +291,13 @@ private fun typeInstantiationItems(expectedType: ExpectedTypeInfo, resolveSessio
|
||||
}
|
||||
}
|
||||
|
||||
val lookupElementWithTail = decorateLookupElement(lookupElementDecorated, expectedType.tail)
|
||||
val lookupElementWithTail = decorateLookupElement(lookupElementDecorated, tail)
|
||||
|
||||
if (suppressAutoInsertion) {
|
||||
return listOf(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElementWithTail))
|
||||
add(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElementWithTail))
|
||||
}
|
||||
else{
|
||||
return listOf(lookupElementWithTail)
|
||||
add(lookupElementWithTail)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
class C{}
|
||||
|
||||
fun foo(c: C){}
|
||||
fun foo(c: C, i: Int){}
|
||||
|
||||
fun foo() {
|
||||
foo(<caret>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class C{}
|
||||
|
||||
fun foo(c: C){}
|
||||
fun foo(c: C, i: Int){}
|
||||
|
||||
fun foo() {
|
||||
foo(C()<caret>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class C{}
|
||||
|
||||
fun foo(c: C){}
|
||||
fun foo(c: C?, i: Int){}
|
||||
|
||||
fun foo() {
|
||||
foo(<caret>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class C{}
|
||||
|
||||
fun foo(c: C){}
|
||||
fun foo(c: C?, i: Int){}
|
||||
|
||||
fun foo() {
|
||||
foo(C()<caret>
|
||||
}
|
||||
+18
-2
@@ -16,11 +16,17 @@
|
||||
|
||||
package org.jetbrains.jet.completion.handlers;
|
||||
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jetbrains.jet.JetTestUtils;
|
||||
import org.jetbrains.jet.test.InnerTestClasses;
|
||||
import org.jetbrains.jet.test.TestMetadata;
|
||||
|
||||
import org.jetbrains.jet.completion.handlers.AbstractSmartCompletionHandlerTest;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@@ -180,6 +186,16 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
|
||||
doTest("idea/testData/completion/handlers/smart/JavaStaticMethodInsertsImport.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MergeTail1.kt")
|
||||
public void testMergeTail1() throws Exception {
|
||||
doTest("idea/testData/completion/handlers/smart/MergeTail1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MergeTail2.kt")
|
||||
public void testMergeTail2() throws Exception {
|
||||
doTest("idea/testData/completion/handlers/smart/MergeTail2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("TabReplaceComma1.kt")
|
||||
public void testTabReplaceComma1() throws Exception {
|
||||
doTest("idea/testData/completion/handlers/smart/TabReplaceComma1.kt");
|
||||
|
||||
Reference in New Issue
Block a user