From 546836d5dd88791ca26e9f33d70afd701ff05cdf Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 9 Feb 2015 21:24:49 +0300 Subject: [PATCH] Fixed bug with importing some of SAM-constructors and factory functions #KT-3449 Fixed --- .../kotlin/idea/util/ShortenReferences.kt | 20 ++++++++++++++++--- .../afterSAMConstructorFromLambda.kt | 11 ++++++++++ .../beforeSAMConstructorFromLambda.kt | 10 ++++++++++ .../factoryFunctionFromLambda.after.kt | 8 ++++++++ .../factoryFunctionFromLambda.before.Main.kt | 6 ++++++ ...ryFunctionFromLambda.before.data.Sample.kt | 5 +++++ .../constructor/SAMConstructorFromLambda.kt | 9 +++++++++ .../SAMConstructorFromLambda.kt.after | 10 ++++++++++ .../QuickFixMultiFileTestGenerated.java | 6 ++++++ .../idea/quickfix/QuickFixTestGenerated.java | 6 ++++++ .../shortenRefs/ShortenRefsTestGenerated.java | 6 ++++++ 11 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 idea/testData/quickfix/autoImports/afterSAMConstructorFromLambda.kt create mode 100644 idea/testData/quickfix/autoImports/beforeSAMConstructorFromLambda.kt create mode 100644 idea/testData/quickfix/autoImports/factoryFunctionFromLambda.after.kt create mode 100644 idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.Main.kt create mode 100644 idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.data.Sample.kt create mode 100644 idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt create mode 100644 idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt.after diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt index 2c337ec5af8..f25dbbfefc2 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt @@ -58,9 +58,23 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. = DescriptorRenderer.FQ_NAMES_IN_TYPES.render(this) private fun JetReferenceExpression.targets(context: BindingContext): Collection { - return context[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it.getImportableDescriptor()) } - ?: context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this]?.map { it.getImportableDescriptor() }?.toSet() - ?: listOf() + val targets = context[BindingContext.REFERENCE_TARGET, this]?.let { listOf(it) } + ?: context[BindingContext.AMBIGUOUS_REFERENCE_TARGET, this] + ?: listOf() + return targets.map { descriptorToImport(it) }.toSet() + } + + private fun descriptorToImport(target: DeclarationDescriptor): DeclarationDescriptor { + val descriptor = target.getImportableDescriptor() + // if there is a class with the same fq-name then prefer to consider it as target (otherwise we won't insert import) + if (descriptor is CallableDescriptor) { + val container = descriptor.getContainingDeclaration() + if (container is PackageFragmentDescriptor) { + val classifier = container.getMemberScope().getClassifier(descriptor.getName()) + if (classifier != null) return classifier + } + } + return descriptor } private fun mayImport(descriptor: DeclarationDescriptor, file: JetFile): Boolean { diff --git a/idea/testData/quickfix/autoImports/afterSAMConstructorFromLambda.kt b/idea/testData/quickfix/autoImports/afterSAMConstructorFromLambda.kt new file mode 100644 index 00000000000..67da9517835 --- /dev/null +++ b/idea/testData/quickfix/autoImports/afterSAMConstructorFromLambda.kt @@ -0,0 +1,11 @@ +// "Import" "true" +import java.util.Collections +import java.util.ArrayList +import java.util.Comparator + +fun foo() { + Collections.sort( + ArrayList(), + Comparator {(x: Int, y: Int) -> x - y } + ) +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/beforeSAMConstructorFromLambda.kt b/idea/testData/quickfix/autoImports/beforeSAMConstructorFromLambda.kt new file mode 100644 index 00000000000..5beb36e5e86 --- /dev/null +++ b/idea/testData/quickfix/autoImports/beforeSAMConstructorFromLambda.kt @@ -0,0 +1,10 @@ +// "Import" "true" +import java.util.Collections +import java.util.ArrayList + +fun foo() { + Collections.sort( + ArrayList(), + Comparator {(x: Int, y: Int) -> x - y } + ) +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.after.kt b/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.after.kt new file mode 100644 index 00000000000..49a6b1a0903 --- /dev/null +++ b/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.after.kt @@ -0,0 +1,8 @@ +// "Import" "true" +// ERROR: Unresolved reference: XXX + +import ppp.XXX + +fun f() { + XXX { 1 } +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.Main.kt b/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.Main.kt new file mode 100644 index 00000000000..dfe5758479c --- /dev/null +++ b/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.Main.kt @@ -0,0 +1,6 @@ +// "Import" "true" +// ERROR: Unresolved reference: XXX + +fun f() { + XXX { 1 } +} \ No newline at end of file diff --git a/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.data.Sample.kt b/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.data.Sample.kt new file mode 100644 index 00000000000..2c308bbbf60 --- /dev/null +++ b/idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.data.Sample.kt @@ -0,0 +1,5 @@ +package ppp + +class XXX + +fun XXX(p: () -> Int){} diff --git a/idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt b/idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt new file mode 100644 index 00000000000..defb287034d --- /dev/null +++ b/idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt @@ -0,0 +1,9 @@ +import java.util.Collections +import java.util.ArrayList + +fun foo() { + Collections.sort( + ArrayList(), + java.util.Comparator {(x: Int, y: Int) -> x - y } + ) +} \ No newline at end of file diff --git a/idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt.after b/idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt.after new file mode 100644 index 00000000000..6d0aede9ecb --- /dev/null +++ b/idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt.after @@ -0,0 +1,10 @@ +import java.util.Collections +import java.util.ArrayList +import java.util.Comparator + +fun foo() { + Collections.sort( + ArrayList(), + Comparator {(x: Int, y: Int) -> x - y } + ) +} \ 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 93e7e8d6658..f3fb2a13482 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -92,6 +92,12 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes doTestWithExtraFile(fileName); } + @TestMetadata("factoryFunctionFromLambda.before.Main.kt") + public void testFactoryFunctionFromLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/factoryFunctionFromLambda.before.Main.kt"); + doTestWithExtraFile(fileName); + } + @TestMetadata("falsePostfixOperator.before.Main.kt") public void testFalsePostfixOperator() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/falsePostfixOperator.before.Main.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 6e1a8ffb234..4eab89693a8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -412,6 +412,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("beforeSAMConstructorFromLambda.kt") + public void testSAMConstructorFromLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/beforeSAMConstructorFromLambda.kt"); + doTest(fileName); + } + @TestMetadata("beforeUnresolvedReferenceInCall.kt") public void testUnresolvedReferenceInCall() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/autoImports/beforeUnresolvedReferenceInCall.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java index a1ba3272b1d..d14116b2b55 100644 --- a/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java @@ -147,6 +147,12 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest { doTest(fileName); } + @TestMetadata("SAMConstructorFromLambda.kt") + public void testSAMConstructorFromLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/shortenRefs/constructor/SAMConstructorFromLambda.kt"); + doTest(fileName); + } + @TestMetadata("WorksForClassNameRange.kt") public void testWorksForClassNameRange() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/shortenRefs/constructor/WorksForClassNameRange.kt");