Completion after "this@" includes immediate this too

#KT-6836 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-03-04 15:34:47 +03:00
parent ffff6226b0
commit 2ef80d1b34
7 changed files with 26 additions and 10 deletions
@@ -294,7 +294,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
// if "this" is parsed correctly in the current context - insert it and all this@xxx items
"this" -> {
if (expression != null) {
collector.addElements(thisExpressionItems(bindingContext!!, expression).map { it.factory() })
collector.addElements(thisExpressionItems(bindingContext!!, expression, prefix).map { it.factory() })
}
}
@@ -212,22 +212,27 @@ fun shouldCompleteThisItems(prefixMatcher: PrefixMatcher): Boolean {
data class ThisItemInfo(val factory: () -> LookupElement, val type: FuzzyType)
fun thisExpressionItems(bindingContext: BindingContext, position: JetExpression): Collection<ThisItemInfo> {
fun thisExpressionItems(bindingContext: BindingContext, position: JetExpression, prefix: String): Collection<ThisItemInfo> {
val scope = bindingContext[BindingContext.RESOLUTION_SCOPE, position] ?: return listOf()
val result = ArrayList<ThisItemInfo>()
for ((i, receiver) in scope.getImplicitReceiversWithInstance().withIndex()) {
val thisType = receiver.getType()
val fuzzyType = FuzzyType(thisType, listOf())
val label = if (i == 0) null else (thisQualifierName(receiver) ?: continue)
fun createLookupElement(): LookupElement {
fun createLookupElement(label: String?): LookupElement {
var element = createKeywordWithLabelElement("this", label)
element = element.withTypeText(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(thisType))
return element
}
result.add(ThisItemInfo({ createLookupElement() }, fuzzyType))
if (i == 0) {
result.add(ThisItemInfo({ createLookupElement(null) }, fuzzyType))
if (!prefix.startsWith("this@")) continue // if prefix does not start with "this@" do not include immediate this in the form with label
}
val label = thisQualifierName(receiver) ?: continue
result.add(ThisItemInfo({ createLookupElement(label) }, fuzzyType))
}
return result
}
@@ -185,7 +185,7 @@ class SmartCompletion(
private fun MutableCollection<LookupElement>.addThisItems(place: JetExpression, expectedInfos: Collection<ExpectedInfo>) {
if (shouldCompleteThisItems(prefixMatcher)) {
val items = thisExpressionItems(bindingContext, place)
val items = thisExpressionItems(bindingContext, place, prefixMatcher.getPrefix())
for ((factory, type) in items) {
val classifier = { (expectedInfo: ExpectedInfo) -> type.classifyExpectedInfo(expectedInfo) }
addLookupElements(null, expectedInfos, classifier) {
@@ -7,7 +7,7 @@ class Outer {
}
// ABSENT: this
// ABSENT: "this@foo"
// EXIST: { lookupString: "this@foo", itemText: "this", tailText: "@foo", typeText: "String", attributes: "bold" }
// EXIST: { lookupString: "this@Inner", itemText: "this", tailText: "@Inner", typeText: "Outer.Inner", attributes: "bold" }
// EXIST: { lookupString: "this@Outer", itemText: "this", tailText: "@Outer", typeText: "Outer", attributes: "bold" }
// NUMBER: 2
// NUMBER: 3
@@ -0,0 +1,5 @@
val String.foo: Int
get() = this@<caret>.length()
// EXIST: "this@foo"
// NUMBER: 1
@@ -7,7 +7,7 @@ class Outer {
}
// ABSENT: this
// ABSENT: "this@foo"
// EXIST: { lookupString: "this@foo", itemText: "this", tailText: "@foo", typeText: "String", attributes: "bold" }
// EXIST: { lookupString: "this@Inner", itemText: "this", tailText: "@Inner", typeText: "Outer.Inner", attributes: "bold" }
// EXIST: { lookupString: "this@Outer", itemText: "this", tailText: "@Outer", typeText: "Outer", attributes: "bold" }
// NUMBER: 2
// NUMBER: 3
@@ -330,6 +330,12 @@ public class KeywordCompletionTestGenerated extends AbstractKeywordCompletionTes
doTest(fileName);
}
@TestMetadata("QualifiedThisInAccessor.kt")
public void testQualifiedThisInAccessor() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/QualifiedThisInAccessor.kt");
doTest(fileName);
}
@TestMetadata("Return1.kt")
public void testReturn1() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/keywords/Return1.kt");