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) {
|
if (receiver == null) {
|
||||||
for (expectedType in expectedTypes) {
|
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
|
//TODO: there can be duplicates here for multiple expected types
|
||||||
staticMembers(expressionWithType, expectedType, resolveSession, bindingContext).toCollection(additionalElements)
|
staticMembers(expressionWithType, expectedType, resolveSession, bindingContext).toCollection(additionalElements)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
additionalElements.addTypeInstantiationItems(expectedTypes, resolveSession, bindingContext)
|
||||||
|
|
||||||
thisItems(expressionWithType, expectedTypes, bindingContext).toCollection(additionalElements)
|
thisItems(expressionWithType, expectedTypes, bindingContext).toCollection(additionalElements)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,18 +203,24 @@ private fun calcItemsToSkip(expression: JetExpression, resolveSession: ResolveSe
|
|||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun typeInstantiationItems(expectedType: ExpectedTypeInfo, resolveSession: ResolveSessionForBodies, bindingContext: BindingContext): Iterable<LookupElement> {
|
private fun MutableCollection<LookupElement>.addTypeInstantiationItems(expectedTypes: Collection<ExpectedTypeInfo>, resolveSession: ResolveSessionForBodies, bindingContext: BindingContext) {
|
||||||
val typeConstructor: TypeConstructor = expectedType.`type`.getConstructor()
|
val expectedTypesGrouped: Map<JetType, List<ExpectedTypeInfo>> = expectedTypes.groupBy { TypeUtils.makeNotNullable(it.`type`) }
|
||||||
val classifier: ClassifierDescriptor? = typeConstructor.getDeclarationDescriptor()
|
for ((jetType, types) in expectedTypesGrouped) {
|
||||||
if (!(classifier is ClassDescriptor)) return listOf()
|
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
|
//TODO: check for constructor's visibility
|
||||||
|
|
||||||
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, classifier)
|
val lookupElement = DescriptorLookupConverter.createLookupElement(resolveSession, bindingContext, classifier)
|
||||||
|
|
||||||
var lookupString = lookupElement.getLookupString()
|
var lookupString = lookupElement.getLookupString()
|
||||||
|
|
||||||
val typeArgs = expectedType.`type`.getArguments()
|
val typeArgs = jetType.getArguments()
|
||||||
var itemText = lookupString + DescriptorRenderer.TEXT.renderTypeArguments(typeArgs)
|
var itemText = lookupString + DescriptorRenderer.TEXT.renderTypeArguments(typeArgs)
|
||||||
|
|
||||||
val insertHandler: InsertHandler<LookupElement>
|
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) {
|
if (suppressAutoInsertion) {
|
||||||
return listOf(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElementWithTail))
|
add(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(lookupElementWithTail))
|
||||||
}
|
}
|
||||||
else{
|
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;
|
package org.jetbrains.jet.completion.handlers;
|
||||||
|
|
||||||
import org.jetbrains.jet.JetTestUtils;
|
import junit.framework.Assert;
|
||||||
import org.jetbrains.jet.test.TestMetadata;
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.regex.Pattern;
|
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 */
|
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@@ -180,6 +186,16 @@ public class SmartCompletionHandlerTestGenerated extends AbstractSmartCompletion
|
|||||||
doTest("idea/testData/completion/handlers/smart/JavaStaticMethodInsertsImport.kt");
|
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")
|
@TestMetadata("TabReplaceComma1.kt")
|
||||||
public void testTabReplaceComma1() throws Exception {
|
public void testTabReplaceComma1() throws Exception {
|
||||||
doTest("idea/testData/completion/handlers/smart/TabReplaceComma1.kt");
|
doTest("idea/testData/completion/handlers/smart/TabReplaceComma1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user