Add new options for '-Xjvm-default'

This commit is contained in:
Mikhail Bogdanov
2020-04-01 08:30:27 +02:00
parent 7876d821a9
commit 0ddef7e4e4
4 changed files with 72 additions and 23 deletions
@@ -270,13 +270,31 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
@Argument( @Argument(
value = "-Xjvm-default", value = "-Xjvm-default",
valueDescription = "{disable|enable|compatibility}", valueDescription = "{all|all-compatibility|disable|enable|compatibility}",
description = "Allow to use '@JvmDefault' annotation for JVM default method support.\n" + description = """Emit JVM default methods for interface declarations with bodies.
"-Xjvm-default=disable Prohibit usages of @JvmDefault\n" + -Xjvm-default=all-compatibility Generate both a default method in the interface, and a compatibility accessor
"-Xjvm-default=enable Allow usages of @JvmDefault; only generate the default method\n" + in the DefaultImpls class.
" in the interface (annotating an existing method can break binary compatibility)\n" + In case of inheritance from a Kotlin interface compiled in the old scheme
"-Xjvm-default=compatibility Allow usages of @JvmDefault; generate a compatibility accessor\n" + (DefaultImpls, no default methods), the compatibility accessor in DefaultImpls
" in the 'DefaultImpls' class in addition to the interface method" will delegate to the DefaultImpls method of the superinterface. Otherwise the
compatibility accessor will invoke the default method on the interface, with
standard JVM runtime resolution semantics.
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 Generate default methods for all interface declarations with bodies.
Do not generate DefaultImpls classes at all.
BREAKS BINARY COMPATIBILITY if some client code relies on the presence of
DefaultImpls classes. Also prohibits the produced binaries to be read by Kotlin
compilers earlier than 1.4.
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=disable Do not generate JVM default methods and prohibit @JvmDefault annotation usage.
The following modes are DEPRECATED:
-Xjvm-default=enable 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 Allow usages of @JvmDefault; generate a compatibility accessor
in the 'DefaultImpls' class in addition to the default interface method"""
) )
var jvmDefault: String by FreezableVar(JvmDefaultMode.DEFAULT.description) var jvmDefault: String by FreezableVar(JvmDefaultMode.DEFAULT.description)
@@ -337,12 +355,19 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
supportCompatqualCheckerFrameworkAnnotations supportCompatqualCheckerFrameworkAnnotations
) )
result[AnalysisFlags.ignoreDataFlowInAssert] = JVMAssertionsMode.fromString(assertionsMode) != JVMAssertionsMode.LEGACY result[AnalysisFlags.ignoreDataFlowInAssert] = JVMAssertionsMode.fromString(assertionsMode) != JVMAssertionsMode.LEGACY
JvmDefaultMode.fromStringOrNull(jvmDefault)?.let { result[JvmAnalysisFlags.jvmDefaultMode] = it } JvmDefaultMode.fromStringOrNull(jvmDefault)?.let {
?: collector.report( result[JvmAnalysisFlags.jvmDefaultMode] = it
CompilerMessageSeverity.ERROR, if (it == JvmDefaultMode.ENABLE || it == JvmDefaultMode.ENABLE_WITH_DEFAULT_IMPLS) {
"Unknown @JvmDefault mode: $jvmDefault, " + collector.report(
"supported modes: ${JvmDefaultMode.values().map { it.description }}" CompilerMessageSeverity.WARNING,
) "'-Xjvm-default=$jvmDefault' mode is deprecated. Please considering to switch to new modes: 'all' and 'all-compatibility'"
)
}
} ?: collector.report(
CompilerMessageSeverity.ERROR,
"Unknown @JvmDefault mode: $jvmDefault, " +
"supported modes: ${JvmDefaultMode.values().map { it.description }}"
)
result[JvmAnalysisFlags.inheritMultifileParts] = inheritMultifileParts result[JvmAnalysisFlags.inheritMultifileParts] = inheritMultifileParts
result[JvmAnalysisFlags.sanitizeParentheses] = sanitizeParentheses result[JvmAnalysisFlags.sanitizeParentheses] = sanitizeParentheses
result[JvmAnalysisFlags.suppressMissingBuiltinsError] = suppressMissingBuiltinsError result[JvmAnalysisFlags.suppressMissingBuiltinsError] = suppressMissingBuiltinsError
@@ -108,9 +108,6 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<List<String>> ADDITIONAL_JAVA_MODULES = public static final CompilerConfigurationKey<List<String>> ADDITIONAL_JAVA_MODULES =
CompilerConfigurationKey.create("additional Java modules"); CompilerConfigurationKey.create("additional Java modules");
public static final CompilerConfigurationKey<Boolean> ENABLE_JVM_DEFAULT =
CompilerConfigurationKey.create("Allow to use '@JvmDefault'");
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS = public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode"); CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
+26 -7
View File
@@ -38,13 +38,32 @@ where advanced options include:
* ignore * ignore
* strict (experimental; treat as other supported nullability annotations) * strict (experimental; treat as other supported nullability annotations)
* warn (report a warning) * warn (report a warning)
-Xjvm-default={disable|enable|compatibility} -Xjvm-default={all|all-compatibility|disable|enable|compatibility}
Allow to use '@JvmDefault' annotation for JVM default method support. Emit JVM default methods for interface declarations with bodies.
-Xjvm-default=disable Prohibit usages of @JvmDefault -Xjvm-default=all-compatibility Generate both a default method in the interface, and a compatibility accessor
-Xjvm-default=enable Allow usages of @JvmDefault; only generate the default method in the DefaultImpls class.
in the interface (annotating an existing method can break binary compatibility) In case of inheritance from a Kotlin interface compiled in the old scheme
-Xjvm-default=compatibility Allow usages of @JvmDefault; generate a compatibility accessor (DefaultImpls, no default methods), the compatibility accessor in DefaultImpls
in the 'DefaultImpls' class in addition to the interface method will delegate to the DefaultImpls method of the superinterface. Otherwise the
compatibility accessor will invoke the default method on the interface, with
standard JVM runtime resolution semantics.
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 Generate default methods for all interface declarations with bodies.
Do not generate DefaultImpls classes at all.
BREAKS BINARY COMPATIBILITY if some client code relies on the presence of
DefaultImpls classes. Also prohibits the produced binaries to be read by Kotlin
compilers earlier than 1.4.
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=disable Do not generate JVM default methods and prohibit @JvmDefault annotation usage.
The following modes are DEPRECATED:
-Xjvm-default=enable 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 Allow usages of @JvmDefault; generate a compatibility accessor
in the 'DefaultImpls' class in addition to the default interface method
-Xklib=<path> Paths to cross-platform libraries in .klib format -Xklib=<path> Paths to cross-platform libraries in .klib format
-Xno-call-assertions Don't generate not-null assertions for arguments of platform types -Xno-call-assertions Don't generate not-null assertions for arguments of platform types
-Xno-exception-on-explicit-equals-for-boxed-null -Xno-exception-on-explicit-equals-for-boxed-null
@@ -9,6 +9,7 @@ import kotlin.internal.RequireKotlin
import kotlin.internal.RequireKotlinVersionKind import kotlin.internal.RequireKotlinVersionKind
/** /**
*
* Specifies that a JVM default method should be generated for non-abstract Kotlin interface member. * Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.
* *
* Usages of this annotation require an explicit compilation argument to be specified: * Usages of this annotation require an explicit compilation argument to be specified:
@@ -26,6 +27,13 @@ import kotlin.internal.RequireKotlinVersionKind
* Generation of default methods is only possible with JVM target bytecode version 1.8 (`-jvm-target 1.8`) or higher. * Generation of default methods is only possible with JVM target bytecode version 1.8 (`-jvm-target 1.8`) or higher.
* *
* @[JvmDefault] methods are excluded from interface delegation. * @[JvmDefault] methods are excluded from interface delegation.
*
* #
* This annotation is **deprecated** in favor of new compiler arguments `-Xjvm-default=all-compatibility` and `-Xjvm-default=all`.
* The new arguments allow all interface methods with bodies to be generated as JVM default methods on JVM target 1.8+.
* Please refer to the [official documentation](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#default-methods-in-interfaces)
* for more information.
*
*/ */
@SinceKotlin("1.2") @SinceKotlin("1.2")
@RequireKotlin("1.2.40", versionKind = RequireKotlinVersionKind.COMPILER_VERSION) @RequireKotlin("1.2.40", versionKind = RequireKotlinVersionKind.COMPILER_VERSION)