Cleanup: LanguageFeature.defaultState -> LanguageFeature.isEnabledWithWarning

Review: https://jetbrains.team/p/kt/reviews/7418

`State` enum contains `DISABLED` item which is redundant for
`LanguageFeature`. It's redundant because `sinceVersion = null` is used
to express the same semantic.

I had to reorder some items in the enum because otherwise
`testLanguageFeatureOrder` fails. I could keep the same logic in
`testLanguageFeatureOrder` but I would need to make
`isEnabledWithWarning` public which I don't want to. Anyway, it's not
obvious what is more readable: keep `isEnabledWithWarning = true` items
at the end or at the beginning.

Also all effectively disabled features (`sinceVersion = null` or
`defaultState = State.DISABLED`) are now moved to the "Experimental"
section at the end which is obviously better.
This commit is contained in:
Nikita Bobko
2022-10-17 13:32:22 +02:00
parent 49a5186f15
commit cdbfcdc465
2 changed files with 40 additions and 38 deletions
@@ -393,7 +393,7 @@ class CodeConformanceTest : TestCase() {
fun testLanguageFeatureOrder() { fun testLanguageFeatureOrder() {
val values = enumValues<LanguageFeature>() val values = enumValues<LanguageFeature>()
val enabledFeatures = values.filter { it.sinceVersion != null && it.defaultState == LanguageFeature.State.ENABLED } val enabledFeatures = values.filter { it.sinceVersion != null }
if (enabledFeatures.sortedBy { it.sinceVersion!! } != enabledFeatures) { if (enabledFeatures.sortedBy { it.sinceVersion!! } != enabledFeatures) {
val (a, b) = enabledFeatures.zipWithNext().first { (a, b) -> a.sinceVersion!! > b.sinceVersion!! } val (a, b) = enabledFeatures.zipWithNext().first { (a, b) -> a.sinceVersion!! > b.sinceVersion!! }
@@ -14,7 +14,7 @@ enum class LanguageFeature(
val sinceVersion: LanguageVersion?, val sinceVersion: LanguageVersion?,
val sinceApiVersion: ApiVersion = ApiVersion.KOTLIN_1_0, val sinceApiVersion: ApiVersion = ApiVersion.KOTLIN_1_0,
val hintUrl: String? = null, val hintUrl: String? = null,
val defaultState: State = State.ENABLED, internal val isEnabledWithWarning: Boolean = false,
val kind: Kind = OTHER // NB: default value OTHER doesn't force pre-releaseness (see KDoc) val kind: Kind = OTHER // NB: default value OTHER doesn't force pre-releaseness (see KDoc)
) { ) {
// Note: names of these entries are also used in diagnostic tests and in user-visible messages (see presentableText below) // Note: names of these entries are also used in diagnostic tests and in user-visible messages (see presentableText below)
@@ -42,6 +42,11 @@ enum class LanguageFeature(
TypeInferenceOnGenericsForCallableReferences(KOTLIN_1_1), TypeInferenceOnGenericsForCallableReferences(KOTLIN_1_1),
NoDelegationToJavaDefaultInterfaceMembers(KOTLIN_1_1), NoDelegationToJavaDefaultInterfaceMembers(KOTLIN_1_1),
DefaultImportOfPackageKotlinComparisons(KOTLIN_1_1), DefaultImportOfPackageKotlinComparisons(KOTLIN_1_1),
Coroutines(
KOTLIN_1_1, ApiVersion.KOTLIN_1_1,
"https://kotlinlang.org/docs/diagnostics/experimental-coroutines",
isEnabledWithWarning = true
),
// 1.2 // 1.2
@@ -93,6 +98,7 @@ enum class LanguageFeature(
NewCapturedReceiverFieldNamingConvention(KOTLIN_1_3, kind = BUG_FIX), NewCapturedReceiverFieldNamingConvention(KOTLIN_1_3, kind = BUG_FIX),
ExtendedMainConvention(KOTLIN_1_3), ExtendedMainConvention(KOTLIN_1_3),
ExperimentalBuilderInference(KOTLIN_1_3), ExperimentalBuilderInference(KOTLIN_1_3),
InlineClasses(KOTLIN_1_3, isEnabledWithWarning = true, kind = UNSTABLE_FEATURE),
// 1.4 // 1.4
@@ -123,7 +129,6 @@ enum class LanguageFeature(
ProperFinally(KOTLIN_1_4, kind = BUG_FIX), ProperFinally(KOTLIN_1_4, kind = BUG_FIX),
AllowAssigningArrayElementsToVarargsInNamedFormForFunctions(KOTLIN_1_4), AllowAssigningArrayElementsToVarargsInNamedFormForFunctions(KOTLIN_1_4),
AllowNullOperatorsForResult(KOTLIN_1_4), AllowNullOperatorsForResult(KOTLIN_1_4),
AllowResultInReturnType(KOTLIN_1_4, defaultState = State.DISABLED),
PreferJavaFieldOverload(KOTLIN_1_4), PreferJavaFieldOverload(KOTLIN_1_4),
AllowContractsForNonOverridableMembers(KOTLIN_1_4), AllowContractsForNonOverridableMembers(KOTLIN_1_4),
AllowReifiedGenericsInContracts(KOTLIN_1_4), AllowReifiedGenericsInContracts(KOTLIN_1_4),
@@ -133,7 +138,7 @@ enum class LanguageFeature(
FunctionalInterfaceConversion(KOTLIN_1_4, kind = UNSTABLE_FEATURE), FunctionalInterfaceConversion(KOTLIN_1_4, kind = UNSTABLE_FEATURE),
GenerateJvmOverloadsAsFinal(KOTLIN_1_4), GenerateJvmOverloadsAsFinal(KOTLIN_1_4),
MangleClassMembersReturningInlineClasses(KOTLIN_1_4), MangleClassMembersReturningInlineClasses(KOTLIN_1_4),
ImproveReportingDiagnosticsOnProtectedMembersOfBaseClass(KOTLIN_1_4, kind = BUG_FIX, defaultState = State.ENABLED), ImproveReportingDiagnosticsOnProtectedMembersOfBaseClass(KOTLIN_1_4, kind = BUG_FIX),
NewInference(KOTLIN_1_4), NewInference(KOTLIN_1_4),
@@ -144,8 +149,6 @@ enum class LanguageFeature(
FunctionReferenceWithDefaultValueAsOtherType(KOTLIN_1_4), FunctionReferenceWithDefaultValueAsOtherType(KOTLIN_1_4),
OverloadResolutionByLambdaReturnType(KOTLIN_1_4), OverloadResolutionByLambdaReturnType(KOTLIN_1_4),
ContractsOnCallsWithImplicitReceiver(KOTLIN_1_4), ContractsOnCallsWithImplicitReceiver(KOTLIN_1_4),
BooleanElvisBoundSmartCasts(KOTLIN_1_3, defaultState = State.DISABLED), // see KT-26357 for details
NewDataFlowForTryExpressions(KOTLIN_1_4, defaultState = State.DISABLED),
// ^----------------------------------------------------------------------^ // ^----------------------------------------------------------------------^
// 1.5 // 1.5
@@ -156,35 +159,29 @@ enum class LanguageFeature(
ProhibitVarargAsArrayAfterSamArgument(KOTLIN_1_5, kind = BUG_FIX), ProhibitVarargAsArrayAfterSamArgument(KOTLIN_1_5, kind = BUG_FIX),
CorrectSourceMappingSyntax(KOTLIN_1_5, kind = UNSTABLE_FEATURE), CorrectSourceMappingSyntax(KOTLIN_1_5, kind = UNSTABLE_FEATURE),
ProperArrayConventionSetterWithDefaultCalls(KOTLIN_1_5, kind = OTHER), ProperArrayConventionSetterWithDefaultCalls(KOTLIN_1_5, kind = OTHER),
DisableCompatibilityModeForNewInference(KOTLIN_1_5, defaultState = State.DISABLED), DisableCompatibilityModeForNewInference(null),
AdaptedCallableReferenceAgainstReflectiveType(KOTLIN_1_5, defaultState = State.DISABLED), AdaptedCallableReferenceAgainstReflectiveType(null),
InferenceCompatibility(KOTLIN_1_5, kind = BUG_FIX), InferenceCompatibility(KOTLIN_1_5, kind = BUG_FIX),
RequiredPrimaryConstructorDelegationCallInEnums(KOTLIN_1_5, kind = BUG_FIX), RequiredPrimaryConstructorDelegationCallInEnums(KOTLIN_1_5, kind = BUG_FIX),
ApproximateAnonymousReturnTypesInPrivateInlineFunctions(KOTLIN_1_5, kind = BUG_FIX), ApproximateAnonymousReturnTypesInPrivateInlineFunctions(KOTLIN_1_5, kind = BUG_FIX),
ForbidReferencingToUnderscoreNamedParameterOfCatchBlock(KOTLIN_1_5, kind = BUG_FIX), ForbidReferencingToUnderscoreNamedParameterOfCatchBlock(KOTLIN_1_5, kind = BUG_FIX),
UseCorrectExecutionOrderForVarargArguments(KOTLIN_1_5, kind = BUG_FIX), UseCorrectExecutionOrderForVarargArguments(KOTLIN_1_5, kind = BUG_FIX),
JvmRecordSupport(KOTLIN_1_5), JvmRecordSupport(KOTLIN_1_5),
AllowNullOperatorsForResultAndResultReturnTypeByDefault(KOTLIN_1_5, defaultState = State.ENABLED), AllowNullOperatorsForResultAndResultReturnTypeByDefault(KOTLIN_1_5),
AllowSealedInheritorsInDifferentFilesOfSamePackage(KOTLIN_1_5), AllowSealedInheritorsInDifferentFilesOfSamePackage(KOTLIN_1_5),
SealedInterfaces(KOTLIN_1_5), SealedInterfaces(KOTLIN_1_5),
JvmIrEnabledByDefault(KOTLIN_1_5), JvmIrEnabledByDefault(KOTLIN_1_5),
JvmInlineValueClasses(KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), JvmInlineValueClasses(KOTLIN_1_5, kind = OTHER),
SuspendFunctionsInFunInterfaces(KOTLIN_1_5, defaultState = State.ENABLED, kind = OTHER), SuspendFunctionsInFunInterfaces(KOTLIN_1_5, kind = OTHER),
SamWrapperClassesAreSynthetic(KOTLIN_1_5, defaultState = State.ENABLED, kind = BUG_FIX), SamWrapperClassesAreSynthetic(KOTLIN_1_5, kind = BUG_FIX),
StrictOnlyInputTypesChecks(KOTLIN_1_5), StrictOnlyInputTypesChecks(KOTLIN_1_5),
JsEnableExtensionFunctionInExternals(KOTLIN_1_5, defaultState = State.DISABLED, kind = OTHER),
// Disabled until the breaking change is approved by the committee, see KT-10884.
PackagePrivateFileClassesWithAllPrivateMembers(KOTLIN_1_5, defaultState = State.DISABLED),
// 1.6 // 1.6
ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor(KOTLIN_1_6, kind = BUG_FIX), ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor(KOTLIN_1_6, kind = BUG_FIX),
PrivateInFileEffectiveVisibility(KOTLIN_1_6, kind = BUG_FIX), PrivateInFileEffectiveVisibility(KOTLIN_1_6, kind = BUG_FIX),
ProhibitSelfCallsInNestedObjects(KOTLIN_1_6, kind = BUG_FIX), ProhibitSelfCallsInNestedObjects(KOTLIN_1_6, kind = BUG_FIX),
ProperCheckAnnotationsTargetInTypeUsePositions(KOTLIN_1_6, kind = BUG_FIX), ProperCheckAnnotationsTargetInTypeUsePositions(KOTLIN_1_6, kind = BUG_FIX),
SuspendFunctionAsSupertype(KOTLIN_1_6), SuspendFunctionAsSupertype(KOTLIN_1_6),
UnrestrictedBuilderInference(KOTLIN_1_6), UnrestrictedBuilderInference(KOTLIN_1_6),
ClassTypeParameterAnnotations(KOTLIN_1_6), ClassTypeParameterAnnotations(KOTLIN_1_6),
@@ -257,7 +254,6 @@ enum class LanguageFeature(
RefineTypeCheckingOnAssignmentsToJavaFields(KOTLIN_1_8, kind = BUG_FIX), // KT-46727 RefineTypeCheckingOnAssignmentsToJavaFields(KOTLIN_1_8, kind = BUG_FIX), // KT-46727
RangeUntilOperator(KOTLIN_1_8), // KT-15613 RangeUntilOperator(KOTLIN_1_8), // KT-15613
GenericInlineClassParameter(sinceVersion = KOTLIN_1_8, kind = UNSTABLE_FEATURE), // KT-32162 GenericInlineClassParameter(sinceVersion = KOTLIN_1_8, kind = UNSTABLE_FEATURE), // KT-32162
LightweightLambdas(KOTLIN_1_8, defaultState = State.DISABLED),
// 1.9 // 1.9
@@ -277,7 +273,7 @@ enum class LanguageFeature(
KeepNullabilityWhenApproximatingLocalType(KOTLIN_1_9, kind = BUG_FIX), // KT-53982 KeepNullabilityWhenApproximatingLocalType(KOTLIN_1_9, kind = BUG_FIX), // KT-53982
SkipStandaloneScriptsInSourceRoots(KOTLIN_1_9, kind = OTHER), // KT-52525 SkipStandaloneScriptsInSourceRoots(KOTLIN_1_9, kind = OTHER), // KT-52525
ModifierNonBuiltinSuspendFunError(KOTLIN_1_9, kind = BUG_FIX), // KT-49264 ModifierNonBuiltinSuspendFunError(KOTLIN_1_9, kind = BUG_FIX), // KT-49264
BreakContinueInInlineLambdas(KOTLIN_1_9, defaultState = State.ENABLED), // KT-1436 BreakContinueInInlineLambdas(KOTLIN_1_9), // KT-1436
EnumEntries(KOTLIN_1_9, sinceApiVersion = ApiVersion.KOTLIN_1_8, kind = UNSTABLE_FEATURE), // KT-48872 EnumEntries(KOTLIN_1_9, sinceApiVersion = ApiVersion.KOTLIN_1_8, kind = UNSTABLE_FEATURE), // KT-48872
EnableDfaWarningsInK2(KOTLIN_1_9, kind = OTHER), // KT-50965 EnableDfaWarningsInK2(KOTLIN_1_9, kind = OTHER), // KT-50965
ForbidSuperDelegationToAbstractFakeOverride(KOTLIN_1_9, kind = BUG_FIX), // KT-49017 ForbidSuperDelegationToAbstractFakeOverride(KOTLIN_1_9, kind = BUG_FIX), // KT-49017
@@ -299,28 +295,34 @@ enum class LanguageFeature(
// However, later we encountered various situations when it works incorrectly, and decided to forbid them. // However, later we encountered various situations when it works incorrectly, and decided to forbid them.
// When this feature is disabled, various errors are reported which are related to these incorrect situations. // When this feature is disabled, various errors are reported which are related to these incorrect situations.
// When this feature is enabled, no such errors are reported. // When this feature is enabled, no such errors are reported.
NoBuilderInferenceWithoutAnnotationRestriction(sinceVersion = null, kind = OTHER, defaultState = State.DISABLED), NoBuilderInferenceWithoutAnnotationRestriction(sinceVersion = null, kind = OTHER),
// Experimental features // Experimental features
Coroutines( LightweightLambdas(null),
KOTLIN_1_1, ApiVersion.KOTLIN_1_1, JsEnableExtensionFunctionInExternals(null, kind = OTHER),
"https://kotlinlang.org/docs/diagnostics/experimental-coroutines", PackagePrivateFileClassesWithAllPrivateMembers(null), // Disabled until the breaking change is approved by the committee, see KT-10884.
State.ENABLED_WITH_WARNING BooleanElvisBoundSmartCasts(null), // see KT-26357 for details
), NewDataFlowForTryExpressions(null),
MultiPlatformProjects(sinceVersion = null, defaultState = State.DISABLED), AllowResultInReturnType(null),
InlineClasses(KOTLIN_1_3, defaultState = State.ENABLED_WITH_WARNING, kind = UNSTABLE_FEATURE), MultiPlatformProjects(sinceVersion = null),
ProhibitComparisonOfIncompatibleClasses(sinceVersion = null, kind = BUG_FIX, defaultState = State.DISABLED), ProhibitComparisonOfIncompatibleClasses(sinceVersion = null, kind = BUG_FIX),
ExplicitBackingFields(sinceVersion = null, defaultState = State.DISABLED, kind = UNSTABLE_FEATURE), ExplicitBackingFields(sinceVersion = null, kind = UNSTABLE_FEATURE),
FunctionalTypeWithExtensionAsSupertype(sinceVersion = KOTLIN_1_6, defaultState = State.DISABLED), FunctionalTypeWithExtensionAsSupertype(sinceVersion = null),
JsAllowInvalidCharsIdentifiersEscaping(sinceVersion = null, defaultState = State.DISABLED, kind = UNSTABLE_FEATURE), JsAllowInvalidCharsIdentifiersEscaping(sinceVersion = null, kind = UNSTABLE_FEATURE),
JsAllowValueClassesInExternals(sinceVersion = null, defaultState = State.DISABLED, kind = UNSTABLE_FEATURE), JsAllowValueClassesInExternals(sinceVersion = null, kind = UNSTABLE_FEATURE),
ContextReceivers(sinceVersion = null, defaultState = State.DISABLED), ContextReceivers(sinceVersion = null),
ValueClasses(sinceVersion = null, defaultState = State.DISABLED, kind = UNSTABLE_FEATURE), ValueClasses(sinceVersion = null, kind = UNSTABLE_FEATURE),
JavaSamConversionEqualsHashCode(sinceVersion = null, defaultState = State.DISABLED, kind = UNSTABLE_FEATURE), JavaSamConversionEqualsHashCode(sinceVersion = null, kind = UNSTABLE_FEATURE),
UnitConversionsOnArbitraryExpressions(sinceVersion = null, defaultState = State.DISABLED), UnitConversionsOnArbitraryExpressions(sinceVersion = null),
; ;
init {
if (sinceVersion == null && isEnabledWithWarning) {
error("$this: '${::isEnabledWithWarning.name}' has no effect if the feature is disabled by default")
}
}
val presentableName: String val presentableName: String
// E.g. "DestructuringLambdaParameters" -> ["Destructuring", "Lambda", "Parameters"] -> "destructuring lambda parameters" // E.g. "DestructuringLambdaParameters" -> ["Destructuring", "Lambda", "Parameters"] -> "destructuring lambda parameters"
get() = name.split("(?<!^)(?=[A-Z])".toRegex()).joinToString(separator = " ", transform = String::lowercase) get() = name.split("(?<!^)(?=[A-Z])".toRegex()).joinToString(separator = " ", transform = String::lowercase)
@@ -512,7 +514,7 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor(
val since = feature.sinceVersion val since = feature.sinceVersion
if (since != null && languageVersion >= since && apiVersion >= feature.sinceApiVersion) { if (since != null && languageVersion >= since && apiVersion >= feature.sinceApiVersion) {
return feature.defaultState return if (feature.isEnabledWithWarning) LanguageFeature.State.ENABLED_WITH_WARNING else LanguageFeature.State.ENABLED
} }
return LanguageFeature.State.DISABLED return LanguageFeature.State.DISABLED