Ordering of static members in completion

This commit is contained in:
Valentin Kipyatkov
2015-11-03 12:29:25 +03:00
parent 3bd508ca84
commit 7198b897ab
13 changed files with 77 additions and 9 deletions
@@ -253,7 +253,10 @@ abstract class CompletionSession(
protected open fun createSorter(): CompletionSorter { protected open fun createSorter(): CompletionSorter {
var sorter = CompletionSorter.defaultSorter(parameters, prefixMatcher)!! var sorter = CompletionSorter.defaultSorter(parameters, prefixMatcher)!!
sorter = sorter.weighBefore("stats", DeprecatedWeigher, PriorityWeigher, NotImportedWeigher(importableFqNameClassifier), KindWeigher, CallableWeigher) sorter = sorter.weighBefore("stats", DeprecatedWeigher, PriorityWeigher,
NotImportedWeigher(importableFqNameClassifier),
NotImportedStaticMemberWeigher(importableFqNameClassifier),
KindWeigher, CallableWeigher)
sorter = sorter.weighAfter("stats", VariableOrFunctionWeigher, ImportedWeigher(importableFqNameClassifier)) sorter = sorter.weighAfter("stats", VariableOrFunctionWeigher, ImportedWeigher(importableFqNameClassifier))
@@ -452,6 +455,6 @@ abstract class CompletionSession(
protected fun isImportableDescriptorImported(descriptor: DeclarationDescriptor): Boolean { protected fun isImportableDescriptorImported(descriptor: DeclarationDescriptor): Boolean {
val classification = importableFqNameClassifier.classify(descriptor.importableFqName!!, false) val classification = importableFqNameClassifier.classify(descriptor.importableFqName!!, false)
return classification != ImportableFqNameClassifier.Classification.notImported return classification != ImportableFqNameClassifier.Classification.notImported
&& classification != ImportableFqNameClassifier.Classification.hasImportFromSamePackage && classification != ImportableFqNameClassifier.Classification.siblingImported
} }
} }
@@ -68,7 +68,6 @@ class StaticMembersCompletion(
//TODO: filter out those that are accessible from SmartCompletion.additionalItems //TODO: filter out those that are accessible from SmartCompletion.additionalItems
//TODO: what about enum members? //TODO: what about enum members?
//TODO: better presentation for lookup elements from imports too //TODO: better presentation for lookup elements from imports too
//TODO: better sorting
//TODO: from the same file //TODO: from the same file
fun completeFromIndices(indicesHelper: KotlinIndicesHelper) { fun completeFromIndices(indicesHelper: KotlinIndicesHelper) {
val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions val descriptorKindFilter = DescriptorKindFilter.CALLABLES exclude DescriptorKindExclude.Extensions
@@ -42,7 +42,7 @@ object PriorityWeigher : LookupElementWeigher("kotlin.priority") {
class NotImportedWeigher(private val classifier: ImportableFqNameClassifier) : LookupElementWeigher("kotlin.notImported") { class NotImportedWeigher(private val classifier: ImportableFqNameClassifier) : LookupElementWeigher("kotlin.notImported") {
private enum class Weight { private enum class Weight {
default, default,
hasImportFromSamePackage, siblingImported,
notImported, notImported,
notToBeUsedInKotlin notToBeUsedInKotlin
} }
@@ -52,7 +52,7 @@ class NotImportedWeigher(private val classifier: ImportableFqNameClassifier) : L
val o = element.`object` as? DeclarationLookupObject val o = element.`object` as? DeclarationLookupObject
val fqName = o?.importableFqName ?: return Weight.default val fqName = o?.importableFqName ?: return Weight.default
return when (classifier.classify(fqName, o is PackageLookupObject)) { return when (classifier.classify(fqName, o is PackageLookupObject)) {
ImportableFqNameClassifier.Classification.hasImportFromSamePackage -> Weight.hasImportFromSamePackage ImportableFqNameClassifier.Classification.siblingImported -> Weight.siblingImported
ImportableFqNameClassifier.Classification.notImported -> Weight.notImported ImportableFqNameClassifier.Classification.notImported -> Weight.notImported
ImportableFqNameClassifier.Classification.notToBeUsedInKotlin -> Weight.notToBeUsedInKotlin ImportableFqNameClassifier.Classification.notToBeUsedInKotlin -> Weight.notToBeUsedInKotlin
else -> Weight.default else -> Weight.default
@@ -60,6 +60,14 @@ class NotImportedWeigher(private val classifier: ImportableFqNameClassifier) : L
} }
} }
class NotImportedStaticMemberWeigher(private val classifier: ImportableFqNameClassifier) : LookupElementWeigher("kotlin.notImportedMember") {
override fun weigh(element: LookupElement): Comparable<*>? {
if (element.getUserData(ITEM_PRIORITY_KEY) != ItemPriority.STATIC_MEMBER) return null
val fqName = (element.`object` as DeclarationLookupObject).importableFqName!!
return classifier.classify(fqName.parent(), false)
}
}
class ImportedWeigher(private val classifier: ImportableFqNameClassifier) : LookupElementWeigher("kotlin.imported") { class ImportedWeigher(private val classifier: ImportableFqNameClassifier) : LookupElementWeigher("kotlin.imported") {
private enum class Weight { private enum class Weight {
currentPackage, currentPackage,
@@ -0,0 +1,5 @@
package p1
object O1 {
fun xxx_fun1FromP1O1(){}
}
@@ -0,0 +1,8 @@
package p2
object O1 {
}
object O2 {
fun xxx_fun1FromP2O2(){}
}
@@ -0,0 +1,5 @@
package p3
object O1 {
fun xxx_fun1FromP3O1(){}
}
@@ -0,0 +1,5 @@
package p4
object O1 {
fun xxx_fun1FromP4O1(){}
}
@@ -0,0 +1,6 @@
package p5
object O1 {
fun xxx_fun1FromP5O1(){}
fun xxx_fun2FromP5O1(){}
}
@@ -0,0 +1,5 @@
package p6
object O1 {
fun xxx_fun1FromP6O1(){}
}
@@ -0,0 +1,19 @@
package p6
import p5.O1.xxx_fun2FromP5O1
import p4.O1
import p3.*
import p2.O1
fun foo() {
xxx_<caret>
}
// INVOCATION_COUNT: 2
// ORDER: xxx_fun2FromP5O1
// ORDER: xxx_fun1FromP5O1
// ORDER: xxx_fun1FromP6O1
// ORDER: xxx_fun1FromP4O1
// ORDER: xxx_fun1FromP3O1
// ORDER: xxx_fun1FromP2O2
// ORDER: xxx_fun1FromP1O1
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.util.configureWithExtraFile import org.jetbrains.kotlin.test.util.configureWithExtraFile
import org.junit.Assert import org.junit.Assert
import java.io.File import java.io.File
@@ -34,7 +33,7 @@ public abstract class AbstractCompletionWeigherTest(val completionType: Completi
assert(path.startsWith(pathPrefix)) assert(path.startsWith(pathPrefix))
val relativePath = path.removePrefix(pathPrefix) val relativePath = path.removePrefix(pathPrefix)
myFixture.configureWithExtraFile(relativePath, ".Data", ".Data1", ".Data2", ".Data3", relativePaths = true) myFixture.configureWithExtraFile(relativePath, ".Data", ".Data1", ".Data2", ".Data3", ".Data4", ".Data5", ".Data6", relativePaths = true)
val text = myFixture.getEditor().getDocument().getText() val text = myFixture.getEditor().getDocument().getText()
@@ -155,6 +155,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
doTest(fileName); doTest(fileName);
} }
@TestMetadata("StaticMembers.kt")
public void testStaticMembers() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/StaticMembers.kt");
doTest(fileName);
}
@TestMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo") @TestMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -49,7 +49,7 @@ class ImportableFqNameClassifier(private val file: KtFile) {
defaultImport, defaultImport,
preciseImport, preciseImport,
allUnderImport, allUnderImport,
hasImportFromSamePackage, siblingImported,
notImported, notImported,
notToBeUsedInKotlin notToBeUsedInKotlin
} }
@@ -77,7 +77,7 @@ class ImportableFqNameClassifier(private val file: KtFile) {
isImportedWithAllUnderImport(fqName) -> Classification.allUnderImport isImportedWithAllUnderImport(fqName) -> Classification.allUnderImport
hasPreciseImportFromPackage(fqName.parent()) -> Classification.hasImportFromSamePackage hasPreciseImportFromPackage(fqName.parent()) -> Classification.siblingImported
else -> Classification.notImported else -> Classification.notImported
} }