From c6cdbe7eeda9665d6ae943bcf920e7465b4bef82 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 11 Apr 2017 16:10:31 +0300 Subject: [PATCH] Fix import member quickfix to check receiver #KT-17037 fixed --- .../jetbrains/kotlin/idea/quickfix/ImportFix.kt | 16 ++++++++++++++-- ...OperatorWithTypeMismatch.before.Dependency.kt | 7 +++++++ .../plusOperatorWithTypeMismatch.before.Main.kt | 12 ++++++++++++ .../quickfix/QuickFixMultiFileTestGenerated.java | 6 ++++++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Dependency.kt create mode 100644 idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Main.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt index 7a73f5d7331..90b9666b1f2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ImportFix.kt @@ -53,6 +53,7 @@ import org.jetbrains.kotlin.idea.project.TargetPlatformDetector import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver import org.jetbrains.kotlin.idea.util.getResolutionScope +import org.jetbrains.kotlin.idea.util.receiverTypes import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.name.FqName @@ -70,6 +71,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.scopes.ExplicitImportsScope import org.jetbrains.kotlin.resolve.scopes.utils.addImportingScope import org.jetbrains.kotlin.resolve.scopes.utils.collectFunctions +import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.util.OperatorNameConventions import java.util.* @@ -283,6 +285,7 @@ internal class ImportFix(expression: KtSimpleNameExpression) : OrdinaryImportFix private fun collectMemberCandidates( name: String, callTypeAndReceiver: CallTypeAndReceiver<*, *>, + bindingContext: BindingContext, indicesHelper: KotlinIndicesHelper ): List { @@ -295,9 +298,18 @@ internal class ImportFix(expression: KtSimpleNameExpression) : OrdinaryImportFix indicesHelper.getKotlinEnumsByName(name).filterTo(result, filterByCallType) + val resolutionFacade = element.getResolutionFacade() + val actualReceiverTypes = + callTypeAndReceiver.receiverTypes(bindingContext, element, resolutionFacade.moduleDescriptor, resolutionFacade, false).orEmpty() + val processor = { descriptor: CallableDescriptor -> if (descriptor.canBeReferencedViaImport() && filterByCallType(descriptor)) { - result.add(descriptor) + val extensionReceiverType = descriptor.extensionReceiverParameter?.type + + if ((actualReceiverTypes.isEmpty() && extensionReceiverType == null) || + (extensionReceiverType != null && actualReceiverTypes.any { it.isSubtypeOf(extensionReceiverType) })) { + result.add(descriptor) + } } } @@ -324,7 +336,7 @@ internal class ImportFix(expression: KtSimpleNameExpression) : OrdinaryImportFix bindingContext: BindingContext, indicesHelper: KotlinIndicesHelper ): List { - return super.fillCandidates(name, callTypeAndReceiver, bindingContext, indicesHelper) + collectMemberCandidates(name, callTypeAndReceiver, indicesHelper) + return super.fillCandidates(name, callTypeAndReceiver, bindingContext, indicesHelper) + collectMemberCandidates(name, callTypeAndReceiver, bindingContext, indicesHelper) } companion object MyFactory : Factory() { diff --git a/idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Dependency.kt b/idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Dependency.kt new file mode 100644 index 00000000000..cc286ef6450 --- /dev/null +++ b/idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Dependency.kt @@ -0,0 +1,7 @@ +package some + +object AAA { + operator fun plus(i: Int): Int { + return 42 + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Main.kt b/idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Main.kt new file mode 100644 index 00000000000..feeb3f42a00 --- /dev/null +++ b/idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Main.kt @@ -0,0 +1,12 @@ +// "class org.jetbrains.kotlin.idea.quickfix.ImportFix" "false" +// ERROR: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public operator fun String?.plus(other: Any?): String defined in kotlin +// ACTION: Create extension function 'JustClass.plus' +// ACTION: Create member function 'JustClass.plus' +// ACTION: Flip '+' +// ACTION: Replace overloaded operator with function call + + +class JustClass +fun some() { + val x = JustClass() + 1 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index a77f72aa7bd..85461a97f13 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -576,6 +576,12 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes doTestWithExtraFile(fileName); } + @TestMetadata("plusOperatorWithTypeMismatch.before.Main.kt") + public void testPlusOperatorWithTypeMismatch() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/plusOperatorWithTypeMismatch.before.Main.kt"); + doTestWithExtraFile(fileName); + } + @TestMetadata("postfixOperator.before.Main.kt") public void testPostfixOperator() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/postfixOperator.before.Main.kt");