From 4deefce603c72a7ce932c877baddb03e97174e06 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 12 Jun 2015 01:07:53 +0300 Subject: [PATCH] KT-7901 Auto import is not suggested KT-7229 Completion for extension functions with complex capture #KT-7901 Fixed #KT-7229 Fixed --- .../jetbrains/kotlin/idea/util/FuzzyType.kt | 18 +++++++++++------- .../basic/common/extensions/ComplexCapture.kt | 12 ++++++++++++ .../basic/common/extensions/ComplexCapture2.kt | 11 +++++++++++ .../test/JSBasicCompletionTestGenerated.java | 12 ++++++++++++ .../test/JvmBasicCompletionTestGenerated.java | 12 ++++++++++++ 5 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 idea/idea-completion/testData/basic/common/extensions/ComplexCapture.kt create mode 100644 idea/idea-completion/testData/basic/common/extensions/ComplexCapture2.kt diff --git a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt index a576e068d26..48f8687fbed 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt +++ b/idea/ide-common/src/org/jetbrains/kotlin/idea/util/FuzzyType.kt @@ -47,18 +47,16 @@ class FuzzyType( val type: JetType, freeParameters: Collection ) { - private val usedTypeParameters: HashSet? public val freeParameters: Set init { if (freeParameters.isNotEmpty()) { - usedTypeParameters = HashSet() + val usedTypeParameters = HashSet() usedTypeParameters.addUsedTypeParameters(type) this.freeParameters = freeParameters.filter { it in usedTypeParameters }.toSet() } else { - usedTypeParameters = null - this.freeParameters = setOf() + this.freeParameters = emptySet() } } @@ -67,7 +65,11 @@ class FuzzyType( override fun hashCode() = type.hashCode() private fun MutableSet.addUsedTypeParameters(type: JetType) { - addIfNotNull(type.getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor) + val typeParameter = type.getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor + if (typeParameter != null && add(typeParameter)) { + typeParameter.getLowerBounds().forEach { addUsedTypeParameters(it) } + typeParameter.getUpperBounds().forEach { addUsedTypeParameters(it) } + } for (argument in type.getArguments()) { addUsedTypeParameters(argument.getType()) @@ -96,7 +98,7 @@ class FuzzyType( } } - if (usedTypeParameters == null || usedTypeParameters.isEmpty()) { + if (freeParameters.isEmpty()) { return if (type.checkInheritance(otherType)) TypeSubstitutor.EMPTY else null } @@ -112,7 +114,9 @@ class FuzzyType( MatchKind.IS_SUPERTYPE -> constraintSystem.addSubtypeConstraint(otherType, type, ConstraintPositionKind.SPECIAL.position()) } - if (constraintSystem.getStatus().isSuccessful() && ConstraintsUtil.checkBoundsAreSatisfied(constraintSystem, true)) { + constraintSystem.processDeclaredBoundConstraints() + + if (!constraintSystem.getStatus().hasContradiction()) { // currently ConstraintSystem return successful status in case there are problems with nullability // that's why we have to check subtyping manually val substitutor = constraintSystem.getResultingSubstitutor() diff --git a/idea/idea-completion/testData/basic/common/extensions/ComplexCapture.kt b/idea/idea-completion/testData/basic/common/extensions/ComplexCapture.kt new file mode 100644 index 00000000000..947d1d4285f --- /dev/null +++ b/idea/idea-completion/testData/basic/common/extensions/ComplexCapture.kt @@ -0,0 +1,12 @@ +trait I + +fun > T.ext() : T = this + +class A : I + +fun main(args: Array) { + val a = A() + a. +} + +// EXIST: ext \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/common/extensions/ComplexCapture2.kt b/idea/idea-completion/testData/basic/common/extensions/ComplexCapture2.kt new file mode 100644 index 00000000000..15b8bbcfe2c --- /dev/null +++ b/idea/idea-completion/testData/basic/common/extensions/ComplexCapture2.kt @@ -0,0 +1,11 @@ +interface D + +fun > T2.ext() {} + +class C : D { + fun foo() { + this. + } +} + +// EXIST: ext \ No newline at end of file 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 b136231c311..49df4f3aa12 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 @@ -1176,6 +1176,18 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/extensions"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("ComplexCapture.kt") + public void testComplexCapture() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ComplexCapture.kt"); + doTest(fileName); + } + + @TestMetadata("ComplexCapture2.kt") + public void testComplexCapture2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ComplexCapture2.kt"); + doTest(fileName); + } + @TestMetadata("ExtensionInExtendedClass.kt") public void testExtensionInExtendedClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ExtensionInExtendedClass.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 551e6dc3be3..44794e4c831 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 @@ -1176,6 +1176,18 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/basic/common/extensions"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("ComplexCapture.kt") + public void testComplexCapture() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ComplexCapture.kt"); + doTest(fileName); + } + + @TestMetadata("ComplexCapture2.kt") + public void testComplexCapture2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ComplexCapture2.kt"); + doTest(fileName); + } + @TestMetadata("ExtensionInExtendedClass.kt") public void testExtensionInExtendedClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/extensions/ExtensionInExtendedClass.kt");