From 9a938b07ba9a9619d50e5a91f252f885852b5729 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Wed, 4 Sep 2019 17:57:39 +0300 Subject: [PATCH] KT-17689: Fix `TypeAliasQualifier` to provide enum entries descriptors - this adds enum entries to the completion on the typealiases - we cannot use `unsubstitutedInnerClassesScope` instead of `EnumEntriesScope` because it allows to complete things that are not allowed to be resolved by the Kotlin compiler; see `EnumEntriesScope` doc for details - ^KT-17689 Fixed --- .../resolve/scopes/receivers/Qualifier.kt | 17 +++++++++++++++++ .../common/EnumItemsThroughChainedTypeAlias.kt | 14 ++++++++++++++ .../common/EnumItemsThroughSingleTypeAlias.kt | 13 +++++++++++++ .../test/JSBasicCompletionTestGenerated.java | 10 ++++++++++ .../test/JvmBasicCompletionTestGenerated.java | 10 ++++++++++ 5 files changed, 64 insertions(+) create mode 100644 idea/idea-completion/testData/basic/common/EnumItemsThroughChainedTypeAlias.kt create mode 100644 idea/idea-completion/testData/basic/common/EnumItemsThroughSingleTypeAlias.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt index 495de7576ed..9f86903e566 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/scopes/receivers/Qualifier.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSe import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.types.KotlinType @@ -107,7 +108,23 @@ class TypeAliasQualifier( classDescriptor.staticScope } + /** + * We cannot use [org.jetbrains.kotlin.descriptors.ClassDescriptor.getUnsubstitutedMemberScope] directly, + * because we do not allow complete resolve through type aliases yet (see KT-15298). + * + * However, we want to allow to resolve and autocomplete enum constants even through type aliases; + * that's why we use [org.jetbrains.kotlin.descriptors.ClassDescriptor.getUnsubstitutedMemberScope], + * but filter only enum entries. + */ private inner class EnumEntriesScope : MemberScopeImpl() { + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection = + classDescriptor.unsubstitutedInnerClassesScope + .getContributedDescriptors(kindFilter, nameFilter) + .filter { DescriptorUtils.isEnumEntry(it) } + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = classDescriptor.unsubstitutedInnerClassesScope .getContributedClassifier(name, location) diff --git a/idea/idea-completion/testData/basic/common/EnumItemsThroughChainedTypeAlias.kt b/idea/idea-completion/testData/basic/common/EnumItemsThroughChainedTypeAlias.kt new file mode 100644 index 00000000000..deab54e74c1 --- /dev/null +++ b/idea/idea-completion/testData/basic/common/EnumItemsThroughChainedTypeAlias.kt @@ -0,0 +1,14 @@ +enum class A { + ONE; + class B // Not allowed to resolve through typealiases +} + +typealias AA = A +typealias AAA = AA + +fun usage() { + AAA. +} + +// EXIST: ONE +// ABSENT: B \ No newline at end of file diff --git a/idea/idea-completion/testData/basic/common/EnumItemsThroughSingleTypeAlias.kt b/idea/idea-completion/testData/basic/common/EnumItemsThroughSingleTypeAlias.kt new file mode 100644 index 00000000000..aa6f21eb38b --- /dev/null +++ b/idea/idea-completion/testData/basic/common/EnumItemsThroughSingleTypeAlias.kt @@ -0,0 +1,13 @@ +enum class A { + ONE; + class B // Not allowed to resolve through typealiases +} + +typealias AA = A + +fun usage() { + AA. +} + +// EXIST: ONE, values, valueOf +// ABSENT: B \ 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 77380c67d16..eb3686176f3 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 @@ -101,6 +101,16 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes runTest("idea/idea-completion/testData/basic/common/DataClassMembers2.kt"); } + @TestMetadata("EnumItemsThroughChainedTypeAlias.kt") + public void testEnumItemsThroughChainedTypeAlias() throws Exception { + runTest("idea/idea-completion/testData/basic/common/EnumItemsThroughChainedTypeAlias.kt"); + } + + @TestMetadata("EnumItemsThroughSingleTypeAlias.kt") + public void testEnumItemsThroughSingleTypeAlias() throws Exception { + runTest("idea/idea-completion/testData/basic/common/EnumItemsThroughSingleTypeAlias.kt"); + } + @TestMetadata("ExtendClassName.kt") public void testExtendClassName() throws Exception { runTest("idea/idea-completion/testData/basic/common/ExtendClassName.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 8381e2371e4..513617c9b9a 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 @@ -101,6 +101,16 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT runTest("idea/idea-completion/testData/basic/common/DataClassMembers2.kt"); } + @TestMetadata("EnumItemsThroughChainedTypeAlias.kt") + public void testEnumItemsThroughChainedTypeAlias() throws Exception { + runTest("idea/idea-completion/testData/basic/common/EnumItemsThroughChainedTypeAlias.kt"); + } + + @TestMetadata("EnumItemsThroughSingleTypeAlias.kt") + public void testEnumItemsThroughSingleTypeAlias() throws Exception { + runTest("idea/idea-completion/testData/basic/common/EnumItemsThroughSingleTypeAlias.kt"); + } + @TestMetadata("ExtendClassName.kt") public void testExtendClassName() throws Exception { runTest("idea/idea-completion/testData/basic/common/ExtendClassName.kt");