"this" with matching type are preferred in ordinary completion

This commit is contained in:
Valentin Kipyatkov
2015-08-04 22:34:10 +03:00
parent 2b61f4c552
commit 07311234db
4 changed files with 36 additions and 7 deletions
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.utils.addToStdlib.check
class BasicCompletionSession(configuration: CompletionSessionConfiguration,
parameters: CompletionParameters,
@@ -284,7 +283,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
sorter = sorter.weighBefore(DeprecatedWeigher.toString(), ParameterNameAndTypeCompletion.Weigher)
}
if (expression != null && completionKind == CompletionKind.ALL) {
if (expression != null) {
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor).calculate(expression)
if (expectedInfos != null && expectedInfos.isNotEmpty()) {
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.completion.smart.SmartCompletionItemPriority
import org.jetbrains.kotlin.idea.completion.smart.fuzzyTypesForSmartCompletion
import org.jetbrains.kotlin.idea.core.SmartCastCalculator
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
import org.jetbrains.kotlin.idea.util.FuzzyType
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.makeNotNullable
import org.jetbrains.kotlin.idea.util.nullability
@@ -200,12 +201,22 @@ class ExpectedInfoMatchWeigher(
}
override fun weigh(element: LookupElement): Weight {
// TODO: keywords with type, this etc
val descriptor = (element.`object` as? DeclarationLookupObject)?.descriptor ?: return Weight.doesNotMatch
val types = descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator)
// TODO: keywords with type
val o = element.`object`
val fuzzyTypes = when (o) {
is DeclarationLookupObject -> {
val descriptor = o.descriptor ?: return Weight.doesNotMatch
descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator)
}
is ThisItemLookupObject -> smartCastCalculator.types(o.receiverParameter).map { FuzzyType(it, emptyList()) }
else -> return Weight.doesNotMatch
}
return when {
types.any { type -> expectedInfos.any { it.matchingSubstitutor(type) != null } } -> Weight.matches
types.any { type -> type.nullability() == TypeNullability.NULLABLE && expectedInfos.any { it.matchingSubstitutor(type.makeNotNullable()) != null } } -> Weight.matchesIfNotNull
fuzzyTypes.any { type -> expectedInfos.any { it.matchingSubstitutor(type) != null } } -> Weight.matches
fuzzyTypes.any { type -> type.nullability() == TypeNullability.NULLABLE && expectedInfos.any { it.matchingSubstitutor(type.makeNotNullable()) != null } } -> Weight.matchesIfNotNull
else -> Weight.doesNotMatch
}
}
@@ -0,0 +1,13 @@
interface X
open class Y : X {
open inner class Inner {
fun Any.foo(): X {
if (this@Inner is X) return this@<caret>
}
}
}
// ORDER: this@Inner
// ORDER: this@Y
// ORDER: this@foo
@@ -156,6 +156,12 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/ExpectedType.kt");
doTest(fileName);
}
@TestMetadata("PreferMatchingThis.kt")
public void testPreferMatchingThis() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/PreferMatchingThis.kt");
doTest(fileName);
}
}
@TestMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType")