From 8631e898a7c15a066a756bb8c47759ca0fea5d50 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Sun, 22 Oct 2017 17:00:50 +0300 Subject: [PATCH] KT-12797: Fix completion to show inner classes from base class #KT-12797 fixed --- .../codeInsight/ReferenceVariantsHelper.kt | 24 +++++++++++++++---- .../testData/basic/common/InnerInBaseClass.kt | 15 ++++++++++++ .../test/JSBasicCompletionTestGenerated.java | 6 +++++ .../test/JvmBasicCompletionTestGenerated.java | 6 +++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 idea/idea-completion/testData/basic/common/InnerInBaseClass.kt 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 f2094ab7c03..1725f2564a2 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 @@ -269,7 +269,11 @@ class ReferenceVariantsHelper( } else { // process non-instance members and class constructors - descriptors.addNonExtensionCallablesAndConstructors(resolutionScope, kindFilter, nameFilter, constructorFilter = { !it.isInner }) + descriptors.addNonExtensionCallablesAndConstructors( + resolutionScope, + kindFilter, nameFilter, constructorFilter = { !it.isInner }, + classesOnly = false + ) } return descriptors } @@ -328,7 +332,18 @@ class ReferenceVariantsHelper( constructorFilter: (ClassDescriptor) -> Boolean ) { for (receiverType in receiverTypes) { - addNonExtensionCallablesAndConstructors(receiverType.memberScope.memberScopeAsImportingScope(), kindFilter, nameFilter, constructorFilter) + addNonExtensionCallablesAndConstructors( + receiverType.memberScope.memberScopeAsImportingScope(), + kindFilter, nameFilter, constructorFilter, + false + ) + receiverType.constructor.supertypes.forEach { + addNonExtensionCallablesAndConstructors( + it.memberScope.memberScopeAsImportingScope(), + kindFilter, nameFilter, constructorFilter, + true + ) + } } } @@ -336,7 +351,8 @@ class ReferenceVariantsHelper( scope: HierarchicalScope, kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean, - constructorFilter: (ClassDescriptor) -> Boolean + constructorFilter: (ClassDescriptor) -> Boolean, + classesOnly: Boolean ) { var filterToUse = DescriptorKindFilter(kindFilter.kindMask and DescriptorKindFilter.CALLABLES.kindMask).exclude(DescriptorKindExclude.Extensions) @@ -351,7 +367,7 @@ class ReferenceVariantsHelper( if (!constructorFilter(descriptor)) continue descriptor.constructors.filterTo(this) { kindFilter.accepts(it) } } - else if (kindFilter.accepts(descriptor)) { + else if (!classesOnly && kindFilter.accepts(descriptor)) { this.add(descriptor) } } diff --git a/idea/idea-completion/testData/basic/common/InnerInBaseClass.kt b/idea/idea-completion/testData/basic/common/InnerInBaseClass.kt new file mode 100644 index 00000000000..e0463d1e479 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/InnerInBaseClass.kt @@ -0,0 +1,15 @@ + +abstract class A { + inner class InnerInA +} + +abstract class B : A() { + inner class InnerInB +} + +fun foo(b: B) { + val v = b.InnerIn +} + +// EXIST: InnerInB +// EXIST: InnerInA 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 45f20a13d8b..fedba24db4e 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 @@ -470,6 +470,12 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes doTest(fileName); } + @TestMetadata("InnerInBaseClass.kt") + public void testInnerInBaseClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InnerInBaseClass.kt"); + doTest(fileName); + } + @TestMetadata("InsideAnonymousClass.kt") public void testInsideAnonymousClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InsideAnonymousClass.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 3d22a1cca0c..b3db80aad51 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 @@ -470,6 +470,12 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT doTest(fileName); } + @TestMetadata("InnerInBaseClass.kt") + public void testInnerInBaseClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InnerInBaseClass.kt"); + doTest(fileName); + } + @TestMetadata("InsideAnonymousClass.kt") public void testInsideAnonymousClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/basic/common/InsideAnonymousClass.kt");