From d21d362f0fbaf9c17984ebdd6fe066655ae6dbb1 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 9 Mar 2017 12:22:10 +0300 Subject: [PATCH] Allow enum entries in double colon LHS with LV = 1.0 #KT-16782 Fixed --- .../resolve/QualifiedExpressionResolver.kt | 6 +++++- .../DoubleColonExpressionResolver.kt | 4 +++- .../boundCallableReference.kt | 5 +++++ .../boundCallableReference.txt | 20 +++++++++++++++++++ .../boundClassLiteral.kt | 4 ++++ .../boundClassLiteral.txt | 20 +++++++++++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt index a226ee67723..5207a277bf4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/QualifiedExpressionResolver.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode +import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector import org.jetbrains.kotlin.resolve.calls.CallExpressionElement import org.jetbrains.kotlin.resolve.calls.unrollToLeftMostQualifiedExpression import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -119,7 +120,10 @@ class QualifiedExpressionResolver { private fun checkNotEnumEntry(descriptor: DeclarationDescriptor?, trace: BindingTrace, expression: KtSimpleNameExpression) { if (descriptor != null && DescriptorUtils.isEnumEntry(descriptor)) { - trace.report(Errors.ENUM_ENTRY_AS_TYPE.on(expression)) + val qualifiedParent = expression.getTopmostParentQualifiedExpressionForSelector() + if (qualifiedParent == null || qualifiedParent.parent !is KtDoubleColonExpression) { + trace.report(Errors.ENUM_ENTRY_AS_TYPE.on(expression)) + } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt index 7c5ee2b0643..54a8e7059a6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/DoubleColonExpressionResolver.kt @@ -423,7 +423,9 @@ class DoubleColonExpressionResolver( val classDescriptor = resultingDescriptor.classDescriptor if (classDescriptor.companionObjectDescriptor != null) return null - if (DescriptorUtils.isObject(classDescriptor)) { + if (DescriptorUtils.isObject(classDescriptor) || + (!languageVersionSettings.supportsFeature(LanguageFeature.BoundCallableReferences) && + DescriptorUtils.isEnumEntry(classDescriptor))) { return DoubleColonLHS.Expression(typeInfo, isObjectQualifier = true) } } diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt index 84def19b7e8..179f1912661 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.kt @@ -13,6 +13,11 @@ val fail2 = O::hashCode val ok2 = O::Y val ok3 = O.Y::hashCode +enum class E { + Entry +} +val ok4 = E.Entry::hashCode + fun hashCode() {} val fail3 = ""::hashCode diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt index f3b4ba5cd7c..95b2b594efe 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundCallableReference.txt @@ -8,6 +8,7 @@ public val fail5: kotlin.reflect.KFunction0 public val ok1: kotlin.reflect.KFunction1 public val ok2: kotlin.reflect.KFunction0 public val ok3: kotlin.reflect.KFunction1 +public val ok4: kotlin.reflect.KFunction1 public fun hashCode(): kotlin.Unit public final class C { @@ -24,6 +25,25 @@ public final class C { } } +public final enum class E : kotlin.Enum { + enum entry Entry + + private constructor E() + 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: E): 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): E + public final /*synthesized*/ fun values(): kotlin.Array +} + public object O { private constructor O() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.kt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.kt index 2981e23a27f..d5371e969fa 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.kt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.kt @@ -7,6 +7,10 @@ val ok2 = C.Companion::class object O val ok3 = O::class +enum class E { + Entry +} +val ok4 = E.Entry::class val fail1 = ""::class val fail2 = String?::class diff --git a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt index 79ecd843f9f..954f1a9a037 100644 --- a/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt +++ b/compiler/testData/diagnostics/tests/sourceCompatibility/noBoundCallableReferences/boundClassLiteral.txt @@ -7,6 +7,7 @@ public val fail4: kotlin.reflect.KClass public val ok1: kotlin.reflect.KClass public val ok2: kotlin.reflect.KClass public val ok3: kotlin.reflect.KClass +public val ok4: kotlin.reflect.KClass public final class C { public constructor C() @@ -22,6 +23,25 @@ public final class C { } } +public final enum class E : kotlin.Enum { + enum entry Entry + + private constructor E() + 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: E): 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): E + public final /*synthesized*/ fun values(): kotlin.Array +} + public object O { private constructor O() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean