diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 931be3f2f6b..d9754cb2fea 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -7612,6 +7612,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/enum/SecondaryConstructorCall.kt"); } + @TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOne.kt") + public void testSecondaryConstructorWithoutDelegatingToPrimaryOne() throws Exception { + runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt"); + } + + @TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt") + public void testSecondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt"); + } + @TestMetadata("starImportNestedClassAndEntries.kt") public void testStarImportNestedClassAndEntries() throws Exception { runTest("compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt"); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index f11a15b80e6..288138a2762 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -388,6 +388,9 @@ public interface Errors { DiagnosticFactory0 PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED = DiagnosticFactory0.create(ERROR, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL); + DiagnosticFactory0 PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM = + DiagnosticFactory0.create(WARNING, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL); + DiagnosticFactory0 DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR = DiagnosticFactory0.create(ERROR); 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 b5cfe358cce..a7d98a34f35 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -634,6 +634,7 @@ public class DefaultErrorMessages { MAP.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects"); MAP.put(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, "Supertype initialization is impossible without primary constructor"); MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, "Primary constructor call expected"); + MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM, "Primary constructor call expected. It's going to be an error in 1.5."); MAP.put(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, "Call to super is not allowed in enum constructor"); MAP.put(PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, "Primary constructor required for data class"); MAP.put(EXPLICIT_DELEGATION_CALL_REQUIRED, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index 833324d75be..de3a627400d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageVersionSettings; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; +import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.psi.*; @@ -334,8 +335,12 @@ public class CallResolver { KtConstructorDelegationCall delegationCall = (KtConstructorDelegationCall) context.call.getCallElement(); DeclarationDescriptor container = context.scope.getOwnerDescriptor(); assert container instanceof ConstructorDescriptor : "Trying to resolve JetConstructorDelegationCall not in constructor. scope.ownerDescriptor = " + container; - return (OverloadResolutionResults) resolveConstructorDelegationCall(context, delegationCall, (KtConstructorDelegationReferenceExpression) calleeExpression, - (ClassConstructorDescriptor) container); + return (OverloadResolutionResults) resolveConstructorDelegationCall( + context, + delegationCall, + (KtConstructorDelegationReferenceExpression) calleeExpression, + (ClassDescriptor) container.getContainingDeclaration() + ); } else if (calleeExpression == null) { return checkArgumentTypesAndFail(context); @@ -433,18 +438,28 @@ public class CallResolver { dataFlowValueFactory, InferenceSession.Companion.getDefault()); - if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context); + KtConstructorDelegationReferenceExpression calleeExpression = call.getCalleeExpression(); + + if (calleeExpression == null) return checkArgumentTypesAndFail(context); + + ClassDescriptor currentClassDescriptor = constructorDescriptor.getContainingDeclaration(); if (constructorDescriptor.getConstructedClass().getKind() == ClassKind.ENUM_CLASS && call.isImplicit()) { + if (currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) { + DiagnosticFactory0 warningOrError; + + if (languageVersionSettings.supportsFeature(LanguageFeature.RequiredPrimaryConstructorDelegationCallInEnums)) { + warningOrError = PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED; // error + } else { + warningOrError = PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM; // warning + } + + context.trace.report(warningOrError.on((KtConstructorDelegationCall) calleeExpression.getParent())); + } return null; } - return resolveConstructorDelegationCall( - context, - call, - call.getCalleeExpression(), - constructorDescriptor - ); + return resolveConstructorDelegationCall(context, call, call.getCalleeExpression(), currentClassDescriptor); } @NotNull @@ -452,12 +467,10 @@ public class CallResolver { @NotNull BasicCallResolutionContext context, @NotNull KtConstructorDelegationCall call, @NotNull KtConstructorDelegationReferenceExpression calleeExpression, - @NotNull ClassConstructorDescriptor calleeConstructor + @NotNull ClassDescriptor currentClassDescriptor ) { context.trace.record(BindingContext.LEXICAL_SCOPE, call, context.scope); - ClassDescriptor currentClassDescriptor = calleeConstructor.getContainingDeclaration(); - boolean isThisCall = calleeExpression.isThis(); if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !isThisCall) { context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on(calleeExpression)); @@ -484,9 +497,8 @@ public class CallResolver { } - KotlinType superType = isThisCall ? - calleeConstructor.getContainingDeclaration().getDefaultType() : - DescriptorUtils.getSuperClassType(currentClassDescriptor); + KotlinType superType = + isThisCall ? currentClassDescriptor.getDefaultType() : DescriptorUtils.getSuperClassType(currentClassDescriptor); Pair>, BasicCallResolutionContext> candidatesAndContext = prepareCandidatesAndContextForConstructorCall(superType, context, syntheticScopes); diff --git a/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.fir.kt b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.fir.kt new file mode 100644 index 00000000000..0dd5c8229cf --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.fir.kt @@ -0,0 +1,43 @@ +// DIAGNOSTICS: -UNUSED_PARAMETER +// !LANGUAGE: -RequiredPrimaryConstructorDelegationCallInEnums + +enum class Enum1(val a: String) { + A; + constructor() +} + +enum class Enum2(val a: String) { + A, B; + constructor(): this("") +} + +enum class Enum3(val a: String = "") { + A, B, C; + constructor() +} + +enum class Enum4(val a: String = "") { + A, B, C; + constructor(): this() +} + +enum class Enum5(val a: String = "") { + A, B, C; + constructor(): this(a = "") +} + +enum class Enum6(val a: String = "") { + A, B, C; +} + +enum class Enum7(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int): this("") +} + +enum class Enum8(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int) +} diff --git a/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt new file mode 100644 index 00000000000..39e3ac120bc --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt @@ -0,0 +1,43 @@ +// DIAGNOSTICS: -UNUSED_PARAMETER +// !LANGUAGE: -RequiredPrimaryConstructorDelegationCallInEnums + +enum class Enum1(val a: String) { + A; + constructor() +} + +enum class Enum2(val a: String) { + A, B; + constructor(): this("") +} + +enum class Enum3(val a: String = "") { + A, B, C; + constructor() +} + +enum class Enum4(val a: String = "") { + A, B, C; + constructor(): this() +} + +enum class Enum5(val a: String = "") { + A, B, C; + constructor(): this(a = "") +} + +enum class Enum6(val a: String = "") { + A, B, C; +} + +enum class Enum7(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int): this("") +} + +enum class Enum8(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int) +} diff --git a/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.txt b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.txt new file mode 100644 index 00000000000..87fd4a619d2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.txt @@ -0,0 +1,196 @@ +package + +public final enum class Enum1 : kotlin.Enum { + enum entry A + + private constructor Enum1() + private constructor Enum1(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum1): 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): Enum1 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum2 : kotlin.Enum { + enum entry A + + enum entry B + + private constructor Enum2() + private constructor Enum2(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum2): 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): Enum2 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum3 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum3() + private constructor Enum3(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum3): 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): Enum3 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum4 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum4() + private constructor Enum4(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum4): 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): Enum4 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum5 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum5() + private constructor Enum5(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum5): 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): Enum5 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum6 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum6(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum6): 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): Enum6 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum7 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum7() + private constructor Enum7(/*0*/ x: kotlin.Int) + private constructor Enum7(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum7): 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): Enum7 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum8 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum8() + private constructor Enum8(/*0*/ x: kotlin.Int) + private constructor Enum8(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum8): 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): Enum8 + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.fir.kt b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.fir.kt new file mode 100644 index 00000000000..0655b2ac457 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.fir.kt @@ -0,0 +1,43 @@ +// DIAGNOSTICS: -UNUSED_PARAMETER +// !LANGUAGE: +RequiredPrimaryConstructorDelegationCallInEnums + +enum class Enum1(val a: String) { + A; + constructor() +} + +enum class Enum2(val a: String) { + A, B; + constructor(): this("") +} + +enum class Enum3(val a: String = "") { + A, B, C; + constructor() +} + +enum class Enum4(val a: String = "") { + A, B, C; + constructor(): this() +} + +enum class Enum5(val a: String = "") { + A, B, C; + constructor(): this(a = "") +} + +enum class Enum6(val a: String = "") { + A, B, C; +} + +enum class Enum7(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int): this("") +} + +enum class Enum8(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int) +} diff --git a/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt new file mode 100644 index 00000000000..015bd1e1d34 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt @@ -0,0 +1,43 @@ +// DIAGNOSTICS: -UNUSED_PARAMETER +// !LANGUAGE: +RequiredPrimaryConstructorDelegationCallInEnums + +enum class Enum1(val a: String) { + A; + constructor() +} + +enum class Enum2(val a: String) { + A, B; + constructor(): this("") +} + +enum class Enum3(val a: String = "") { + A, B, C; + constructor() +} + +enum class Enum4(val a: String = "") { + A, B, C; + constructor(): this() +} + +enum class Enum5(val a: String = "") { + A, B, C; + constructor(): this(a = "") +} + +enum class Enum6(val a: String = "") { + A, B, C; +} + +enum class Enum7(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int): this("") +} + +enum class Enum8(val a: String) { + A, B, C; + constructor(): this(10) + constructor(x: Int) +} diff --git a/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.txt b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.txt new file mode 100644 index 00000000000..87fd4a619d2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.txt @@ -0,0 +1,196 @@ +package + +public final enum class Enum1 : kotlin.Enum { + enum entry A + + private constructor Enum1() + private constructor Enum1(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum1): 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): Enum1 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum2 : kotlin.Enum { + enum entry A + + enum entry B + + private constructor Enum2() + private constructor Enum2(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum2): 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): Enum2 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum3 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum3() + private constructor Enum3(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum3): 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): Enum3 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum4 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum4() + private constructor Enum4(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum4): 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): Enum4 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum5 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum5() + private constructor Enum5(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum5): 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): Enum5 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum6 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum6(/*0*/ a: kotlin.String = ...) + public final val a: kotlin.String + 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: Enum6): 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): Enum6 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum7 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum7() + private constructor Enum7(/*0*/ x: kotlin.Int) + private constructor Enum7(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum7): 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): Enum7 + public final /*synthesized*/ fun values(): kotlin.Array +} + +public final enum class Enum8 : kotlin.Enum { + enum entry A + + enum entry B + + enum entry C + + private constructor Enum8() + private constructor Enum8(/*0*/ x: kotlin.Int) + private constructor Enum8(/*0*/ a: kotlin.String) + public final val a: kotlin.String + 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: Enum8): 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): Enum8 + public final /*synthesized*/ fun values(): kotlin.Array +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index c2156196a37..8383d3ef729 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -7619,6 +7619,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTestWithFirVali runTest("compiler/testData/diagnostics/tests/enum/SecondaryConstructorCall.kt"); } + @TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOne.kt") + public void testSecondaryConstructorWithoutDelegatingToPrimaryOne() throws Exception { + runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt"); + } + + @TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt") + public void testSecondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt"); + } + @TestMetadata("starImportNestedClassAndEntries.kt") public void testStarImportNestedClassAndEntries() throws Exception { runTest("compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 652c6bdcb6b..911e649e25a 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -7614,6 +7614,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/enum/SecondaryConstructorCall.kt"); } + @TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOne.kt") + public void testSecondaryConstructorWithoutDelegatingToPrimaryOne() throws Exception { + runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt"); + } + + @TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt") + public void testSecondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature() throws Exception { + runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt"); + } + @TestMetadata("starImportNestedClassAndEntries.kt") public void testStarImportNestedClassAndEntries() throws Exception { runTest("compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index b6d792bbf73..33730a1d417 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -136,6 +136,7 @@ enum class LanguageFeature( AdaptedCallableReferenceAgainstReflectiveType(KOTLIN_1_5, defaultState = LanguageFeature.State.DISABLED), ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated(KOTLIN_1_5, kind = BUG_FIX), InferenceCompatibility(KOTLIN_1_5, kind = BUG_FIX), + RequiredPrimaryConstructorDelegationCallInEnums(KOTLIN_1_5, kind = BUG_FIX), // Temporarily disabled, see KT-27084/KT-22379 SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),