From a0790047f7bd8a7b7d2d26e9777e122f27f59b0f Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Sat, 22 Apr 2023 00:28:51 +0200 Subject: [PATCH] JvmDefault: remove -Xjvm-default modes "enable" and "compatibility" #KT-54746 --- .../cli/common/arguments/K2JVMCompilerArguments.kt | 12 +++--------- .../kotlin/backend/jvm/lower/InterfaceLowering.kt | 5 ++--- compiler/testData/cli/jvm/extraHelp.out | 9 ++------- .../org/jetbrains/kotlin/config/JvmDefaultMode.kt | 13 +++++++++---- 4 files changed, 16 insertions(+), 23 deletions(-) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt index 6eec916e764..3c116e54afc 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JVMCompilerArguments.kt @@ -466,7 +466,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { @Argument( value = "-Xjvm-default", - valueDescription = "{all|all-compatibility|disable|enable|compatibility}", + valueDescription = "{all|all-compatibility|disable}", description = """Emit JVM default methods for interface declarations with bodies. Default is 'disable'. -Xjvm-default=all Generate JVM default methods for all interface declarations with bodies in the module. Do not generate DefaultImpls stubs for interface declarations with bodies, which are generated by default @@ -474,7 +474,6 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { mode and doesn't override it, then a DefaultImpls stub will be generated for it. BREAKS BINARY COMPATIBILITY if some client code relies on the presence of DefaultImpls classes. Note that if interface delegation is used, all interface methods are delegated. - The only exception are methods annotated with the deprecated @JvmDefault annotation. -Xjvm-default=all-compatibility In addition to the 'all' mode, generate compatibility stubs in the DefaultImpls classes. Compatibility stubs could be useful for library and runtime authors to keep backward binary compatibility for existing clients compiled against previous library versions. @@ -487,11 +486,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() { additional implicit method with specialized signatures was generated in the 'disable' mode: unlike in the 'disable' mode, the compiler will report an error if such method is not overridden explicitly and the class is not annotated with @JvmDefaultWithoutCompatibility (see KT-39603 for more details). --Xjvm-default=disable Default behavior. Do not generate JVM default methods and prohibit @JvmDefault annotation usage. --Xjvm-default=enable Deprecated. Allow usages of @JvmDefault; only generate the default method for annotated method - in the interface (annotating an existing method can break binary compatibility). --Xjvm-default=compatibility Deprecated. Allow usages of @JvmDefault; generate a compatibility accessor - in the DefaultImpls class in addition to the default interface method.""" +-Xjvm-default=disable Default behavior. Do not generate JVM default methods.""" ) var jvmDefault: String = JvmDefaultMode.DEFAULT.description set(value) { @@ -871,8 +866,7 @@ Also sets `-jvm-target` value equal to the selected JDK version""" result[JvmAnalysisFlags.jvmDefaultMode] = it } ?: collector.report( CompilerMessageSeverity.ERROR, - "Unknown @JvmDefault mode: $jvmDefault, " + - "supported modes: ${JvmDefaultMode.values().map { it.description }}" + "Unknown -Xjvm-default mode: $jvmDefault, supported modes: ${JvmDefaultMode.values().map { it.description }}" ) result[JvmAnalysisFlags.inheritMultifileParts] = inheritMultifileParts result[JvmAnalysisFlags.sanitizeParentheses] = sanitizeParentheses diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index 30fde28e9e3..5ae72402668 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -78,10 +78,9 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran * create a bridge from DefaultImpls of derived to DefaultImpls of base, unless * - the implementation is private, or belongs to java.lang.Object, * or is a stub for function with default parameters ($default) - * - we're in -Xjvm-default=compatibility|all-compatibility mode, in which case we go via + * - we're in -Xjvm-default=all-compatibility mode, in which case we go via * accessors on the parent class rather than the DefaultImpls if inherited method is compiled to JVM default - * - we're in -Xjvm-default=enable|all mode, and we have that default implementation, - * in which case we simply leave it. + * - we're in -Xjvm-default=all mode, and we have that default implementation, in which case we simply leave it. * * ``` * interface A { fun foo() = 0 } diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 57108074255..12ff2b8fc51 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -56,7 +56,7 @@ where advanced options include: * ignore * strict (experimental; treat as other supported nullability annotations) * warn (report a warning) - -Xjvm-default={all|all-compatibility|disable|enable|compatibility} + -Xjvm-default={all|all-compatibility|disable} Emit JVM default methods for interface declarations with bodies. Default is 'disable'. -Xjvm-default=all Generate JVM default methods for all interface declarations with bodies in the module. Do not generate DefaultImpls stubs for interface declarations with bodies, which are generated by default @@ -64,7 +64,6 @@ where advanced options include: mode and doesn't override it, then a DefaultImpls stub will be generated for it. BREAKS BINARY COMPATIBILITY if some client code relies on the presence of DefaultImpls classes. Note that if interface delegation is used, all interface methods are delegated. - The only exception are methods annotated with the deprecated @JvmDefault annotation. -Xjvm-default=all-compatibility In addition to the 'all' mode, generate compatibility stubs in the DefaultImpls classes. Compatibility stubs could be useful for library and runtime authors to keep backward binary compatibility for existing clients compiled against previous library versions. @@ -77,11 +76,7 @@ where advanced options include: additional implicit method with specialized signatures was generated in the 'disable' mode: unlike in the 'disable' mode, the compiler will report an error if such method is not overridden explicitly and the class is not annotated with @JvmDefaultWithoutCompatibility (see KT-39603 for more details). - -Xjvm-default=disable Default behavior. Do not generate JVM default methods and prohibit @JvmDefault annotation usage. - -Xjvm-default=enable Deprecated. Allow usages of @JvmDefault; only generate the default method for annotated method - in the interface (annotating an existing method can break binary compatibility). - -Xjvm-default=compatibility Deprecated. Allow usages of @JvmDefault; generate a compatibility accessor - in the DefaultImpls class in addition to the default interface method. + -Xjvm-default=disable Default behavior. Do not generate JVM default methods. -Xklib= Paths to cross-platform libraries in .klib format -Xlambdas={class|indy} Select code generation scheme for lambdas. -Xlambdas=indy Generate lambdas using `invokedynamic` with `LambdaMetafactory.metafactory`. Requires `-jvm-target 1.8` or greater. diff --git a/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt b/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt index 0224be5045a..323a949172b 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/JvmDefaultMode.kt @@ -12,13 +12,13 @@ enum class JvmDefaultMode(val description: String) { ALL_COMPATIBILITY("all-compatibility"), ALL_INCOMPATIBLE("all"); - val isEnabled + val isEnabled: Boolean get() = this != DISABLE - val isCompatibility + val isCompatibility: Boolean get() = this == ENABLE_WITH_DEFAULT_IMPLS || this == ALL_COMPATIBILITY - val forAllMethodsWithBody + val forAllMethodsWithBody: Boolean get() = this == ALL_COMPATIBILITY || this == ALL_INCOMPATIBLE companion object { @@ -26,6 +26,11 @@ enum class JvmDefaultMode(val description: String) { val DEFAULT = DISABLE @JvmStatic - fun fromStringOrNull(string: String?) = values().find { it.description == string } + fun fromStringOrNull(string: String?): JvmDefaultMode? = when (string) { + DISABLE.description -> DISABLE + ALL_COMPATIBILITY.description -> ALL_COMPATIBILITY + ALL_INCOMPATIBLE.description -> ALL_INCOMPATIBLE + else -> null + } } }