From 07311234db233ab828dd95ae3b6db73ce69f5292 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 4 Aug 2015 22:34:10 +0300 Subject: [PATCH] "this" with matching type are preferred in ordinary completion --- .../idea/completion/BasicCompletionSession.kt | 3 +-- .../kotlin/idea/completion/Weighers.kt | 21 ++++++++++++++----- .../basic/expectedInfo/PreferMatchingThis.kt | 13 ++++++++++++ .../BasicCompletionWeigherTestGenerated.java | 6 ++++++ 4 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 idea/idea-completion/testData/weighers/basic/expectedInfo/PreferMatchingThis.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt index 632cccdf267..33e3cc1a1f7 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/BasicCompletionSession.kt @@ -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()) { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt index c286648db8b..8f2a23b7e85 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/Weighers.kt @@ -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 } } diff --git a/idea/idea-completion/testData/weighers/basic/expectedInfo/PreferMatchingThis.kt b/idea/idea-completion/testData/weighers/basic/expectedInfo/PreferMatchingThis.kt new file mode 100644 index 00000000000..3cf28dcbe59 --- /dev/null +++ b/idea/idea-completion/testData/weighers/basic/expectedInfo/PreferMatchingThis.kt @@ -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@ + } + } +} + +// ORDER: this@Inner +// ORDER: this@Y +// ORDER: this@foo diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java index f94047b4992..4b63e0535aa 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java @@ -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")