diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt index 16a0f36ab0e..1f135a237dd 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/codeInsight/ReferenceVariantsHelper.kt @@ -18,11 +18,11 @@ package org.jetbrains.kotlin.idea.codeInsight import com.intellij.openapi.project.Project -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.idea.util.* +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.util.CallType +import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter +import org.jetbrains.kotlin.idea.util.getImplicitReceiversWithInstance +import org.jetbrains.kotlin.idea.util.substituteExtensionIfCallable import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* @@ -37,9 +37,11 @@ import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.synthetic.SyntheticExtensionPropertyDescriptor import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.checker.JetTypeChecker +import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* public class ReferenceVariantsHelper( @@ -61,11 +63,28 @@ public class ReferenceVariantsHelper( expression: JetSimpleNameExpression, kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, + filterOutJavaGettersAndSetters: Boolean = false, useRuntimeReceiverType: Boolean = false ): Collection { - val variants = getReferenceVariantsNoVisibilityFilter(expression, kindFilter, useRuntimeReceiverType, nameFilter) + var variants: Collection + = getReferenceVariantsNoVisibilityFilter(expression, kindFilter, useRuntimeReceiverType, nameFilter) .filter(visibilityFilter) - return ShadowedDeclarationsFilter(context, moduleDescriptor, project).filter(variants, expression) + + variants = ShadowedDeclarationsFilter(context, moduleDescriptor, project).filter(variants, expression) + + if (filterOutJavaGettersAndSetters) { + val accessorMethodsToRemove = HashSet() + for (variant in variants) { + if (variant is SyntheticExtensionPropertyDescriptor) { + accessorMethodsToRemove.add(variant.getMethod) + accessorMethodsToRemove.addIfNotNull(variant.setMethod) + } + } + + variants = variants.filter { it !in accessorMethodsToRemove } + } + + return variants } private fun getReferenceVariantsNoVisibilityFilter( 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 1e7377c0bc6..c4b6fe976a6 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 @@ -61,11 +61,15 @@ import kotlin.properties.Delegates class CompletionSessionConfiguration( val completeNonImportedDeclarations: Boolean, - val completeNonAccessibleDeclarations: Boolean) + val completeNonAccessibleDeclarations: Boolean, + val filterOutJavaGettersAndSetters: Boolean +) fun CompletionSessionConfiguration(parameters: CompletionParameters) = CompletionSessionConfiguration( completeNonImportedDeclarations = parameters.getInvocationCount() >= 2, - completeNonAccessibleDeclarations = parameters.getInvocationCount() >= 2) + completeNonAccessibleDeclarations = parameters.getInvocationCount() >= 2, + filterOutJavaGettersAndSetters = parameters.getInvocationCount() < 2 +) abstract class CompletionSession(protected val configuration: CompletionSessionConfiguration, protected val parameters: CompletionParameters, @@ -208,7 +212,7 @@ abstract class CompletionSession(protected val configuration: CompletionSessionC protected val referenceVariants: Collection by Delegates.lazy { if (descriptorKindFilter != null) { val expression = reference!!.expression - referenceVariantsHelper.getReferenceVariants(expression, descriptorKindFilter!!, prefixMatcher.asNameFilter()) + referenceVariantsHelper.getReferenceVariants(expression, descriptorKindFilter!!, prefixMatcher.asNameFilter(), filterOutJavaGettersAndSetters = configuration.filterOutJavaGettersAndSetters) .excludeNonInitializedVariable(expression) } else { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KotlinCompletionContributor.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KotlinCompletionContributor.kt index 443661a2189..6bbb421b308 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KotlinCompletionContributor.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/KotlinCompletionContributor.kt @@ -249,7 +249,8 @@ public class KotlinCompletionContributor : CompletionContributor() { if (!somethingAdded && parameters.getInvocationCount() < 2) { // Rerun completion if nothing was found val newConfiguration = CompletionSessionConfiguration(completeNonImportedDeclarations = true, - completeNonAccessibleDeclarations = false) + completeNonAccessibleDeclarations = false, + filterOutJavaGettersAndSetters = false) BasicCompletionSession(newConfiguration, parameters, result).complete() } } diff --git a/idea/idea-completion/testData/basic/common/extensions/DoNotHideGetterWhenExtensionCannotBeUsed.kt b/idea/idea-completion/testData/basic/common/extensions/DoNotHideGetterWhenExtensionCannotBeUsed.kt new file mode 100644 index 00000000000..bfad110447f --- /dev/null +++ b/idea/idea-completion/testData/basic/common/extensions/DoNotHideGetterWhenExtensionCannotBeUsed.kt @@ -0,0 +1,8 @@ +import java.io.File + +fun File.foo(absolutePath: String) { + +} + +// EXIST_JAVA_ONLY: getAbsolutePath +// ABSENT: { itemText: "absolutePath", tailText: " for File" } diff --git a/idea/idea-completion/testData/basic/common/extensions/ShowGetMethodWhenNothingElseMatch.kt b/idea/idea-completion/testData/basic/common/extensions/ShowGetMethodWhenNothingElseMatch.kt new file mode 100644 index 00000000000..bc619e05fd9 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/extensions/ShowGetMethodWhenNothingElseMatch.kt @@ -0,0 +1,5 @@ +fun foo(thread: Thread) { + thread.get +} + +// EXIST_JAVA_ONLY: getPriority diff --git a/idea/idea-completion/testData/basic/common/extensions/ShowGetSetOnSecondCompletion.kt b/idea/idea-completion/testData/basic/common/extensions/ShowGetSetOnSecondCompletion.kt new file mode 100644 index 00000000000..fef508589b2 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/extensions/ShowGetSetOnSecondCompletion.kt @@ -0,0 +1,8 @@ +fun foo(thread: Thread) { + thread. +} + +// INVOCATION_COUNT: 2 +// EXIST_JAVA_ONLY: { lookupString: "priority", itemText: "priority", tailText: " for Thread", typeText: "Int" } +// EXIST_JAVA_ONLY: getPriority +// EXIST_JAVA_ONLY: setPriority diff --git a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt index 568ab2a2869..b8625274b72 100644 --- a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt +++ b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt @@ -5,3 +5,4 @@ fun foo(file: File) { } // EXIST_JAVA_ONLY: { lookupString: "absolutePath", itemText: "absolutePath", tailText: " for File", typeText: "String!" } +// ABSENT: getAbsolutePath diff --git a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt index 511ecc4b5bd..6fdc9c39ef0 100644 --- a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt +++ b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions2.kt @@ -1,7 +1,7 @@ -import java.io.File - -fun File.foo() { +fun Thread.foo() { } -// EXIST_JAVA_ONLY: { lookupString: "absolutePath", itemText: "absolutePath", tailText: " for File", typeText: "String!" } +// EXIST_JAVA_ONLY: { lookupString: "priority", itemText: "priority", tailText: " for Thread", typeText: "Int" } +// ABSENT: getPriority +// ABSENT: setPriority diff --git a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensionsSafeCall.kt b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensionsSafeCall.kt index 8865bcb0403..e145299c03d 100644 --- a/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensionsSafeCall.kt +++ b/idea/idea-completion/testData/basic/common/extensions/SyntheticExtensionsSafeCall.kt @@ -5,3 +5,4 @@ fun foo(file: File?) { } // EXIST_JAVA_ONLY: { lookupString: "absolutePath", itemText: "absolutePath", tailText: " for File", typeText: "String!" } +// ABSENT: getAbsolutePath diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java index 96778ee88b5..210106ae8d0 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JSBasicCompletionTestGenerated.java @@ -1107,6 +1107,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("DoNotHideGetterWhenExtensionCannotBeUsed.kt") + public void testDoNotHideGetterWhenExtensionCannotBeUsed() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/DoNotHideGetterWhenExtensionCannotBeUsed.kt"); + doTest(fileName); + } + @TestMetadata("ExtensionInExtendedClass.kt") public void testExtensionInExtendedClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ExtensionInExtendedClass.kt"); @@ -1209,6 +1215,18 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("ShowGetMethodWhenNothingElseMatch.kt") + public void testShowGetMethodWhenNothingElseMatch() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ShowGetMethodWhenNothingElseMatch.kt"); + doTest(fileName); + } + + @TestMetadata("ShowGetSetOnSecondCompletion.kt") + public void testShowGetSetOnSecondCompletion() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ShowGetSetOnSecondCompletion.kt"); + doTest(fileName); + } + @TestMetadata("SyntheticExtensions1.kt") public void testSyntheticExtensions1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt"); diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java index ae651dd71f6..d149189acfa 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/JvmBasicCompletionTestGenerated.java @@ -1107,6 +1107,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } + @TestMetadata("DoNotHideGetterWhenExtensionCannotBeUsed.kt") + public void testDoNotHideGetterWhenExtensionCannotBeUsed() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/DoNotHideGetterWhenExtensionCannotBeUsed.kt"); + doTest(fileName); + } + @TestMetadata("ExtensionInExtendedClass.kt") public void testExtensionInExtendedClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ExtensionInExtendedClass.kt"); @@ -1209,6 +1215,18 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } + @TestMetadata("ShowGetMethodWhenNothingElseMatch.kt") + public void testShowGetMethodWhenNothingElseMatch() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ShowGetMethodWhenNothingElseMatch.kt"); + doTest(fileName); + } + + @TestMetadata("ShowGetSetOnSecondCompletion.kt") + public void testShowGetSetOnSecondCompletion() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ShowGetSetOnSecondCompletion.kt"); + doTest(fileName); + } + @TestMetadata("SyntheticExtensions1.kt") public void testSyntheticExtensions1() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/SyntheticExtensions1.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java index bb395ba8842..61df88e3725 100644 --- a/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/parameterInfo/JetFunctionParameterInfoHandler.java @@ -414,7 +414,7 @@ public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWith }; Collection variants = new ReferenceVariantsHelper(bindingContext, moduleDescriptor, file.getProject(), visibilityFilter).getReferenceVariants( callNameExpression, new DescriptorKindFilter(DescriptorKindFilter.FUNCTIONS_MASK | DescriptorKindFilter.CLASSIFIERS_MASK, - Collections.emptyList()), nameFilter, false); + Collections.emptyList()), nameFilter, false, false); Collection> itemsToShow = new ArrayList>(); for (DeclarationDescriptor variant : variants) {