diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt index 2b1067bdf42..cf51f82350b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt @@ -48,7 +48,7 @@ interface ControlFlowBuilder { fun declareVariable(property: KtVariableDeclaration) fun declareFunction(subroutine: KtElement, pseudocode: Pseudocode) - fun declareEnumEntry(enumEntry: KtEnumEntry) + fun declareEntryOrObject(entryOrObject: KtClassOrObject) // Labels fun createUnboundLabel(): Label diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt index 7e757058a01..2c774b45446 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt @@ -200,8 +200,8 @@ abstract class ControlFlowBuilderAdapter : ControlFlowBuilder { delegateBuilder.declareFunction(subroutine, pseudocode) } - override fun declareEnumEntry(enumEntry: KtEnumEntry) { - delegateBuilder.declareEnumEntry(enumEntry) + override fun declareEntryOrObject(entryOrObject: KtClassOrObject) { + delegateBuilder.declareEntryOrObject(entryOrObject) } override fun repeatPseudocode(startLabel: Label, finishLabel: Label) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt index 778611339d1..97aff80e15c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProvider.kt @@ -328,8 +328,20 @@ class ControlFlowInformationProvider private constructor( when (variableDescriptor) { is ValueParameterDescriptor -> report(Errors.UNINITIALIZED_PARAMETER.on(element, variableDescriptor), ctxt) - is FakeCallableDescriptorForObject -> - report(Errors.UNINITIALIZED_ENUM_ENTRY.on(element, variableDescriptor.classDescriptor), ctxt) + is FakeCallableDescriptorForObject -> { + val classDescriptor = variableDescriptor.classDescriptor + when (classDescriptor.kind) { + ClassKind.ENUM_ENTRY -> + 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) { + report(Errors.UNINITIALIZED_ENUM_COMPANION.on(element, container), ctxt) + } + } + else -> {} + } + } is VariableDescriptor -> report(Errors.UNINITIALIZED_VARIABLE.on(element, variableDescriptor), ctxt) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt index 10cdcb3570b..5c08b4bfc03 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt @@ -1266,6 +1266,16 @@ class ControlFlowProcessor(private val trace: BindingTrace) { } } + private fun processEntryOrObject(entryOrObject: KtClassOrObject) { + val classDescriptor = trace[BindingContext.DECLARATION_TO_DESCRIPTOR, entryOrObject] + if (classDescriptor is ClassDescriptor) { + builder.declareEntryOrObject(entryOrObject) + builder.write(entryOrObject, entryOrObject, createSyntheticValue(entryOrObject, MagicKind.FAKE_INITIALIZER), + AccessTarget.Declaration(FakeCallableDescriptorForObject(classDescriptor)), emptyMap()) + generateInstructions(entryOrObject) + } + } + override fun visitClass(klass: KtClass) { if (klass.hasPrimaryConstructor()) { processParameters(klass.getPrimaryConstructorParameters()) @@ -1281,16 +1291,10 @@ class ControlFlowProcessor(private val trace: BindingTrace) { klass.declarations.forEach { when (it) { is KtEnumEntry -> { - val classDescriptor = trace[BindingContext.DECLARATION_TO_DESCRIPTOR, it] - if (classDescriptor is ClassDescriptor) { - builder.declareEnumEntry(it) - builder.write(it, it, createSyntheticValue(it, MagicKind.FAKE_INITIALIZER), - AccessTarget.Declaration(FakeCallableDescriptorForObject(classDescriptor)), emptyMap()) - generateInstructions(it) - } + processEntryOrObject(it) } is KtObjectDeclaration -> if (it.isCompanion()) { - generateInstructions(it) + processEntryOrObject(it) } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt index 1dff2d6eb8d..6de539054c3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt @@ -274,8 +274,8 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { add(LocalFunctionDeclarationInstruction(subroutine, pseudocode, currentScope)) } - override fun declareEnumEntry(enumEntry: KtEnumEntry) { - add(VariableDeclarationInstruction(enumEntry, currentScope)) + override fun declareEntryOrObject(entryOrObject: KtClassOrObject) { + add(VariableDeclarationInstruction(entryOrObject, currentScope)) } override fun loadUnit(expression: KtExpression) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/VariableDeclarationInstruction.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/VariableDeclarationInstruction.kt index 682d9c0d89b..867ad4a3a8e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/VariableDeclarationInstruction.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/VariableDeclarationInstruction.kt @@ -16,22 +16,19 @@ package org.jetbrains.kotlin.cfg.pseudocode.instructions.special -import org.jetbrains.kotlin.psi.KtDeclaration -import org.jetbrains.kotlin.psi.KtVariableDeclaration -import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl -import org.jetbrains.kotlin.psi.KtEnumEntry +import org.jetbrains.kotlin.psi.* class VariableDeclarationInstruction( element: KtDeclaration, blockScope: BlockScope ) : InstructionWithNext(element, blockScope) { init { - assert(element is KtVariableDeclaration || element is KtParameter || element is KtEnumEntry) { + assert(element is KtVariableDeclaration || element is KtParameter || element is KtEnumEntry || element is KtObjectDeclaration) { "Invalid element: ${render(element)}}" } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index f7febd5f8f6..7709a65aeea 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -645,6 +645,7 @@ 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 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 ee0a1fea10d..602c19ff51f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -265,6 +265,7 @@ public class DefaultErrorMessages { MAP.put(UNINITIALIZED_VARIABLE, "Variable ''{0}'' must be initialized", NAME); 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(UNUSED_VARIABLE, "Variable ''{0}'' is never used", NAME); MAP.put(UNUSED_PARAMETER, "Parameter ''{0}'' is never used", NAME); MAP.put(ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE, "Variable ''{0}'' is assigned but never accessed", NAME); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java index 8f60ad51ca5..f6d811b2093 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContextUtils.java @@ -71,7 +71,8 @@ public class BindingContextUtils { public static VariableDescriptor extractVariableDescriptorIfAny(@NotNull BindingContext bindingContext, @Nullable KtElement element, boolean onlyReference) { DeclarationDescriptor descriptor = null; if (!onlyReference && - (element instanceof KtVariableDeclaration || element instanceof KtParameter || element instanceof KtEnumEntry)) { + (element instanceof KtVariableDeclaration || element instanceof KtParameter || + element instanceof KtEnumEntry || element instanceof KtObjectDeclaration)) { descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element); } else if (element instanceof KtSimpleNameExpression) { diff --git a/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.instructions b/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.instructions new file mode 100644 index 00000000000..dd8ad526b5c --- /dev/null +++ b/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.instructions @@ -0,0 +1,43 @@ +== EE == +enum class EE(val x: Int) { + INSTANCE(Companion.foo()), + ANOTHER(foo()); + + companion object { + fun foo() = 42 + } +} +--------------------- +L0: + 1 + v(val x: Int) + magic[FAKE_INITIALIZER](val x: Int) -> + w(x|) + v(INSTANCE(Companion.foo()),) + magic[FAKE_INITIALIZER](INSTANCE(Companion.foo()),) -> + w(INSTANCE|) + mark(Companion.foo()) + mark(Companion) + r(Companion) -> + mark(foo()) + call(foo(), foo|) -> + mark((Companion.foo())) + call((Companion.foo()), |) -> + v(ANOTHER(foo());) + magic[FAKE_INITIALIZER](ANOTHER(foo());) -> + w(ANOTHER|) + magic[IMPLICIT_RECEIVER](foo()) -> + mark(foo()) + call(foo(), foo|) -> + mark((foo())) + call((foo()), |) -> + v(companion object { fun foo() = 42 }) + magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> + w(Companion|) +L1: + NEXT:[] +error: + PREV:[] +sink: + PREV:[, ] +===================== diff --git a/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.kt b/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.kt new file mode 100644 index 00000000000..0e58b358910 --- /dev/null +++ b/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.kt @@ -0,0 +1,8 @@ +enum class EE(val x: Int) { + INSTANCE(Companion.foo()), + ANOTHER(foo()); + + companion object { + fun foo() = 42 + } +} \ No newline at end of file diff --git a/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.values b/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.values new file mode 100644 index 00000000000..d998d0467f8 --- /dev/null +++ b/compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.values @@ -0,0 +1,22 @@ +== EE == +enum class EE(val x: Int) { + INSTANCE(Companion.foo()), + ANOTHER(foo()); + + companion object { + fun foo() = 42 + } +} +--------------------- + : Int NEW: magic[FAKE_INITIALIZER](val x: Int) -> + : EE NEW: magic[FAKE_INITIALIZER](INSTANCE(Companion.foo()),) -> + : EE NEW: magic[FAKE_INITIALIZER](ANOTHER(foo());) -> + : EE.Companion NEW: magic[IMPLICIT_RECEIVER](foo()) -> + : EE.Companion NEW: magic[FAKE_INITIALIZER](companion object { fun foo() = 42 }) -> +Companion : EE.Companion NEW: r(Companion) -> +foo() : Int NEW: call(foo(), foo|) -> +Companion.foo() : Int COPY +(Companion.foo()) : * NEW: call((Companion.foo()), |) -> +foo() : Int NEW: call(foo(), foo|) -> +(foo()) : * NEW: call((foo()), |) -> +===================== diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt new file mode 100644 index 00000000000..a4dce9846c1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt @@ -0,0 +1,55 @@ +enum class B(val x: Int) { + B1(1), + B2(2); + + companion object { + val SUM = B1.x + B2.x + val COPY = B1 + } +} + +enum class C(val x: Int) { + C1(SUM), + C2(1); + + companion object { + val COPY = C2 + val SUM = C1.x + COPY.x + } +} + +// From KT-11769 +enum class Fruit(personal: Int) { + APPLE(1); + + companion object { + val common = 20 + } + + val score = personal + common +} + +// Another example from KT-11769 +enum class EnumCompanion1(val x: Int) { + INSTANCE(Companion.foo()), + ANOTHER(foo()); + + companion object { + fun foo() = 42 + } +} +// Also should be reported for implicit receiver +enum class EnumCompanion2(val x: Int) { + INSTANCE(foo()); // TODO + + companion object { + fun foo() = 42 + } +} +// But not for another enum +enum class EnumCompanion3(val x: Int) { + INSTANCE(EnumCompanion1.foo()), + ANOTHER(EnumCompanion2.foo()); + + companion object +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.txt new file mode 100644 index 00000000000..d7bd881ae52 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.txt @@ -0,0 +1,178 @@ +package + +public final enum class B : kotlin.Enum { + enum entry B1 + + enum entry B2 + + private constructor B(/*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: B): 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 COPY: B + public final val SUM: kotlin.Int + 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): B + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class C : kotlin.Enum { + enum entry C1 + + enum entry C2 + + private constructor C(/*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: C): 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 COPY: C + public final val SUM: kotlin.Int + 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): C + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class EnumCompanion1 : kotlin.Enum { + enum entry INSTANCE + + enum entry ANOTHER + + private constructor EnumCompanion1(/*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: EnumCompanion1): 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 open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Int + 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): EnumCompanion1 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class EnumCompanion2 : kotlin.Enum { + enum entry INSTANCE + + private constructor EnumCompanion2(/*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: EnumCompanion2): 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 open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): kotlin.Int + 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): EnumCompanion2 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class EnumCompanion3 : kotlin.Enum { + enum entry INSTANCE + + enum entry ANOTHER + + private constructor EnumCompanion3(/*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: EnumCompanion3): 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 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): EnumCompanion3 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Fruit : kotlin.Enum { + enum entry APPLE + + private constructor Fruit(/*0*/ personal: 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 score: kotlin.Int + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Fruit): 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 common: kotlin.Int = 20 + 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): Fruit + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.kt index 40ac0f00670..e2ec8f0801f 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.kt @@ -3,26 +3,6 @@ enum class A(val v: A) { A2(A1) } -enum class B(val x: Int) { - B1(1), - B2(2); - - companion object { - val SUM = B1.x + B2.x - val COPY = B1 - } -} - -enum class C(val x: Int) { - C1(SUM), - C2(1); - - companion object { - val COPY = C2 - val SUM = C1.x + COPY.x - } -} - enum class D(val x: Int) { D1(D2.x), D2(D1.x) @@ -44,17 +24,6 @@ object Object1 { } } -// From KT-11769 -enum class Fruit(personal: Int) { - APPLE(1); - - companion object { - val common = 20 - } - - val score = personal + common -} - // From KT-6054 enum class MyEnum { A, B; diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.txt index 0526eb5bfbe..956ae2370c4 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.txt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.txt @@ -22,68 +22,6 @@ public final enum class A : kotlin.Enum { public final /*synthesized*/ fun values(): kotlin.Array } -public final enum class B : kotlin.Enum { - enum entry B1 - - enum entry B2 - - private constructor B(/*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: B): 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 COPY: B - public final val SUM: kotlin.Int - 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): B - public final /*synthesized*/ fun values(): kotlin.Array -} - -public final enum class C : kotlin.Enum { - enum entry C1 - - enum entry C2 - - private constructor C(/*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: C): 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 COPY: C - public final val SUM: kotlin.Int - 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): C - public final /*synthesized*/ fun values(): kotlin.Array -} - public final enum class D : kotlin.Enum { enum entry D1 @@ -134,34 +72,6 @@ public final enum class E : kotlin.Enum { public final /*synthesized*/ fun values(): kotlin.Array } -public final enum class Fruit : kotlin.Enum { - enum entry APPLE - - private constructor Fruit(/*0*/ personal: 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 score: kotlin.Int - protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any - public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: Fruit): 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 common: kotlin.Int = 20 - 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): Fruit - public final /*synthesized*/ fun values(): kotlin.Array -} - public final enum class MyEnum : kotlin.Enum { enum entry A diff --git a/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java index 6e8371ed10a..8cbfc851efb 100644 --- a/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cfg/ControlFlowTestGenerated.java @@ -375,6 +375,12 @@ public class ControlFlowTestGenerated extends AbstractControlFlowTest { doTest(fileName); } + @TestMetadata("EnumEntryRefersCompanion.kt") + public void testEnumEntryRefersCompanion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.kt"); + doTest(fileName); + } + @TestMetadata("ObjectEnumQualifiers.kt") public void testObjectEnumQualifiers() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/classesAndObjects/ObjectEnumQualifiers.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java index c83e8fdbc87..6e078ad7a71 100644 --- a/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cfg/PseudoValueTestGenerated.java @@ -377,6 +377,12 @@ public class PseudoValueTestGenerated extends AbstractPseudoValueTest { doTest(fileName); } + @TestMetadata("EnumEntryRefersCompanion.kt") + public void testEnumEntryRefersCompanion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/classesAndObjects/EnumEntryRefersCompanion.kt"); + doTest(fileName); + } + @TestMetadata("ObjectEnumQualifiers.kt") public void testObjectEnumQualifiers() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cfg/declarations/classesAndObjects/ObjectEnumQualifiers.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 0a4a31a1069..83dbc4b71b0 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -3306,6 +3306,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("enumCompanionInterdependence.kt") + public void testEnumCompanionInterdependence() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/enumCompanionInterdependence.kt"); + doTest(fileName); + } + @TestMetadata("enumInterdependence.kt") public void testEnumInterdependence() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlFlowAnalysis/enumInterdependence.kt");