From 2ec81f44bf5286817b7f21982258fb87c363cb7a Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Sat, 14 May 2016 01:22:41 +0300 Subject: [PATCH] Fixed extension properties not completed after "get" --- .../idea/completion/CompletionSession.kt | 14 +++++------ .../kotlin/idea/completion/CompletionUtils.kt | 24 +++++++++---------- .../ExtensionsAndGetPrefix.dependency.kt | 4 ++++ .../ExtensionsAndGetPrefix.kt | 9 +++++++ ...tiFileJvmBasicCompletionTestGenerated.java | 6 +++++ 5 files changed, 36 insertions(+), 21 deletions(-) create mode 100644 idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.dependency.kt create mode 100644 idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt index c1ab3f2e2e2..778a8ccb50c 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionSession.kt @@ -118,17 +118,16 @@ abstract class CompletionSession( protected val prefixMatcher = CamelHumpMatcher(prefix) - protected val descriptorNameFilter: (Name) -> Boolean = run { - val nameFilter = prefixMatcher.asNameFilter() + private val descriptorStringNameFilter: (String) -> Boolean = run { + val nameFilter = prefixMatcher.asStringNameFilter() val getOrSetPrefix = listOf("get", "set", "ge", "se", "g", "s").firstOrNull { prefix.startsWith(it) } if (getOrSetPrefix != null) - nameFilter or prefixMatcher.cloneWithPrefix(prefix.removePrefix(getOrSetPrefix).decapitalizeSmart()).asNameFilter() + prefixMatcher.cloneWithPrefix(prefix.removePrefix(getOrSetPrefix).decapitalizeSmart()).asStringNameFilter() or nameFilter else nameFilter } - private infix fun ((Name) -> Boolean).or(otherFilter: (Name) -> Boolean): (Name) -> Boolean - = { this(it) || otherFilter(it) } + protected val descriptorNameFilter: (Name) -> Boolean = descriptorStringNameFilter.toNameFilter() protected val isVisibleFilter: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it, completeNonAccessible = configuration.completeNonAccessibleDeclarations) } protected val isVisibleFilterCheckAlways: (DeclarationDescriptor) -> Boolean = { isVisibleDescriptor(it, completeNonAccessible = false) } @@ -318,12 +317,11 @@ abstract class CompletionSession( var notImportedExtensions: Collection = emptyList() if (callTypeAndReceiver.shouldCompleteCallableExtensions()) { - val nameFilter: (String) -> Boolean = { prefixMatcher.prefixMatches(it) } val indicesHelper = indicesHelper(true) val extensions = if (runtimeReceiver != null) - indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, listOf(runtimeReceiver.type), nameFilter) + indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, listOf(runtimeReceiver.type), descriptorStringNameFilter) else - indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, expression!!, bindingContext, nameFilter) + indicesHelper.getCallableTopLevelExtensions(callTypeAndReceiver, expression!!, bindingContext, descriptorStringNameFilter) val pair = extensions.partition { isImportableDescriptorImported(it) } variants += pair.first diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt index 404af89841d..c756fc6a0e2 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionUtils.kt @@ -118,21 +118,19 @@ fun rethrowWithCancelIndicator(exception: ProcessCanceledException): ProcessCanc return exception } -fun PrefixMatcher.asNameFilter() = { name: Name -> - if (name.isSpecial) { - false - } - else { - val identifier = name.identifier - if (prefix.startsWith("$")) { // we need properties from scope for backing field completion - prefixMatches("$" + identifier) - } - else { - prefixMatches(identifier) - } - } +fun PrefixMatcher.asNameFilter(): (Name) -> Boolean { + return { name -> !name.isSpecial && prefixMatches(name.identifier) } } +fun PrefixMatcher.asStringNameFilter() = { name: String -> prefixMatches(name) } + +fun ((String) -> Boolean).toNameFilter(): (Name) -> Boolean { + return { name -> !name.isSpecial && this(name.identifier) } +} + +infix fun ((T) -> Boolean).or(otherFilter: (T) -> Boolean): (T) -> Boolean + = { this(it) || otherFilter(it) } + fun LookupElementPresentation.prependTailText(text: String, grayed: Boolean) { val tails = tailFragments clearTail() diff --git a/idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.dependency.kt b/idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.dependency.kt new file mode 100644 index 00000000000..e36fadb8d5d --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.dependency.kt @@ -0,0 +1,4 @@ +package dependency + +val String.notImportedExtension: Int + get() = 0 diff --git a/idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.kt b/idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.kt new file mode 100644 index 00000000000..0c5838f243e --- /dev/null +++ b/idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/ExtensionsAndGetPrefix.kt @@ -0,0 +1,9 @@ +val String.thisFileExtension: Int + get() = 0 + +fun f() { + "".get +} + +// EXIST: thisFileExtension +// EXIST: notImportedExtension diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java index 8e6bc5d3c1a..4977aa62e06 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/MultiFileJvmBasicCompletionTestGenerated.java @@ -119,6 +119,12 @@ public class MultiFileJvmBasicCompletionTestGenerated extends AbstractMultiFileJ doTest(fileName); } + @TestMetadata("ExtensionsAndGetPrefix") + public void testExtensionsAndGetPrefix() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/ExtensionsAndGetPrefix/"); + doTest(fileName); + } + @TestMetadata("ExtensionsForSmartCast") public void testExtensionsForSmartCast() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/multifile/ExtensionsForSmartCast/");