diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index faa6ccecc90..7f825b4c756 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -407,7 +407,15 @@ class ControlFlowInformationProviderImpl private constructor( report(Errors.UNINITIALIZED_ENUM_ENTRY.on(element, classDescriptor), ctxt) ClassKind.OBJECT -> if (classDescriptor.isCompanionObject) { val container = classDescriptor.containingDeclaration - if (container is ClassDescriptor && container.kind == ClassKind.ENUM_CLASS) { + /* + * ProhibitAccessToEnumCompanionMembersInEnumConstructorCall feature enabled then UNINITIALIZED_ENUM_COMPANION + * will be reported from EnumCompanionInEnumConstructorCallChecker + */ + if ( + container is ClassDescriptor && + container.kind == ClassKind.ENUM_CLASS && + !languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAccessToEnumCompanionMembersInEnumConstructorCall) + ) { report(Errors.UNINITIALIZED_ENUM_COMPANION.on(element, container), ctxt) } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index ab3ae7b5794..e8b2395832e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -964,7 +964,8 @@ public interface Errors { DiagnosticFactory1 UNINITIALIZED_VARIABLE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 UNINITIALIZED_PARAMETER = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 UNINITIALIZED_ENUM_ENTRY = DiagnosticFactory1.create(ERROR); - DiagnosticFactory1 UNINITIALIZED_ENUM_COMPANION = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 UNINITIALIZED_ENUM_COMPANION = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 UNINITIALIZED_ENUM_COMPANION_WARNING = DiagnosticFactory1.create(WARNING); DiagnosticFactory1 UNUSED_VARIABLE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME); DiagnosticFactory1 UNUSED_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 35d4935c261..1b19ee0f3aa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -346,6 +346,7 @@ public class DefaultErrorMessages { MAP.put(UNINITIALIZED_PARAMETER, "Parameter ''{0}'' is uninitialized here", NAME); MAP.put(UNINITIALIZED_ENUM_ENTRY, "Enum entry ''{0}'' is uninitialized here", NAME); MAP.put(UNINITIALIZED_ENUM_COMPANION, "Companion object of enum class ''{0}'' is uninitialized here", NAME); + MAP.put(UNINITIALIZED_ENUM_COMPANION_WARNING, "Companion object of enum class ''{0}'' is uninitialized here. This warning will became error in future releases", NAME); MAP.put(UNUSED_VARIABLE, "Variable ''{0}'' is never used", NAME); MAP.put(UNUSED_PARAMETER, "Parameter ''{0}'' is never used", NAME); MAP.put(UNUSED_ANONYMOUS_PARAMETER, "Parameter ''{0}'' is never used, could be renamed to _", NAME); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt index d5a6fc72135..2e70e2535d3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/PlatformConfiguratorBase.kt @@ -46,6 +46,7 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf( SealedInheritorInSameModuleChecker, SealedInterfaceAllowedChecker, SuspendFunctionAsSupertypeChecker, + EnumCompanionInEnumConstructorCallChecker, ) private val DEFAULT_CALL_CHECKERS = listOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/EnumCompanionInEnumConstructorCallChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/EnumCompanionInEnumConstructorCallChecker.kt new file mode 100644 index 00000000000..e4433984648 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/EnumCompanionInEnumConstructorCallChecker.kt @@ -0,0 +1,109 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.checkers + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.diagnostics.DiagnosticSink +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall +import org.jetbrains.kotlin.resolve.scopes.receivers.ClassValueReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull + +object EnumCompanionInEnumConstructorCallChecker : DeclarationChecker { + override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { + if (declaration !is KtEnumEntry || descriptor !is ClassDescriptor) return + if (descriptor.kind != ClassKind.ENUM_ENTRY) return + val enumDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return + val enumCompanion = enumDescriptor.companionObjectDescriptor ?: return + val initializer = declaration.initializerList?.initializers?.firstIsInstanceOrNull() ?: return + val bindingTrace = context.trace + val visitor = Visitor( + enumDescriptor, + enumCompanion, + bindingTrace.bindingContext, + bindingTrace, + reportError = context.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAccessToEnumCompanionMembersInEnumConstructorCall) + ) + initializer.acceptChildren(visitor) + } + + private class Visitor( + val enumDescriptor: ClassDescriptor, + val companionDescriptor: ClassDescriptor, + val context: BindingContext, + val reporter: DiagnosticSink, + val reportError: Boolean + ) : KtVisitorVoid() { + override fun visitElement(element: PsiElement) { + element.acceptChildren(this) + } + + override fun visitExpression(expression: KtExpression) { + val needAnalyzeReceiver = analyzeExpression(expression) + if (needAnalyzeReceiver) { + expression.acceptChildren(this) + } else if (expression is KtCallExpression) { + expression.valueArgumentList?.acceptChildren(this) + } + } + + private fun analyzeExpression(expression: KtExpression): Boolean { + if (expression.parent is KtCallExpression) return true + val resolvedCall = expression.getResolvedCall(context) ?: return true + + val dispatchDescriptor = resolvedCall.dispatchReceiver.resolvedDescriptor + val extensionDescriptor = resolvedCall.extensionReceiver.resolvedDescriptor + val dispatchIsCompanion = dispatchDescriptor == companionDescriptor + val extensionIsCompanion = extensionDescriptor == companionDescriptor + + val dispatchIsImplicit = resolvedCall.dispatchReceiver is ImplicitClassReceiver + val extensionIsImplicit = resolvedCall.extensionReceiver is ImplicitClassReceiver + + /* + * ControlFlowInformationProviderImpl already reports UNINITIALIZED_ENUM_COMPANION for extension function calls + * with implicit companion receiver, so we should skip reporting a warning + * + * If feature is enabled then ControlFlowInformationProviderImpl won't report an error, to keep all checks + * in one place (in this checker) + */ + if ( + !reportError && + expression is KtCallExpression && + (dispatchIsCompanion && dispatchIsImplicit || extensionIsCompanion && extensionIsImplicit) + ) return false + + if (dispatchIsCompanion || extensionIsCompanion) { + val reportOn = when (val receiverExpression = (expression as? KtQualifiedExpression)?.receiverExpression) { + is KtSimpleNameExpression -> receiverExpression + is KtQualifiedExpression -> receiverExpression.selectorExpression + else -> null + } ?: expression + val factory = if (reportError) { + Errors.UNINITIALIZED_ENUM_COMPANION + } else { + Errors.UNINITIALIZED_ENUM_COMPANION_WARNING + } + reporter.report(factory.on(reportOn, enumDescriptor)) + return false + } + return true + } + } + + private val ReceiverValue?.resolvedDescriptor: DeclarationDescriptor? + get() { + if (this !is ClassValueReceiver && this !is ImplicitClassReceiver) return null + return this.type.unwrap().constructor.declarationDescriptor + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedEnumCompanionVals.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedEnumCompanionVals.kt index 02fc1d595f3..86fea59ebe5 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedEnumCompanionVals.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/UninitializedEnumCompanionVals.kt @@ -1,7 +1,7 @@ // SKIP_TXT enum class A(val z: Any) { - Y(x); + Y(x); companion object { val x = A.Y.ordinal @@ -9,7 +9,7 @@ enum class A(val z: Any) { } enum class B(val z: Any) { - Y(B.x); + Y(B.x); companion object { val x = B.Y.ordinal diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt index 0bae914a844..1838987b064 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt @@ -9,7 +9,7 @@ enum class B(val x: Int) { } enum class C(val x: Int) { - C1(SUM), + C1(SUM), C2(1); companion object { @@ -32,7 +32,7 @@ enum class Fruit(personal: Int) { // Another example from KT-11769 enum class EnumCompanion1(val x: Int) { - INSTANCE(Companion.foo()), + INSTANCE(Companion.foo()), ANOTHER(foo()); companion object { diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.kt new file mode 100644 index 00000000000..cf805150c1a --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.kt @@ -0,0 +1,40 @@ +// LANGUAGE: +ProhibitAccessToEnumCompanionMembersInEnumConstructorCall +// FIR_IDENTICAL +// ISSUE: KT-49110 + +enum class SomeEnum(val x: Int) { + A(companionFun().length),// UNINITIALIZED_ENUM_COMPANION + B(companionProp.length), // UNINITIALIZED_VARIABLE + + C(SomeEnum.companionFun().length), + D(SomeEnum.companionProp.length), + + E(SomeEnum.Companion.companionFun().length), + F(SomeEnum.Companion.companionProp.length); // UNINITIALIZED_VARIABLE + + companion object { + val companionProp = "someString" + fun companionFun(): String = "someString" + } +} + +enum class OtherEnum(val x: Int) { + G(extensionFun().length), // UNINITIALIZED_ENUM_COMPANION + H(extensionProp.length), + + I(OtherEnum.extensionFun().length), + J(OtherEnum.extensionProp.length), + + K(OtherEnum.Companion.extensionFun().length), + L(OtherEnum.Companion.extensionProp.length); + + companion object { + val companionProp = "someString" + fun companionFun(): String = "someString" + } +} + +fun OtherEnum.Companion.extensionFun(): String = companionFun() +val OtherEnum.Companion.extensionProp: String + get() = companionProp + diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.txt new file mode 100644 index 00000000000..1935f46affd --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.txt @@ -0,0 +1,82 @@ +package + +public val OtherEnum.Companion.extensionProp: kotlin.String +public fun OtherEnum.Companion.extensionFun(): kotlin.String + +public final enum class OtherEnum : kotlin.Enum { + enum entry G + + enum entry H + + enum entry I + + enum entry J + + enum entry K + + enum entry L + + private constructor OtherEnum(/*0*/ x: kotlin.Int) + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + public final val x: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: OtherEnum): 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 + + public companion object Companion { + private constructor Companion() + public final val companionProp: kotlin.String = "someString" + public final fun companionFun(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open 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): OtherEnum + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class SomeEnum : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + enum entry D + + enum entry E + + enum entry F + + private constructor SomeEnum(/*0*/ x: kotlin.Int) + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + public final val x: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): 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 + + public companion object Companion { + private constructor Companion() + public final val companionProp: kotlin.String = "someString" + public final fun companionFun(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open 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): SomeEnum + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.fir.kt new file mode 100644 index 00000000000..819b4879c24 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.fir.kt @@ -0,0 +1,39 @@ +// LANGUAGE: -ProhibitAccessToEnumCompanionMembersInEnumConstructorCall +// ISSUE: KT-49110 + +enum class SomeEnum(val x: Int) { + A(companionFun().length),// UNINITIALIZED_ENUM_COMPANION + B(companionProp.length), // UNINITIALIZED_VARIABLE + + C(SomeEnum.companionFun().length), + D(SomeEnum.companionProp.length), + + E(SomeEnum.Companion.companionFun().length), + F(SomeEnum.Companion.companionProp.length); // UNINITIALIZED_VARIABLE + + companion object { + val companionProp = "someString" + fun companionFun(): String = "someString" + } +} + +enum class OtherEnum(val x: Int) { + G(extensionFun().length), // UNINITIALIZED_ENUM_COMPANION + H(extensionProp.length), + + I(OtherEnum.extensionFun().length), + J(OtherEnum.extensionProp.length), + + K(OtherEnum.Companion.extensionFun().length), + L(OtherEnum.Companion.extensionProp.length); + + companion object { + val companionProp = "someString" + fun companionFun(): String = "someString" + } +} + +fun OtherEnum.Companion.extensionFun(): String = companionFun() +val OtherEnum.Companion.extensionProp: String + get() = companionProp + diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.kt new file mode 100644 index 00000000000..fb1fde5b102 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.kt @@ -0,0 +1,39 @@ +// LANGUAGE: -ProhibitAccessToEnumCompanionMembersInEnumConstructorCall +// ISSUE: KT-49110 + +enum class SomeEnum(val x: Int) { + A(companionFun().length),// UNINITIALIZED_ENUM_COMPANION + B(companionProp.length), // UNINITIALIZED_VARIABLE + + C(SomeEnum.companionFun().length), + D(SomeEnum.companionProp.length), + + E(SomeEnum.Companion.companionFun().length), + F(SomeEnum.Companion.companionProp.length); // UNINITIALIZED_VARIABLE + + companion object { + val companionProp = "someString" + fun companionFun(): String = "someString" + } +} + +enum class OtherEnum(val x: Int) { + G(extensionFun().length), // UNINITIALIZED_ENUM_COMPANION + H(extensionProp.length), + + I(OtherEnum.extensionFun().length), + J(OtherEnum.extensionProp.length), + + K(OtherEnum.Companion.extensionFun().length), + L(OtherEnum.Companion.extensionProp.length); + + companion object { + val companionProp = "someString" + fun companionFun(): String = "someString" + } +} + +fun OtherEnum.Companion.extensionFun(): String = companionFun() +val OtherEnum.Companion.extensionProp: String + get() = companionProp + diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.txt new file mode 100644 index 00000000000..51a79a23652 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.txt @@ -0,0 +1,83 @@ +package + +public val OtherEnum.Companion.extensionProp: kotlin.String +public fun OtherEnum.Companion.extensionFun(): kotlin.String + +public final enum class OtherEnum : kotlin.Enum { + enum entry G + + enum entry H + + enum entry I + + enum entry J + + enum entry K + + enum entry L + + private constructor OtherEnum(/*0*/ x: kotlin.Int) + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + public final val x: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: OtherEnum): 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 + + public companion object Companion { + private constructor Companion() + public final val companionProp: kotlin.String = "someString" + public final fun companionFun(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open 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): OtherEnum + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class SomeEnum : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + enum entry D + + enum entry E + + enum entry F + + private constructor SomeEnum(/*0*/ x: kotlin.Int) + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + public final val x: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: SomeEnum): 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 + + public companion object Companion { + private constructor Companion() + public final val companionProp: kotlin.String = "someString" + public final fun companionFun(): kotlin.String + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open 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): SomeEnum + public final /*synthesized*/ fun values(): kotlin.Array +} + diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 4b33f3ab1cf..740c8b276d2 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -5757,6 +5757,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/tryWithAssignmentUsedInCatch.kt"); } + @Test + @TestMetadata("uninitializedCompanionOfEnum_after.kt") + public void testUninitializedCompanionOfEnum_after() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_after.kt"); + } + + @Test + @TestMetadata("uninitializedCompanionOfEnum_before.kt") + public void testUninitializedCompanionOfEnum_before() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/uninitializedCompanionOfEnum_before.kt"); + } + @Test @TestMetadata("UninitializedEnumCompanionVals.kt") public void testUninitializedEnumCompanionVals() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 38d549b441d..e4019e6c961 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -237,6 +237,7 @@ enum class LanguageFeature( ProperTypeInferenceConstraintsProcessing(KOTLIN_1_7, kind = BUG_FIX), ProhibitNonExhaustiveIfInRhsOfElvis(KOTLIN_1_7, kind = BUG_FIX), // KT-44705 ForbidExposingTypesInPrimaryConstructorProperties(KOTLIN_1_7, kind = BUG_FIX), + ProhibitAccessToEnumCompanionMembersInEnumConstructorCall(KOTLIN_1_7, kind = BUG_FIX), // 1.8