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 0fa528d0152..68eacb94e97 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 @@ -17,13 +17,18 @@ package org.jetbrains.kotlin.resolve.scopes.receivers import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector +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.MemberScope +import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.utils.Printer import java.util.* interface Qualifier : QualifierReceiver { @@ -91,7 +96,28 @@ class TypeAliasQualifier( } override val staticScope: MemberScope - get() = classDescriptor.staticScope + get() = when { + DescriptorUtils.isEnumClass(classDescriptor) -> + ChainedMemberScope("Static scope for typealias ${descriptor.name}", + listOf(classDescriptor.staticScope, EnumEntriesScope())) + else -> + classDescriptor.staticScope + } + + private inner class EnumEntriesScope : MemberScopeImpl() { + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? = + classDescriptor.unsubstitutedInnerClassesScope + .getContributedClassifier(name, location) + ?.takeIf { DescriptorUtils.isEnumEntry(it) } + + override fun printScopeStructure(p: Printer) { + p.println(javaClass.simpleName, " {") + p.pushIndent() + p.println("descriptor = ", descriptor) + p.popIndent() + p.println("}") + } + } } class ClassValueReceiver(val classQualifier: ClassifierQualifier, private val type: KotlinType) : ExpressionReceiver { diff --git a/compiler/testData/codegen/box/typealias/enumEntryQualifier.kt b/compiler/testData/codegen/box/typealias/enumEntryQualifier.kt new file mode 100644 index 00000000000..19c383aaed0 --- /dev/null +++ b/compiler/testData/codegen/box/typealias/enumEntryQualifier.kt @@ -0,0 +1,10 @@ +enum class MyEnum { + O; + companion object { + val K = "K" + } +} + +typealias MyAlias = MyEnum + +fun box() = MyAlias.O.name + MyAlias.K \ No newline at end of file diff --git a/compiler/testData/codegen/light-analysis/typealias/enumEntryQualifier.txt b/compiler/testData/codegen/light-analysis/typealias/enumEntryQualifier.txt new file mode 100644 index 00000000000..3007c7026c2 --- /dev/null +++ b/compiler/testData/codegen/light-analysis/typealias/enumEntryQualifier.txt @@ -0,0 +1,22 @@ +@kotlin.Metadata +public final class EnumEntryQualifierKt { + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String +} + +@kotlin.Metadata +public enum class MyEnum { + public final static field Companion: MyEnum.Companion + private final static @org.jetbrains.annotations.NotNull field K: java.lang.String + public final static field O: MyEnum + inner class MyEnum/Companion + protected method (p0: java.lang.String, p1: int): void + public static method valueOf(p0: java.lang.String): MyEnum + public static method values(): MyEnum[] +} + +@kotlin.Metadata +public final static class MyEnum/Companion { + inner class MyEnum/Companion + private method (): void + public final @org.jetbrains.annotations.NotNull method getK(): java.lang.String +} diff --git a/compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.kt b/compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.kt new file mode 100644 index 00000000000..cc49eb2ad50 --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.kt @@ -0,0 +1,6 @@ +enum class MyEnum { A } + +typealias TestAlias = MyEnum + +val test1 = MyEnum.A +val test2 = TestAlias.A \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.txt b/compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.txt new file mode 100644 index 00000000000..f736664f26b --- /dev/null +++ b/compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.txt @@ -0,0 +1,24 @@ +package + +public val test1: MyEnum +public val test2: MyEnum + +public final enum class MyEnum : kotlin.Enum { + enum entry A + + private constructor MyEnum() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: MyEnum): kotlin.Int + public final override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): MyEnum + public final /*synthesized*/ fun values(): kotlin.Array +} +public typealias TestAlias = MyEnum diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 8c859856d09..be9d2019f66 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17261,6 +17261,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/typealias"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("enumEntryQualifier.kt") + public void testEnumEntryQualifier() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); + doTest(fileName); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 328ae1b94e8..3ee44026049 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -22168,6 +22168,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("enumEntryQualifier.kt") + public void testEnumEntryQualifier() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/enumEntryQualifier.kt"); + doTest(fileName); + } + @TestMetadata("exposedExpandedType.kt") public void testExposedExpandedType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/typealias/exposedExpandedType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index f7831022513..ac09cb1160a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17261,6 +17261,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/typealias"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("enumEntryQualifier.kt") + public void testEnumEntryQualifier() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); + doTest(fileName); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java index 9c3022853d0..4c406aee6dd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeCodegenTestGenerated.java @@ -17261,6 +17261,12 @@ public class LightAnalysisModeCodegenTestGenerated extends AbstractLightAnalysis KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/typealias"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("enumEntryQualifier.kt") + public void testEnumEntryQualifier() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); + doTest(fileName); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index bf4b1896c35..e5d2eac03c9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -21729,6 +21729,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/typealias"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); } + @TestMetadata("enumEntryQualifier.kt") + public void testEnumEntryQualifier() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); + doTest(fileName); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java index f350fefced9..a8c4bfa1fdb 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java @@ -123,7 +123,7 @@ public final class BindingUtils { if (descriptor instanceof TypeAliasDescriptor) { ClassDescriptor classDescriptor = ((TypeAliasDescriptor) descriptor).getClassDescriptor(); assert classDescriptor != null : "Class descriptor must be non-null in resolved typealias: " + descriptor; - if (classDescriptor.getKind() != ClassKind.OBJECT) { + if (classDescriptor.getKind() != ClassKind.OBJECT && classDescriptor.getKind() != ClassKind.ENUM_CLASS) { classDescriptor = classDescriptor.getCompanionObjectDescriptor(); assert classDescriptor != null : "Resolved typealias must have non-null class descriptor: " + descriptor; }