"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.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.utils.addToStdlib.check
class BasicCompletionSession(configuration: CompletionSessionConfiguration, class BasicCompletionSession(configuration: CompletionSessionConfiguration,
parameters: CompletionParameters, parameters: CompletionParameters,
@@ -284,7 +283,7 @@ class BasicCompletionSession(configuration: CompletionSessionConfiguration,
sorter = sorter.weighBefore(DeprecatedWeigher.toString(), ParameterNameAndTypeCompletion.Weigher) sorter = sorter.weighBefore(DeprecatedWeigher.toString(), ParameterNameAndTypeCompletion.Weigher)
} }
if (expression != null && completionKind == CompletionKind.ALL) { if (expression != null) {
val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor).calculate(expression) val expectedInfos = ExpectedInfos(bindingContext, resolutionFacade, moduleDescriptor).calculate(expression)
if (expectedInfos != null && expectedInfos.isNotEmpty()) { 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.completion.smart.fuzzyTypesForSmartCompletion
import org.jetbrains.kotlin.idea.core.SmartCastCalculator import org.jetbrains.kotlin.idea.core.SmartCastCalculator
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject 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.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.makeNotNullable import org.jetbrains.kotlin.idea.util.makeNotNullable
import org.jetbrains.kotlin.idea.util.nullability import org.jetbrains.kotlin.idea.util.nullability
@@ -200,12 +201,22 @@ class ExpectedInfoMatchWeigher(
} }
override fun weigh(element: LookupElement): Weight { override fun weigh(element: LookupElement): Weight {
// TODO: keywords with type, this etc // TODO: keywords with type
val descriptor = (element.`object` as? DeclarationLookupObject)?.descriptor ?: return Weight.doesNotMatch val o = element.`object`
val types = descriptor.fuzzyTypesForSmartCompletion(smartCastCalculator) 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 { return when {
types.any { type -> expectedInfos.any { it.matchingSubstitutor(type) != null } } -> Weight.matches fuzzyTypes.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 -> type.nullability() == TypeNullability.NULLABLE && expectedInfos.any { it.matchingSubstitutor(type.makeNotNullable()) != null } } -> Weight.matchesIfNotNull
else -> Weight.doesNotMatch 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"); String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/expectedInfo/ExpectedType.kt");
doTest(fileName); 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") @TestMetadata("idea/idea-completion/testData/weighers/basic/parameterNameAndType")